Add dependences
This commit is contained in:
parent
86515cd537
commit
3f7de941f1
|
@ -0,0 +1,191 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
https://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
|
||||||
|
|
||||||
|
Copyright 2015-2015 Li Yi (denverdino@gmail.com).
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
https://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.
|
|
@ -0,0 +1,227 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Client represents a client of ECS services
|
||||||
|
type Client struct {
|
||||||
|
AccessKeyId string //Access Key Id
|
||||||
|
AccessKeySecret string //Access Key Secret
|
||||||
|
debug bool
|
||||||
|
httpClient *http.Client
|
||||||
|
endpoint string
|
||||||
|
version string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new instance of ECS client
|
||||||
|
func (client *Client) Init(endpoint, version, accessKeyId, accessKeySecret string) {
|
||||||
|
client.AccessKeyId = accessKeyId
|
||||||
|
client.AccessKeySecret = accessKeySecret + "&"
|
||||||
|
client.debug = false
|
||||||
|
client.httpClient = &http.Client{}
|
||||||
|
client.endpoint = endpoint
|
||||||
|
client.version = version
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEndpoint sets custom endpoint
|
||||||
|
func (client *Client) SetEndpoint(endpoint string) {
|
||||||
|
client.endpoint = endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEndpoint sets custom version
|
||||||
|
func (client *Client) SetVersion(version string) {
|
||||||
|
client.version = version
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAccessKeyId sets new AccessKeyId
|
||||||
|
func (client *Client) SetAccessKeyId(id string) {
|
||||||
|
client.AccessKeyId = id
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAccessKeySecret sets new AccessKeySecret
|
||||||
|
func (client *Client) SetAccessKeySecret(secret string) {
|
||||||
|
client.AccessKeySecret = secret + "&"
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDebug sets debug mode to log the request/response message
|
||||||
|
func (client *Client) SetDebug(debug bool) {
|
||||||
|
client.debug = debug
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke sends the raw HTTP request for ECS services
|
||||||
|
func (client *Client) Invoke(action string, args interface{}, response interface{}) error {
|
||||||
|
|
||||||
|
request := Request{}
|
||||||
|
request.init(client.version, action, client.AccessKeyId)
|
||||||
|
|
||||||
|
query := util.ConvertToQueryValues(request)
|
||||||
|
util.SetQueryValues(args, &query)
|
||||||
|
|
||||||
|
// Sign request
|
||||||
|
signature := util.CreateSignatureForRequest(ECSRequestMethod, &query, client.AccessKeySecret)
|
||||||
|
|
||||||
|
// Generate the request URL
|
||||||
|
requestURL := client.endpoint + "?" + query.Encode() + "&Signature=" + url.QueryEscape(signature)
|
||||||
|
|
||||||
|
httpReq, err := http.NewRequest(ECSRequestMethod, requestURL, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return GetClientError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO move to util and add build val flag
|
||||||
|
httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version)
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
httpResp, err := client.httpClient.Do(httpReq)
|
||||||
|
t1 := time.Now()
|
||||||
|
if err != nil {
|
||||||
|
return GetClientError(err)
|
||||||
|
}
|
||||||
|
statusCode := httpResp.StatusCode
|
||||||
|
|
||||||
|
if client.debug {
|
||||||
|
log.Printf("Invoke %s %s %d (%v)", ECSRequestMethod, requestURL, statusCode, t1.Sub(t0))
|
||||||
|
}
|
||||||
|
|
||||||
|
defer httpResp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(httpResp.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return GetClientError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if client.debug {
|
||||||
|
var prettyJSON bytes.Buffer
|
||||||
|
err = json.Indent(&prettyJSON, body, "", " ")
|
||||||
|
log.Println(string(prettyJSON.Bytes()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if statusCode >= 400 && statusCode <= 599 {
|
||||||
|
errorResponse := ErrorResponse{}
|
||||||
|
err = json.Unmarshal(body, &errorResponse)
|
||||||
|
ecsError := &Error{
|
||||||
|
ErrorResponse: errorResponse,
|
||||||
|
StatusCode: statusCode,
|
||||||
|
}
|
||||||
|
return ecsError
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(body, response)
|
||||||
|
//log.Printf("%++v", response)
|
||||||
|
if err != nil {
|
||||||
|
return GetClientError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke sends the raw HTTP request for ECS services
|
||||||
|
//改进了一下上面那个方法,可以使用各种Http方法
|
||||||
|
//2017.1.30 增加了一个path参数,用来拓展访问的地址
|
||||||
|
func (client *Client) InvokeByAnyMethod(method, action, path string, args interface{}, response interface{}) error {
|
||||||
|
|
||||||
|
request := Request{}
|
||||||
|
request.init(client.version, action, client.AccessKeyId)
|
||||||
|
|
||||||
|
data := util.ConvertToQueryValues(request)
|
||||||
|
util.SetQueryValues(args, &data)
|
||||||
|
|
||||||
|
// Sign request
|
||||||
|
signature := util.CreateSignatureForRequest(method, &data, client.AccessKeySecret)
|
||||||
|
|
||||||
|
data.Add("Signature", signature)
|
||||||
|
// Generate the request URL
|
||||||
|
var (
|
||||||
|
httpReq *http.Request
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if method == http.MethodGet {
|
||||||
|
requestURL := client.endpoint + path + "?" + data.Encode()
|
||||||
|
//fmt.Println(requestURL)
|
||||||
|
httpReq, err = http.NewRequest(method, requestURL, nil)
|
||||||
|
} else {
|
||||||
|
//fmt.Println(client.endpoint + path)
|
||||||
|
httpReq, err = http.NewRequest(method, client.endpoint + path, strings.NewReader(data.Encode()))
|
||||||
|
httpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return GetClientError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO move to util and add build val flag
|
||||||
|
httpReq.Header.Set("X-SDK-Client", `AliyunGO/` + Version)
|
||||||
|
|
||||||
|
t0 := time.Now()
|
||||||
|
httpResp, err := client.httpClient.Do(httpReq)
|
||||||
|
t1 := time.Now()
|
||||||
|
if err != nil {
|
||||||
|
return GetClientError(err)
|
||||||
|
}
|
||||||
|
statusCode := httpResp.StatusCode
|
||||||
|
|
||||||
|
if client.debug {
|
||||||
|
log.Printf("Invoke %s %s %d (%v) %v", ECSRequestMethod, client.endpoint, statusCode, t1.Sub(t0), data.Encode())
|
||||||
|
}
|
||||||
|
|
||||||
|
defer httpResp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(httpResp.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return GetClientError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if client.debug {
|
||||||
|
var prettyJSON bytes.Buffer
|
||||||
|
err = json.Indent(&prettyJSON, body, "", " ")
|
||||||
|
log.Println(string(prettyJSON.Bytes()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if statusCode >= 400 && statusCode <= 599 {
|
||||||
|
errorResponse := ErrorResponse{}
|
||||||
|
err = json.Unmarshal(body, &errorResponse)
|
||||||
|
ecsError := &Error{
|
||||||
|
ErrorResponse: errorResponse,
|
||||||
|
StatusCode: statusCode,
|
||||||
|
}
|
||||||
|
return ecsError
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(body, response)
|
||||||
|
//log.Printf("%++v", response)
|
||||||
|
if err != nil {
|
||||||
|
return GetClientError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateClientToken generates the Client Token with random string
|
||||||
|
func (client *Client) GenerateClientToken() string {
|
||||||
|
return util.CreateRandomString()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetClientErrorFromString(str string) error {
|
||||||
|
return &Error{
|
||||||
|
ErrorResponse: ErrorResponse{
|
||||||
|
Code: "AliyunGoClientFailure",
|
||||||
|
Message: str,
|
||||||
|
},
|
||||||
|
StatusCode: -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetClientError(err error) error {
|
||||||
|
return GetClientErrorFromString(err.Error())
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
// Region represents ECS region
|
||||||
|
type Region string
|
||||||
|
|
||||||
|
// Constants of region definition
|
||||||
|
const (
|
||||||
|
Hangzhou = Region("cn-hangzhou")
|
||||||
|
Qingdao = Region("cn-qingdao")
|
||||||
|
Beijing = Region("cn-beijing")
|
||||||
|
Hongkong = Region("cn-hongkong")
|
||||||
|
Shenzhen = Region("cn-shenzhen")
|
||||||
|
USWest1 = Region("us-west-1")
|
||||||
|
USEast1 = Region("us-east-1")
|
||||||
|
APSouthEast1 = Region("ap-southeast-1")
|
||||||
|
Shanghai = Region("cn-shanghai")
|
||||||
|
MEEast1 = Region("me-east-1")
|
||||||
|
APNorthEast1 = Region("ap-northeast-1")
|
||||||
|
APSouthEast2 = Region("ap-southeast-2")
|
||||||
|
EUCentral1 = Region("eu-central-1")
|
||||||
|
)
|
||||||
|
|
||||||
|
var ValidRegions = []Region{
|
||||||
|
Hangzhou, Qingdao, Beijing, Shenzhen, Hongkong, Shanghai,
|
||||||
|
USWest1, USEast1,
|
||||||
|
APNorthEast1, APSouthEast1, APSouthEast2,
|
||||||
|
MEEast1,
|
||||||
|
EUCentral1,
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants for Aliyun API requests
|
||||||
|
const (
|
||||||
|
SignatureVersion = "1.0"
|
||||||
|
SignatureMethod = "HMAC-SHA1"
|
||||||
|
JSONResponseFormat = "JSON"
|
||||||
|
XMLResponseFormat = "XML"
|
||||||
|
ECSRequestMethod = "GET"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
Format string
|
||||||
|
Version string
|
||||||
|
AccessKeyId string
|
||||||
|
Signature string
|
||||||
|
SignatureMethod string
|
||||||
|
Timestamp util.ISO6801Time
|
||||||
|
SignatureVersion string
|
||||||
|
SignatureNonce string
|
||||||
|
ResourceOwnerAccount string
|
||||||
|
Action string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request *Request) init(version string, action string, AccessKeyId string) {
|
||||||
|
request.Format = JSONResponseFormat
|
||||||
|
request.Timestamp = util.NewISO6801Time(time.Now().UTC())
|
||||||
|
request.Version = version
|
||||||
|
request.SignatureVersion = SignatureVersion
|
||||||
|
request.SignatureMethod = SignatureMethod
|
||||||
|
request.SignatureNonce = util.CreateRandomString()
|
||||||
|
request.Action = action
|
||||||
|
request.AccessKeyId = AccessKeyId
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
RequestId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorResponse struct {
|
||||||
|
Response
|
||||||
|
HostId string
|
||||||
|
Code string
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Error represents a custom error for Aliyun API failure response
|
||||||
|
type Error struct {
|
||||||
|
ErrorResponse
|
||||||
|
StatusCode int //Status Code of HTTP Response
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Error) Error() string {
|
||||||
|
return fmt.Sprintf("Aliyun API Error: RequestId: %s Status Code: %d Code: %s Message: %s", e.RequestId, e.StatusCode, e.Code, e.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pagination struct {
|
||||||
|
PageNumber int
|
||||||
|
PageSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pagination) SetPageSize(size int) {
|
||||||
|
p.PageSize = size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pagination) Validate() {
|
||||||
|
if p.PageNumber < 0 {
|
||||||
|
log.Printf("Invalid PageNumber: %d", p.PageNumber)
|
||||||
|
p.PageNumber = 1
|
||||||
|
}
|
||||||
|
if p.PageSize < 0 {
|
||||||
|
log.Printf("Invalid PageSize: %d", p.PageSize)
|
||||||
|
p.PageSize = 10
|
||||||
|
} else if p.PageSize > 50 {
|
||||||
|
log.Printf("Invalid PageSize: %d", p.PageSize)
|
||||||
|
p.PageSize = 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A PaginationResponse represents a response with pagination information
|
||||||
|
type PaginationResult struct {
|
||||||
|
TotalCount int
|
||||||
|
PageNumber int
|
||||||
|
PageSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextPage gets the next page of the result set
|
||||||
|
func (r *PaginationResult) NextPage() *Pagination {
|
||||||
|
if r.PageNumber*r.PageSize >= r.TotalCount {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &Pagination{PageNumber: r.PageNumber + 1, PageSize: r.PageSize}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
type InternetChargeType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
PayByBandwidth = InternetChargeType("PayByBandwidth")
|
||||||
|
PayByTraffic = InternetChargeType("PayByTraffic")
|
||||||
|
)
|
||||||
|
|
||||||
|
type InstanceChargeType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrePaid = InstanceChargeType("PrePaid")
|
||||||
|
PostPaid = InstanceChargeType("PostPaid")
|
||||||
|
)
|
|
@ -0,0 +1,3 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
const Version = "0.1"
|
|
@ -0,0 +1,37 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Interval for checking status in WaitForXXX method
|
||||||
|
const DefaultWaitForInterval = 5
|
||||||
|
|
||||||
|
// Default timeout value for WaitForXXX method
|
||||||
|
const DefaultTimeout = 60
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
common.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ECSDefaultEndpoint is the default API endpoint of ECS services
|
||||||
|
ECSDefaultEndpoint = "https://ecs-cn-hangzhou.aliyuncs.com"
|
||||||
|
ECSAPIVersion = "2014-05-26"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewClient creates a new instance of ECS client
|
||||||
|
func NewClient(accessKeyId, accessKeySecret string) *Client {
|
||||||
|
endpoint := os.Getenv("ECS_ENDPOINT")
|
||||||
|
if endpoint == "" {
|
||||||
|
endpoint = ECSDefaultEndpoint
|
||||||
|
}
|
||||||
|
return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client {
|
||||||
|
client := &Client{}
|
||||||
|
client.Init(endpoint, ECSAPIVersion, accessKeyId, accessKeySecret)
|
||||||
|
return client
|
||||||
|
}
|
|
@ -0,0 +1,330 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Types of disks
|
||||||
|
type DiskType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
DiskTypeAll = DiskType("all") //Default
|
||||||
|
DiskTypeAllSystem = DiskType("system")
|
||||||
|
DiskTypeAllData = DiskType("data")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Categories of disks
|
||||||
|
type DiskCategory string
|
||||||
|
|
||||||
|
const (
|
||||||
|
DiskCategoryAll = DiskCategory("all") //Default
|
||||||
|
DiskCategoryCloud = DiskCategory("cloud")
|
||||||
|
DiskCategoryEphemeral = DiskCategory("ephemeral")
|
||||||
|
DiskCategoryEphemeralSSD = DiskCategory("ephemeral_ssd")
|
||||||
|
DiskCategoryCloudEfficiency = DiskCategory("cloud_efficiency")
|
||||||
|
DiskCategoryCloudSSD = DiskCategory("cloud_ssd")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Status of disks
|
||||||
|
type DiskStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
DiskStatusInUse = DiskStatus("In_use")
|
||||||
|
DiskStatusAvailable = DiskStatus("Available")
|
||||||
|
DiskStatusAttaching = DiskStatus("Attaching")
|
||||||
|
DiskStatusDetaching = DiskStatus("Detaching")
|
||||||
|
DiskStatusCreating = DiskStatus("Creating")
|
||||||
|
DiskStatusReIniting = DiskStatus("ReIniting")
|
||||||
|
DiskStatusAll = DiskStatus("All") //Default
|
||||||
|
)
|
||||||
|
|
||||||
|
// Charge type of disks
|
||||||
|
type DiskChargeType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrePaid = DiskChargeType("PrePaid")
|
||||||
|
PostPaid = DiskChargeType("PostPaid")
|
||||||
|
)
|
||||||
|
|
||||||
|
// A DescribeDisksArgs defines the arguments to describe disks
|
||||||
|
type DescribeDisksArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ZoneId string
|
||||||
|
DiskIds []string
|
||||||
|
InstanceId string
|
||||||
|
DiskType DiskType //enum for all(default) | system | data
|
||||||
|
Category DiskCategory //enum for all(default) | cloud | ephemeral
|
||||||
|
Status DiskStatus //enum for In_use | Available | Attaching | Detaching | Creating | ReIniting | All(default)
|
||||||
|
SnapshotId string
|
||||||
|
Name string
|
||||||
|
Portable *bool //optional
|
||||||
|
DeleteWithInstance *bool //optional
|
||||||
|
DeleteAutoSnapshot *bool //optional
|
||||||
|
EnableAutoSnapshot *bool //optional
|
||||||
|
DiskChargeType DiskChargeType
|
||||||
|
Tag map[string]string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&diskitemtype
|
||||||
|
type DiskItemType struct {
|
||||||
|
DiskId string
|
||||||
|
RegionId common.Region
|
||||||
|
ZoneId string
|
||||||
|
DiskName string
|
||||||
|
Description string
|
||||||
|
Type DiskType
|
||||||
|
Category DiskCategory
|
||||||
|
Size int
|
||||||
|
ImageId string
|
||||||
|
SourceSnapshotId string
|
||||||
|
ProductCode string
|
||||||
|
Portable bool
|
||||||
|
Status DiskStatus
|
||||||
|
OperationLocks OperationLocksType
|
||||||
|
InstanceId string
|
||||||
|
Device string
|
||||||
|
DeleteWithInstance bool
|
||||||
|
DeleteAutoSnapshot bool
|
||||||
|
EnableAutoSnapshot bool
|
||||||
|
CreationTime util.ISO6801Time
|
||||||
|
AttachedTime util.ISO6801Time
|
||||||
|
DetachedTime util.ISO6801Time
|
||||||
|
DiskChargeType DiskChargeType
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeDisksResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
RegionId common.Region
|
||||||
|
Disks struct {
|
||||||
|
Disk []DiskItemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeDisks describes Disks
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&describedisks
|
||||||
|
func (client *Client) DescribeDisks(args *DescribeDisksArgs) (disks []DiskItemType, pagination *common.PaginationResult, err error) {
|
||||||
|
response := DescribeDisksResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeDisks", args, &response)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.Disks.Disk, &response.PaginationResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateDiskArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ZoneId string
|
||||||
|
DiskName string
|
||||||
|
Description string
|
||||||
|
DiskCategory DiskCategory
|
||||||
|
Size int
|
||||||
|
SnapshotId string
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateDisksResponse struct {
|
||||||
|
common.Response
|
||||||
|
DiskId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDisk creates a new disk
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&createdisk
|
||||||
|
func (client *Client) CreateDisk(args *CreateDiskArgs) (diskId string, err error) {
|
||||||
|
response := CreateDisksResponse{}
|
||||||
|
err = client.Invoke("CreateDisk", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response.DiskId, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteDiskArgs struct {
|
||||||
|
DiskId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteDiskResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteDisk deletes disk
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&deletedisk
|
||||||
|
func (client *Client) DeleteDisk(diskId string) error {
|
||||||
|
args := DeleteDiskArgs{
|
||||||
|
DiskId: diskId,
|
||||||
|
}
|
||||||
|
response := DeleteDiskResponse{}
|
||||||
|
err := client.Invoke("DeleteDisk", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReInitDiskArgs struct {
|
||||||
|
DiskId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReInitDiskResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReInitDisk reinitizes disk
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&reinitdisk
|
||||||
|
func (client *Client) ReInitDisk(diskId string) error {
|
||||||
|
args := ReInitDiskArgs{
|
||||||
|
DiskId: diskId,
|
||||||
|
}
|
||||||
|
response := ReInitDiskResponse{}
|
||||||
|
err := client.Invoke("ReInitDisk", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type AttachDiskArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
DiskId string
|
||||||
|
Device string
|
||||||
|
DeleteWithInstance bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type AttachDiskResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttachDisk attaches disk to instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&attachdisk
|
||||||
|
func (client *Client) AttachDisk(args *AttachDiskArgs) error {
|
||||||
|
response := AttachDiskResponse{}
|
||||||
|
err := client.Invoke("AttachDisk", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DetachDiskArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
DiskId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DetachDiskResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DetachDisk detaches disk from instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&detachdisk
|
||||||
|
func (client *Client) DetachDisk(instanceId string, diskId string) error {
|
||||||
|
args := DetachDiskArgs{
|
||||||
|
InstanceId: instanceId,
|
||||||
|
DiskId: diskId,
|
||||||
|
}
|
||||||
|
response := DetachDiskResponse{}
|
||||||
|
err := client.Invoke("DetachDisk", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResetDiskArgs struct {
|
||||||
|
DiskId string
|
||||||
|
SnapshotId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResetDiskResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetDisk resets disk to original status
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&resetdisk
|
||||||
|
func (client *Client) ResetDisk(diskId string, snapshotId string) error {
|
||||||
|
args := ResetDiskArgs{
|
||||||
|
SnapshotId: snapshotId,
|
||||||
|
DiskId: diskId,
|
||||||
|
}
|
||||||
|
response := ResetDiskResponse{}
|
||||||
|
err := client.Invoke("ResetDisk", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyDiskAttributeArgs struct {
|
||||||
|
DiskId string
|
||||||
|
DiskName string
|
||||||
|
Description string
|
||||||
|
DeleteWithInstance *bool
|
||||||
|
DeleteAutoSnapshot *bool
|
||||||
|
EnableAutoSnapshot *bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyDiskAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyDiskAttribute modifies disk attribute
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&modifydiskattribute
|
||||||
|
func (client *Client) ModifyDiskAttribute(args *ModifyDiskAttributeArgs) error {
|
||||||
|
response := ModifyDiskAttributeResponse{}
|
||||||
|
err := client.Invoke("ModifyDiskAttribute", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReplaceSystemDiskArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
ImageId string
|
||||||
|
SystemDisk SystemDiskType
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReplaceSystemDiskResponse struct {
|
||||||
|
common.Response
|
||||||
|
DiskId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReplaceSystemDisk replace system disk
|
||||||
|
//
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/ecs/open-api/disk/replacesystemdisk.html
|
||||||
|
func (client *Client) ReplaceSystemDisk(args *ReplaceSystemDiskArgs) (diskId string, err error) {
|
||||||
|
response := ReplaceSystemDiskResponse{}
|
||||||
|
err = client.Invoke("ReplaceSystemDisk", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response.DiskId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForDisk waits for disk to given status
|
||||||
|
func (client *Client) WaitForDisk(regionId common.Region, diskId string, status DiskStatus, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = DefaultTimeout
|
||||||
|
}
|
||||||
|
args := DescribeDisksArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
DiskIds: []string{diskId},
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
disks, _, err := client.DescribeDisks(&args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if disks == nil || len(disks) == 0 {
|
||||||
|
return common.GetClientErrorFromString("Not found")
|
||||||
|
}
|
||||||
|
if disks[0].Status == status {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,281 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ImageOwnerAlias represents image owner
|
||||||
|
type ImageOwnerAlias string
|
||||||
|
|
||||||
|
// Constants of image owner
|
||||||
|
const (
|
||||||
|
ImageOwnerSystem = ImageOwnerAlias("system")
|
||||||
|
ImageOwnerSelf = ImageOwnerAlias("self")
|
||||||
|
ImageOwnerOthers = ImageOwnerAlias("others")
|
||||||
|
ImageOwnerMarketplace = ImageOwnerAlias("marketplace")
|
||||||
|
ImageOwnerDefault = ImageOwnerAlias("") //Return the values for system, self, and others
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImageStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ImageStatusAvailable = ImageStatus("Available")
|
||||||
|
ImageStatusUnAvailable = ImageStatus("UnAvailable")
|
||||||
|
ImageStatusCreating = ImageStatus("Creating")
|
||||||
|
ImageStatusCreateFailed = ImageStatus("CreateFailed")
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImageUsage string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ImageUsageInstance = ImageUsage("instance")
|
||||||
|
ImageUsageNone = ImageUsage("none")
|
||||||
|
)
|
||||||
|
|
||||||
|
// DescribeImagesArgs repsents arguements to describe images
|
||||||
|
type DescribeImagesArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ImageId string
|
||||||
|
SnapshotId string
|
||||||
|
ImageName string
|
||||||
|
Status ImageStatus
|
||||||
|
ImageOwnerAlias ImageOwnerAlias
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeImagesResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
|
||||||
|
RegionId common.Region
|
||||||
|
Images struct {
|
||||||
|
Image []ImageType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&diskdevicemapping
|
||||||
|
type DiskDeviceMapping struct {
|
||||||
|
SnapshotId string
|
||||||
|
//Why Size Field is string-type.
|
||||||
|
Size string
|
||||||
|
Device string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&imagetype
|
||||||
|
type ImageType struct {
|
||||||
|
ImageId string
|
||||||
|
ImageVersion string
|
||||||
|
Architecture string
|
||||||
|
ImageName string
|
||||||
|
Description string
|
||||||
|
Size int
|
||||||
|
ImageOwnerAlias string
|
||||||
|
OSName string
|
||||||
|
OSType string
|
||||||
|
Platform string
|
||||||
|
DiskDeviceMappings struct {
|
||||||
|
DiskDeviceMapping []DiskDeviceMapping
|
||||||
|
}
|
||||||
|
ProductCode string
|
||||||
|
IsSubscribed bool
|
||||||
|
IsSelfShared string
|
||||||
|
IsCopied bool
|
||||||
|
IsSupportIoOptimized bool
|
||||||
|
Progress string
|
||||||
|
Usage ImageUsage
|
||||||
|
Status ImageStatus
|
||||||
|
CreationTime util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeImages describes images
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/image&describeimages
|
||||||
|
func (client *Client) DescribeImages(args *DescribeImagesArgs) (images []ImageType, pagination *common.PaginationResult, err error) {
|
||||||
|
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeImagesResponse{}
|
||||||
|
err = client.Invoke("DescribeImages", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return response.Images.Image, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImageArgs repsents arguements to create image
|
||||||
|
type CreateImageArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
SnapshotId string
|
||||||
|
InstanceId string
|
||||||
|
ImageName string
|
||||||
|
ImageVersion string
|
||||||
|
Description string
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateImageResponse struct {
|
||||||
|
common.Response
|
||||||
|
|
||||||
|
ImageId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImage creates a new image
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/image&createimage
|
||||||
|
func (client *Client) CreateImage(args *CreateImageArgs) (imageId string, err error) {
|
||||||
|
response := &CreateImageResponse{}
|
||||||
|
err = client.Invoke("CreateImage", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response.ImageId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteImageArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ImageId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteImageResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteImage deletes Image
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/image&deleteimage
|
||||||
|
func (client *Client) DeleteImage(regionId common.Region, imageId string) error {
|
||||||
|
args := DeleteImageArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
ImageId: imageId,
|
||||||
|
}
|
||||||
|
|
||||||
|
response := &DeleteImageResponse{}
|
||||||
|
return client.Invoke("DeleteImage", &args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyImageSharePermission repsents arguements to share image
|
||||||
|
type ModifyImageSharePermissionArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ImageId string
|
||||||
|
AddAccount []string
|
||||||
|
RemoveAccount []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can read doc at http://help.aliyun.com/document_detail/ecs/open-api/image/modifyimagesharepermission.html
|
||||||
|
func (client *Client) ModifyImageSharePermission(args *ModifyImageSharePermissionArgs) error {
|
||||||
|
req := url.Values{}
|
||||||
|
req.Add("RegionId", string(args.RegionId))
|
||||||
|
req.Add("ImageId", args.ImageId)
|
||||||
|
|
||||||
|
for i, item := range args.AddAccount {
|
||||||
|
req.Add("AddAccount."+strconv.Itoa(i+1), item)
|
||||||
|
}
|
||||||
|
for i, item := range args.RemoveAccount {
|
||||||
|
req.Add("RemoveAccount."+strconv.Itoa(i+1), item)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.Invoke("ModifyImageSharePermission", req, &common.Response{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountType struct {
|
||||||
|
AliyunId string
|
||||||
|
}
|
||||||
|
type ImageSharePermissionResponse struct {
|
||||||
|
common.Response
|
||||||
|
ImageId string
|
||||||
|
RegionId string
|
||||||
|
Accounts struct {
|
||||||
|
Account []AccountType
|
||||||
|
}
|
||||||
|
TotalCount int
|
||||||
|
PageNumber int
|
||||||
|
PageSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) DescribeImageSharePermission(args *ModifyImageSharePermissionArgs) (*ImageSharePermissionResponse, error) {
|
||||||
|
response := ImageSharePermissionResponse{}
|
||||||
|
err := client.Invoke("DescribeImageSharePermission", args, &response)
|
||||||
|
return &response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type CopyImageArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ImageId string
|
||||||
|
DestinationRegionId common.Region
|
||||||
|
DestinationImageName string
|
||||||
|
DestinationDescription string
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CopyImageResponse struct {
|
||||||
|
common.Response
|
||||||
|
ImageId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/25538.html
|
||||||
|
func (client *Client) CopyImage(args *CopyImageArgs) (string, error) {
|
||||||
|
response := &CopyImageResponse{}
|
||||||
|
err := client.Invoke("CopyImage", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response.ImageId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default timeout value for WaitForImageReady method
|
||||||
|
const ImageDefaultTimeout = 120
|
||||||
|
|
||||||
|
//Wait Image ready
|
||||||
|
func (client *Client) WaitForImageReady(regionId common.Region, imageId string, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = ImageDefaultTimeout
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
args := DescribeImagesArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
ImageId: imageId,
|
||||||
|
Status: ImageStatusCreating,
|
||||||
|
}
|
||||||
|
|
||||||
|
images, _, err := client.DescribeImages(&args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if images == nil || len(images) == 0 {
|
||||||
|
args.Status = ImageStatusAvailable
|
||||||
|
images, _, er := client.DescribeImages(&args)
|
||||||
|
if er == nil && len(images) == 1 {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
return common.GetClientErrorFromString("Not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if images[0].Progress == "100%" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CancelCopyImageRequest struct {
|
||||||
|
regionId common.Region
|
||||||
|
ImageId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/25539.html
|
||||||
|
func (client *Client) CancelCopyImage(regionId common.Region, imageId string) error {
|
||||||
|
response := &common.Response{}
|
||||||
|
err := client.Invoke("CancelCopyImage", &CancelCopyImageRequest{regionId, imageId}, &response)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import "github.com/denverdino/aliyungo/common"
|
||||||
|
|
||||||
|
type DescribeInstanceTypesArgs struct {
|
||||||
|
InstanceTypeFamily string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancetypeitemtype
|
||||||
|
type InstanceTypeItemType struct {
|
||||||
|
InstanceTypeId string
|
||||||
|
CpuCoreCount int
|
||||||
|
MemorySize float64
|
||||||
|
InstanceTypeFamily string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstanceTypesResponse struct {
|
||||||
|
common.Response
|
||||||
|
InstanceTypes struct {
|
||||||
|
InstanceType []InstanceTypeItemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeInstanceTypes describes all instance types
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/other&describeinstancetypes
|
||||||
|
func (client *Client) DescribeInstanceTypes() (instanceTypes []InstanceTypeItemType, err error) {
|
||||||
|
response := DescribeInstanceTypesResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeInstanceTypes", &DescribeInstanceTypesArgs{}, &response)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []InstanceTypeItemType{}, err
|
||||||
|
}
|
||||||
|
return response.InstanceTypes.InstanceType, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// support user args
|
||||||
|
func (client *Client) DescribeInstanceTypesNew(args *DescribeInstanceTypesArgs) (instanceTypes []InstanceTypeItemType, err error) {
|
||||||
|
response := DescribeInstanceTypesResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeInstanceTypes", args, &response)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []InstanceTypeItemType{}, err
|
||||||
|
}
|
||||||
|
return response.InstanceTypes.InstanceType, nil
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,611 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InstanceStatus represents instance status
|
||||||
|
type InstanceStatus string
|
||||||
|
|
||||||
|
// Constants of InstanceStatus
|
||||||
|
const (
|
||||||
|
Creating = InstanceStatus("Creating") // For backward compatability
|
||||||
|
Pending = InstanceStatus("Pending")
|
||||||
|
Running = InstanceStatus("Running")
|
||||||
|
Starting = InstanceStatus("Starting")
|
||||||
|
|
||||||
|
Stopped = InstanceStatus("Stopped")
|
||||||
|
Stopping = InstanceStatus("Stopping")
|
||||||
|
Deleted = InstanceStatus("Deleted")
|
||||||
|
)
|
||||||
|
|
||||||
|
type LockReason string
|
||||||
|
|
||||||
|
const (
|
||||||
|
LockReasonFinancial = LockReason("financial")
|
||||||
|
LockReasonSecurity = LockReason("security")
|
||||||
|
)
|
||||||
|
|
||||||
|
type LockReasonType struct {
|
||||||
|
LockReason LockReason
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeUserdataArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancestatusitemtype
|
||||||
|
type DescribeUserdataItemType struct {
|
||||||
|
UserData string
|
||||||
|
InstanceId string
|
||||||
|
RegionId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeUserdataResponse struct {
|
||||||
|
common.Response
|
||||||
|
DescribeUserdataItemType
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeInstanceStatus describes instance status
|
||||||
|
//
|
||||||
|
// You can read doc at https://intl.aliyun.com/help/doc-detail/49227.htm
|
||||||
|
func (client *Client) DescribeUserdata(args *DescribeUserdataArgs) (userData *DescribeUserdataItemType, err error) {
|
||||||
|
response := DescribeUserdataResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeUserdata", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return &response.DescribeUserdataItemType, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstanceStatusArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ZoneId string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancestatusitemtype
|
||||||
|
type InstanceStatusItemType struct {
|
||||||
|
InstanceId string
|
||||||
|
Status InstanceStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstanceStatusResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
InstanceStatuses struct {
|
||||||
|
InstanceStatus []InstanceStatusItemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeInstanceStatus describes instance status
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&describeinstancestatus
|
||||||
|
func (client *Client) DescribeInstanceStatus(args *DescribeInstanceStatusArgs) (instanceStatuses []InstanceStatusItemType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeInstanceStatusResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeInstanceStatus", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.InstanceStatuses.InstanceStatus, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type StopInstanceArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
ForceStop bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type StopInstanceResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopInstance stops instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&stopinstance
|
||||||
|
func (client *Client) StopInstance(instanceId string, forceStop bool) error {
|
||||||
|
args := StopInstanceArgs{
|
||||||
|
InstanceId: instanceId,
|
||||||
|
ForceStop: forceStop,
|
||||||
|
}
|
||||||
|
response := StopInstanceResponse{}
|
||||||
|
err := client.Invoke("StopInstance", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type StartInstanceArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StartInstanceResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartInstance starts instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&startinstance
|
||||||
|
func (client *Client) StartInstance(instanceId string) error {
|
||||||
|
args := StartInstanceArgs{InstanceId: instanceId}
|
||||||
|
response := StartInstanceResponse{}
|
||||||
|
err := client.Invoke("StartInstance", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type RebootInstanceArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
ForceStop bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type RebootInstanceResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// RebootInstance reboot instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&rebootinstance
|
||||||
|
func (client *Client) RebootInstance(instanceId string, forceStop bool) error {
|
||||||
|
request := RebootInstanceArgs{
|
||||||
|
InstanceId: instanceId,
|
||||||
|
ForceStop: forceStop,
|
||||||
|
}
|
||||||
|
response := RebootInstanceResponse{}
|
||||||
|
err := client.Invoke("RebootInstance", &request, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstanceAttributeArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&operationlockstype
|
||||||
|
type OperationLocksType struct {
|
||||||
|
LockReason []LockReasonType //enum for financial, security
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&securitygroupidsettype
|
||||||
|
type SecurityGroupIdSetType struct {
|
||||||
|
SecurityGroupId string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&ipaddresssettype
|
||||||
|
type IpAddressSetType struct {
|
||||||
|
IpAddress []string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vpcattributestype
|
||||||
|
type VpcAttributesType struct {
|
||||||
|
VpcId string
|
||||||
|
VSwitchId string
|
||||||
|
PrivateIpAddress IpAddressSetType
|
||||||
|
NatIpAddress string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&eipaddressassociatetype
|
||||||
|
type EipAddressAssociateType struct {
|
||||||
|
AllocationId string
|
||||||
|
IpAddress string
|
||||||
|
Bandwidth int
|
||||||
|
InternetChargeType common.InternetChargeType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Experimental feature
|
||||||
|
type SpotStrategyType string
|
||||||
|
|
||||||
|
// Constants of SpotStrategyType
|
||||||
|
const (
|
||||||
|
NoSpot = SpotStrategyType("NoSpot")
|
||||||
|
SpotWithPriceLimit = SpotStrategyType("SpotWithPriceLimit")
|
||||||
|
)
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instanceattributestype
|
||||||
|
type InstanceAttributesType struct {
|
||||||
|
InstanceId string
|
||||||
|
InstanceName string
|
||||||
|
Description string
|
||||||
|
ImageId string
|
||||||
|
RegionId common.Region
|
||||||
|
ZoneId string
|
||||||
|
CPU int
|
||||||
|
Memory int
|
||||||
|
ClusterId string
|
||||||
|
InstanceType string
|
||||||
|
InstanceTypeFamily string
|
||||||
|
HostName string
|
||||||
|
SerialNumber string
|
||||||
|
Status InstanceStatus
|
||||||
|
OperationLocks OperationLocksType
|
||||||
|
SecurityGroupIds struct {
|
||||||
|
SecurityGroupId []string
|
||||||
|
}
|
||||||
|
PublicIpAddress IpAddressSetType
|
||||||
|
InnerIpAddress IpAddressSetType
|
||||||
|
InstanceNetworkType string //enum Classic | Vpc
|
||||||
|
InternetMaxBandwidthIn int
|
||||||
|
InternetMaxBandwidthOut int
|
||||||
|
InternetChargeType common.InternetChargeType
|
||||||
|
CreationTime util.ISO6801Time //time.Time
|
||||||
|
VpcAttributes VpcAttributesType
|
||||||
|
EipAddress EipAddressAssociateType
|
||||||
|
IoOptimized StringOrBool
|
||||||
|
InstanceChargeType common.InstanceChargeType
|
||||||
|
ExpiredTime util.ISO6801Time
|
||||||
|
Tags struct {
|
||||||
|
Tag []TagItemType
|
||||||
|
}
|
||||||
|
SpotStrategy SpotStrategyType
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstanceAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
InstanceAttributesType
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeInstanceAttribute describes instance attribute
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&describeinstanceattribute
|
||||||
|
func (client *Client) DescribeInstanceAttribute(instanceId string) (instance *InstanceAttributesType, err error) {
|
||||||
|
args := DescribeInstanceAttributeArgs{InstanceId: instanceId}
|
||||||
|
|
||||||
|
response := DescribeInstanceAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeInstanceAttribute", &args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &response.InstanceAttributesType, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyInstanceAttributeArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
InstanceName string
|
||||||
|
Description string
|
||||||
|
Password string
|
||||||
|
HostName string
|
||||||
|
UserData string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyInstanceAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
//ModifyInstanceAttribute modify instance attrbute
|
||||||
|
//
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/ecs/open-api/instance/modifyinstanceattribute.html
|
||||||
|
func (client *Client) ModifyInstanceAttribute(args *ModifyInstanceAttributeArgs) error {
|
||||||
|
response := ModifyInstanceAttributeResponse{}
|
||||||
|
err := client.Invoke("ModifyInstanceAttribute", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default timeout value for WaitForInstance method
|
||||||
|
const InstanceDefaultTimeout = 120
|
||||||
|
|
||||||
|
// WaitForInstance waits for instance to given status
|
||||||
|
func (client *Client) WaitForInstance(instanceId string, status InstanceStatus, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = InstanceDefaultTimeout
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
instance, err := client.DescribeInstanceAttribute(instanceId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if instance.Status == status {
|
||||||
|
//TODO
|
||||||
|
//Sleep one more time for timing issues
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForInstance waits for instance to given status
|
||||||
|
// when instance.NotFound wait until timeout
|
||||||
|
func (client *Client) WaitForInstanceAsyn(instanceId string, status InstanceStatus, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = InstanceDefaultTimeout
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
instance, err := client.DescribeInstanceAttribute(instanceId)
|
||||||
|
if err != nil {
|
||||||
|
e, _ := err.(*common.Error)
|
||||||
|
if e.ErrorResponse.Code != "InvalidInstanceId.NotFound" {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if instance.Status == status {
|
||||||
|
//TODO
|
||||||
|
//Sleep one more time for timing issues
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstanceVncUrlArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstanceVncUrlResponse struct {
|
||||||
|
common.Response
|
||||||
|
VncUrl string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&describeinstancevncurl
|
||||||
|
func (client *Client) DescribeInstanceVncUrl(args *DescribeInstanceVncUrlArgs) (string, error) {
|
||||||
|
response := DescribeInstanceVncUrlResponse{}
|
||||||
|
|
||||||
|
err := client.Invoke("DescribeInstanceVncUrl", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.VncUrl, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstancesArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
VpcId string
|
||||||
|
VSwitchId string
|
||||||
|
ZoneId string
|
||||||
|
InstanceIds string
|
||||||
|
InstanceNetworkType string
|
||||||
|
InstanceName string
|
||||||
|
Status InstanceStatus
|
||||||
|
PrivateIpAddresses string
|
||||||
|
InnerIpAddresses string
|
||||||
|
PublicIpAddresses string
|
||||||
|
SecurityGroupId string
|
||||||
|
Tag map[string]string
|
||||||
|
InstanceType string
|
||||||
|
SpotStrategy SpotStrategyType
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstancesResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
Instances struct {
|
||||||
|
Instance []InstanceAttributesType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeInstances describes instances
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&describeinstances
|
||||||
|
func (client *Client) DescribeInstances(args *DescribeInstancesArgs) (instances []InstanceAttributesType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeInstancesResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeInstances", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.Instances.Instance, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteInstanceArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteInstanceResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteInstance deletes instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&deleteinstance
|
||||||
|
func (client *Client) DeleteInstance(instanceId string) error {
|
||||||
|
args := DeleteInstanceArgs{InstanceId: instanceId}
|
||||||
|
response := DeleteInstanceResponse{}
|
||||||
|
err := client.Invoke("DeleteInstance", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DataDiskType struct {
|
||||||
|
Size int
|
||||||
|
Category DiskCategory //Enum cloud, ephemeral, ephemeral_ssd
|
||||||
|
SnapshotId string
|
||||||
|
DiskName string
|
||||||
|
Description string
|
||||||
|
Device string
|
||||||
|
DeleteWithInstance bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemDiskType struct {
|
||||||
|
Size int
|
||||||
|
Category DiskCategory //Enum cloud, ephemeral, ephemeral_ssd
|
||||||
|
DiskName string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type IoOptimized string
|
||||||
|
|
||||||
|
type StringOrBool struct {
|
||||||
|
Value bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||||
|
func (io *StringOrBool) UnmarshalJSON(value []byte) error {
|
||||||
|
if value[0] == '"' {
|
||||||
|
var str string
|
||||||
|
err := json.Unmarshal(value, &str)
|
||||||
|
if err == nil {
|
||||||
|
io.Value = (str == "true" || str == "optimized")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var boolVal bool
|
||||||
|
err := json.Unmarshal(value, &boolVal)
|
||||||
|
if err == nil {
|
||||||
|
io.Value = boolVal
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (io StringOrBool) Bool() bool {
|
||||||
|
return io.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (io StringOrBool) String() string {
|
||||||
|
return strconv.FormatBool(io.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
IoOptimizedNone = IoOptimized("none")
|
||||||
|
IoOptimizedOptimized = IoOptimized("optimized")
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateInstanceArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ZoneId string
|
||||||
|
ImageId string
|
||||||
|
InstanceType string
|
||||||
|
SecurityGroupId string
|
||||||
|
InstanceName string
|
||||||
|
Description string
|
||||||
|
InternetChargeType common.InternetChargeType
|
||||||
|
InternetMaxBandwidthIn int
|
||||||
|
InternetMaxBandwidthOut int
|
||||||
|
HostName string
|
||||||
|
Password string
|
||||||
|
IoOptimized IoOptimized
|
||||||
|
SystemDisk SystemDiskType
|
||||||
|
DataDisk []DataDiskType
|
||||||
|
VSwitchId string
|
||||||
|
PrivateIpAddress string
|
||||||
|
ClientToken string
|
||||||
|
InstanceChargeType common.InstanceChargeType
|
||||||
|
Period int
|
||||||
|
UserData string
|
||||||
|
AutoRenew bool
|
||||||
|
AutoRenewPeriod int
|
||||||
|
SpotStrategy SpotStrategyType
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateInstanceResponse struct {
|
||||||
|
common.Response
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateInstance creates instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&createinstance
|
||||||
|
func (client *Client) CreateInstance(args *CreateInstanceArgs) (instanceId string, err error) {
|
||||||
|
if args.UserData != "" {
|
||||||
|
// Encode to base64 string
|
||||||
|
args.UserData = base64.StdEncoding.EncodeToString([]byte(args.UserData))
|
||||||
|
}
|
||||||
|
response := CreateInstanceResponse{}
|
||||||
|
err = client.Invoke("CreateInstance", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response.InstanceId, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type RunInstanceArgs struct {
|
||||||
|
CreateInstanceArgs
|
||||||
|
MinAmount int
|
||||||
|
MaxAmount int
|
||||||
|
AutoReleaseTime string
|
||||||
|
NetworkType string
|
||||||
|
InnerIpAddress string
|
||||||
|
BusinessInfo string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RunInstanceResponse struct {
|
||||||
|
common.Response
|
||||||
|
InstanceIdSets InstanceIdSets
|
||||||
|
}
|
||||||
|
|
||||||
|
type InstanceIdSets struct {
|
||||||
|
InstanceIdSet []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BusinessInfo struct {
|
||||||
|
Pack string `json:"pack,omitempty" yaml:"pack,omitempty"`
|
||||||
|
ActivityId string `json:"activityId,omitempty" yaml:"activityId,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) RunInstances(args *RunInstanceArgs) (instanceIdSet []string, err error) {
|
||||||
|
if args.UserData != "" {
|
||||||
|
// Encode to base64 string
|
||||||
|
args.UserData = base64.StdEncoding.EncodeToString([]byte(args.UserData))
|
||||||
|
}
|
||||||
|
response := RunInstanceResponse{}
|
||||||
|
err = client.Invoke("RunInstances", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response.InstanceIdSets.InstanceIdSet, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecurityGroupArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
SecurityGroupId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecurityGroupResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
//JoinSecurityGroup
|
||||||
|
//
|
||||||
|
//You can read doc at https://help.aliyun.com/document_detail/ecs/open-api/instance/joinsecuritygroup.html
|
||||||
|
func (client *Client) JoinSecurityGroup(instanceId string, securityGroupId string) error {
|
||||||
|
args := SecurityGroupArgs{InstanceId: instanceId, SecurityGroupId: securityGroupId}
|
||||||
|
response := SecurityGroupResponse{}
|
||||||
|
err := client.Invoke("JoinSecurityGroup", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//LeaveSecurityGroup
|
||||||
|
//
|
||||||
|
//You can read doc at https://help.aliyun.com/document_detail/ecs/open-api/instance/leavesecuritygroup.html
|
||||||
|
func (client *Client) LeaveSecurityGroup(instanceId string, securityGroupId string) error {
|
||||||
|
args := SecurityGroupArgs{InstanceId: instanceId, SecurityGroupId: securityGroupId}
|
||||||
|
response := SecurityGroupResponse{}
|
||||||
|
err := client.Invoke("LeaveSecurityGroup", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DescribeInstanceMonitorDataArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
StartTime util.ISO6801Time
|
||||||
|
EndTime util.ISO6801Time
|
||||||
|
Period int //Default 60s
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancemonitordatatype
|
||||||
|
type InstanceMonitorDataType struct {
|
||||||
|
InstanceId string
|
||||||
|
CPU int
|
||||||
|
IntranetRX int
|
||||||
|
IntranetTX int
|
||||||
|
IntranetBandwidth int
|
||||||
|
InternetRX int
|
||||||
|
InternetTX int
|
||||||
|
InternetBandwidth int
|
||||||
|
IOPSRead int
|
||||||
|
IOPSWrite int
|
||||||
|
BPSRead int
|
||||||
|
BPSWrite int
|
||||||
|
TimeStamp util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeInstanceMonitorDataResponse struct {
|
||||||
|
common.Response
|
||||||
|
MonitorData struct {
|
||||||
|
InstanceMonitorData []InstanceMonitorDataType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeInstanceMonitorData describes instance monitoring data
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/monitor&describeinstancemonitordata
|
||||||
|
func (client *Client) DescribeInstanceMonitorData(args *DescribeInstanceMonitorDataArgs) (monitorData []InstanceMonitorDataType, err error) {
|
||||||
|
if args.Period == 0 {
|
||||||
|
args.Period = 60
|
||||||
|
}
|
||||||
|
response := DescribeInstanceMonitorDataResponse{}
|
||||||
|
err = client.Invoke("DescribeInstanceMonitorData", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response.MonitorData.InstanceMonitorData, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeEipMonitorDataArgs struct {
|
||||||
|
AllocationId string
|
||||||
|
StartTime util.ISO6801Time
|
||||||
|
EndTime util.ISO6801Time
|
||||||
|
Period int //Default 60s
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&eipmonitordatatype
|
||||||
|
type EipMonitorDataType struct {
|
||||||
|
EipRX int
|
||||||
|
EipTX int
|
||||||
|
EipFlow int
|
||||||
|
EipBandwidth int
|
||||||
|
EipPackets int
|
||||||
|
TimeStamp util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeEipMonitorDataResponse struct {
|
||||||
|
common.Response
|
||||||
|
EipMonitorDatas struct {
|
||||||
|
EipMonitorData []EipMonitorDataType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeEipMonitorData describes EIP monitoring data
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/monitor&describeeipmonitordata
|
||||||
|
func (client *Client) DescribeEipMonitorData(args *DescribeEipMonitorDataArgs) (monitorData []EipMonitorDataType, err error) {
|
||||||
|
if args.Period == 0 {
|
||||||
|
args.Period = 60
|
||||||
|
}
|
||||||
|
response := DescribeEipMonitorDataResponse{}
|
||||||
|
err = client.Invoke("DescribeEipMonitorData", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response.EipMonitorDatas.EipMonitorData, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeDiskMonitorDataArgs struct {
|
||||||
|
DiskId string
|
||||||
|
StartTime util.ISO6801Time
|
||||||
|
EndTime util.ISO6801Time
|
||||||
|
Period int //Default 60s
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&diskmonitordatatype
|
||||||
|
type DiskMonitorDataType struct {
|
||||||
|
DiskId string
|
||||||
|
IOPSRead int
|
||||||
|
IOPSWrite int
|
||||||
|
IOPSTotal int
|
||||||
|
BPSRead int
|
||||||
|
BPSWrite int
|
||||||
|
BPSTotal int
|
||||||
|
TimeStamp util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeDiskMonitorDataResponse struct {
|
||||||
|
common.Response
|
||||||
|
TotalCount int
|
||||||
|
MonitorData struct {
|
||||||
|
DiskMonitorData []DiskMonitorDataType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeDiskMonitorData describes disk monitoring data
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/monitor&describediskmonitordata
|
||||||
|
func (client *Client) DescribeDiskMonitorData(args *DescribeDiskMonitorDataArgs) (monitorData []DiskMonitorDataType, totalCount int, err error) {
|
||||||
|
if args.Period == 0 {
|
||||||
|
args.Period = 60
|
||||||
|
}
|
||||||
|
response := DescribeDiskMonitorDataResponse{}
|
||||||
|
err = client.Invoke("DescribeDiskMonitorData", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
return response.MonitorData.DiskMonitorData, response.TotalCount, err
|
||||||
|
}
|
|
@ -0,0 +1,249 @@
|
||||||
|
// API on Network
|
||||||
|
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AllocatePublicIpAddressArgs struct {
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllocatePublicIpAddressResponse struct {
|
||||||
|
common.Response
|
||||||
|
|
||||||
|
IpAddress string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllocatePublicIpAddress allocates Public Ip Address
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&allocatepublicipaddress
|
||||||
|
func (client *Client) AllocatePublicIpAddress(instanceId string) (ipAddress string, err error) {
|
||||||
|
args := AllocatePublicIpAddressArgs{
|
||||||
|
InstanceId: instanceId,
|
||||||
|
}
|
||||||
|
response := AllocatePublicIpAddressResponse{}
|
||||||
|
err = client.Invoke("AllocatePublicIpAddress", &args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response.IpAddress, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyInstanceNetworkSpec struct {
|
||||||
|
InstanceId string
|
||||||
|
InternetMaxBandwidthOut *int
|
||||||
|
InternetMaxBandwidthIn *int
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyInstanceNetworkSpecResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyInstanceNetworkSpec modifies instance network spec
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&modifyinstancenetworkspec
|
||||||
|
func (client *Client) ModifyInstanceNetworkSpec(args *ModifyInstanceNetworkSpec) error {
|
||||||
|
|
||||||
|
response := ModifyInstanceNetworkSpecResponse{}
|
||||||
|
return client.Invoke("ModifyInstanceNetworkSpec", args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllocateEipAddressArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
Bandwidth int
|
||||||
|
InternetChargeType common.InternetChargeType
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllocateEipAddressResponse struct {
|
||||||
|
common.Response
|
||||||
|
EipAddress string
|
||||||
|
AllocationId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllocateEipAddress allocates Eip Address
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&allocateeipaddress
|
||||||
|
func (client *Client) AllocateEipAddress(args *AllocateEipAddressArgs) (EipAddress string, AllocationId string, err error) {
|
||||||
|
if args.Bandwidth == 0 {
|
||||||
|
args.Bandwidth = 5
|
||||||
|
}
|
||||||
|
response := AllocateEipAddressResponse{}
|
||||||
|
err = client.Invoke("AllocateEipAddress", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
return response.EipAddress, response.AllocationId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssociateEipAddressArgs struct {
|
||||||
|
AllocationId string
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssociateEipAddressResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssociateEipAddress associates EIP address to VM instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&associateeipaddress
|
||||||
|
func (client *Client) AssociateEipAddress(allocationId string, instanceId string) error {
|
||||||
|
args := AssociateEipAddressArgs{
|
||||||
|
AllocationId: allocationId,
|
||||||
|
InstanceId: instanceId,
|
||||||
|
}
|
||||||
|
response := ModifyInstanceNetworkSpecResponse{}
|
||||||
|
return client.Invoke("AssociateEipAddress", &args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status of disks
|
||||||
|
type EipStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
EipStatusAssociating = EipStatus("Associating")
|
||||||
|
EipStatusUnassociating = EipStatus("Unassociating")
|
||||||
|
EipStatusInUse = EipStatus("InUse")
|
||||||
|
EipStatusAvailable = EipStatus("Available")
|
||||||
|
)
|
||||||
|
|
||||||
|
type DescribeEipAddressesArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
Status EipStatus //enum Associating | Unassociating | InUse | Available
|
||||||
|
EipAddress string
|
||||||
|
AllocationId string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&eipaddresssettype
|
||||||
|
type EipAddressSetType struct {
|
||||||
|
RegionId common.Region
|
||||||
|
IpAddress string
|
||||||
|
AllocationId string
|
||||||
|
Status EipStatus
|
||||||
|
InstanceId string
|
||||||
|
Bandwidth string // Why string
|
||||||
|
InternetChargeType common.InternetChargeType
|
||||||
|
OperationLocks OperationLocksType
|
||||||
|
AllocationTime util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeEipAddressesResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
EipAddresses struct {
|
||||||
|
EipAddress []EipAddressSetType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeInstanceStatus describes instance status
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&describeeipaddresses
|
||||||
|
func (client *Client) DescribeEipAddresses(args *DescribeEipAddressesArgs) (eipAddresses []EipAddressSetType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeEipAddressesResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeEipAddresses", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.EipAddresses.EipAddress, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyEipAddressAttributeArgs struct {
|
||||||
|
AllocationId string
|
||||||
|
Bandwidth int
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyEipAddressAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyEipAddressAttribute Modifies EIP attribute
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&modifyeipaddressattribute
|
||||||
|
func (client *Client) ModifyEipAddressAttribute(allocationId string, bandwidth int) error {
|
||||||
|
args := ModifyEipAddressAttributeArgs{
|
||||||
|
AllocationId: allocationId,
|
||||||
|
Bandwidth: bandwidth,
|
||||||
|
}
|
||||||
|
response := ModifyEipAddressAttributeResponse{}
|
||||||
|
return client.Invoke("ModifyEipAddressAttribute", &args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnallocateEipAddressArgs struct {
|
||||||
|
AllocationId string
|
||||||
|
InstanceId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnallocateEipAddressResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnassociateEipAddress unallocates Eip Address from instance
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&unassociateeipaddress
|
||||||
|
func (client *Client) UnassociateEipAddress(allocationId string, instanceId string) error {
|
||||||
|
args := UnallocateEipAddressArgs{
|
||||||
|
AllocationId: allocationId,
|
||||||
|
InstanceId: instanceId,
|
||||||
|
}
|
||||||
|
response := UnallocateEipAddressResponse{}
|
||||||
|
return client.Invoke("UnassociateEipAddress", &args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReleaseEipAddressArgs struct {
|
||||||
|
AllocationId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReleaseEipAddressResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseEipAddress releases Eip address
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&releaseeipaddress
|
||||||
|
func (client *Client) ReleaseEipAddress(allocationId string) error {
|
||||||
|
args := ReleaseEipAddressArgs{
|
||||||
|
AllocationId: allocationId,
|
||||||
|
}
|
||||||
|
response := ReleaseEipAddressResponse{}
|
||||||
|
return client.Invoke("ReleaseEipAddress", &args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForVSwitchAvailable waits for VSwitch to given status
|
||||||
|
func (client *Client) WaitForEip(regionId common.Region, allocationId string, status EipStatus, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = DefaultTimeout
|
||||||
|
}
|
||||||
|
args := DescribeEipAddressesArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
AllocationId: allocationId,
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
eips, _, err := client.DescribeEipAddresses(&args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(eips) == 0 {
|
||||||
|
return common.GetClientErrorFromString("Not found")
|
||||||
|
}
|
||||||
|
if eips[0].Status == status {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import "github.com/denverdino/aliyungo/common"
|
||||||
|
|
||||||
|
type DescribeRegionsArgs struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype®iontype
|
||||||
|
type RegionType struct {
|
||||||
|
RegionId common.Region
|
||||||
|
LocalName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeRegionsResponse struct {
|
||||||
|
common.Response
|
||||||
|
Regions struct {
|
||||||
|
Region []RegionType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeRegions describes regions
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/region&describeregions
|
||||||
|
func (client *Client) DescribeRegions() (regions []RegionType, err error) {
|
||||||
|
response := DescribeRegionsResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeRegions", &DescribeRegionsArgs{}, &response)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []RegionType{}, err
|
||||||
|
}
|
||||||
|
return response.Regions.Region, nil
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DescribeRouteTablesArgs struct {
|
||||||
|
VRouterId string
|
||||||
|
RouteTableId string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
type RouteTableType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
RouteTableSystem = RouteTableType("System")
|
||||||
|
RouteTableCustom = RouteTableType("Custom")
|
||||||
|
)
|
||||||
|
|
||||||
|
type RouteEntryStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
RouteEntryStatusPending = RouteEntryStatus("Pending")
|
||||||
|
RouteEntryStatusAvailable = RouteEntryStatus("Available")
|
||||||
|
RouteEntryStatusModifying = RouteEntryStatus("Modifying")
|
||||||
|
)
|
||||||
|
|
||||||
|
type NextHopListType struct {
|
||||||
|
NextHopList struct {
|
||||||
|
NextHopItem []NextHopItemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type NextHopItemType struct {
|
||||||
|
NextHopType string
|
||||||
|
NextHopId string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&routeentrysettype
|
||||||
|
type RouteEntrySetType struct {
|
||||||
|
RouteTableId string
|
||||||
|
DestinationCidrBlock string
|
||||||
|
Type RouteTableType
|
||||||
|
NextHopType string
|
||||||
|
NextHopId string
|
||||||
|
NextHopList NextHopListType
|
||||||
|
InstanceId string
|
||||||
|
Status RouteEntryStatus // enum Pending | Available | Modifying
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&routetablesettype
|
||||||
|
type RouteTableSetType struct {
|
||||||
|
VRouterId string
|
||||||
|
RouteTableId string
|
||||||
|
RouteEntrys struct {
|
||||||
|
RouteEntry []RouteEntrySetType
|
||||||
|
}
|
||||||
|
RouteTableType RouteTableType
|
||||||
|
CreationTime util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeRouteTablesResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
RouteTables struct {
|
||||||
|
RouteTable []RouteTableSetType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeRouteTables describes Virtual Routers
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/routertable&describeroutetables
|
||||||
|
func (client *Client) DescribeRouteTables(args *DescribeRouteTablesArgs) (routeTables []RouteTableSetType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeRouteTablesResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeRouteTables", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.RouteTables.RouteTable, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type NextHopType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
NextHopIntance = NextHopType("Instance") //Default
|
||||||
|
NextHopTunnel = NextHopType("Tunnel")
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateRouteEntryArgs struct {
|
||||||
|
RouteTableId string
|
||||||
|
DestinationCidrBlock string
|
||||||
|
NextHopType NextHopType
|
||||||
|
NextHopId string
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateRouteEntryResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRouteEntry creates route entry
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/routertable&createrouteentry
|
||||||
|
func (client *Client) CreateRouteEntry(args *CreateRouteEntryArgs) error {
|
||||||
|
response := CreateRouteEntryResponse{}
|
||||||
|
return client.Invoke("CreateRouteEntry", args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteRouteEntryArgs struct {
|
||||||
|
RouteTableId string
|
||||||
|
DestinationCidrBlock string
|
||||||
|
NextHopId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteRouteEntryResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRouteEntry deletes route entry
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/routertable&deleterouteentry
|
||||||
|
func (client *Client) DeleteRouteEntry(args *DeleteRouteEntryArgs) error {
|
||||||
|
response := DeleteRouteEntryResponse{}
|
||||||
|
return client.Invoke("DeleteRouteEntry", args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForAllRouteEntriesAvailable waits for all route entries to Available status
|
||||||
|
func (client *Client) WaitForAllRouteEntriesAvailable(vrouterId string, routeTableId string, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = DefaultTimeout
|
||||||
|
}
|
||||||
|
args := DescribeRouteTablesArgs{
|
||||||
|
VRouterId: vrouterId,
|
||||||
|
RouteTableId: routeTableId,
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
|
||||||
|
routeTables, _, err := client.DescribeRouteTables(&args)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(routeTables) == 0 {
|
||||||
|
return common.GetClientErrorFromString("Not found")
|
||||||
|
}
|
||||||
|
success := true
|
||||||
|
|
||||||
|
loop:
|
||||||
|
for _, routeTable := range routeTables {
|
||||||
|
for _, routeEntry := range routeTable.RouteEntrys.RouteEntry {
|
||||||
|
if routeEntry.Status != RouteEntryStatusAvailable {
|
||||||
|
success = false
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if success {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,272 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NicType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
NicTypeInternet = NicType("internet")
|
||||||
|
NicTypeIntranet = NicType("intranet")
|
||||||
|
)
|
||||||
|
|
||||||
|
type IpProtocol string
|
||||||
|
|
||||||
|
const (
|
||||||
|
IpProtocolAll = IpProtocol("all")
|
||||||
|
IpProtocolTCP = IpProtocol("tcp")
|
||||||
|
IpProtocolUDP = IpProtocol("udp")
|
||||||
|
IpProtocolICMP = IpProtocol("icmp")
|
||||||
|
IpProtocolGRE = IpProtocol("gre")
|
||||||
|
)
|
||||||
|
|
||||||
|
type PermissionPolicy string
|
||||||
|
|
||||||
|
const (
|
||||||
|
PermissionPolicyAccept = PermissionPolicy("accept")
|
||||||
|
PermissionPolicyDrop = PermissionPolicy("drop")
|
||||||
|
)
|
||||||
|
|
||||||
|
type DescribeSecurityGroupAttributeArgs struct {
|
||||||
|
SecurityGroupId string
|
||||||
|
RegionId common.Region
|
||||||
|
NicType NicType //enum for internet (default) |intranet
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&permissiontype
|
||||||
|
type PermissionType struct {
|
||||||
|
IpProtocol IpProtocol
|
||||||
|
PortRange string
|
||||||
|
SourceCidrIp string
|
||||||
|
SourceGroupId string
|
||||||
|
SourceGroupOwnerAccount string
|
||||||
|
DestCidrIp string
|
||||||
|
DestGroupId string
|
||||||
|
DestGroupOwnerAccount string
|
||||||
|
Policy PermissionPolicy
|
||||||
|
NicType NicType
|
||||||
|
Priority int
|
||||||
|
Direction string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeSecurityGroupAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
|
||||||
|
SecurityGroupId string
|
||||||
|
SecurityGroupName string
|
||||||
|
RegionId common.Region
|
||||||
|
Description string
|
||||||
|
Permissions struct {
|
||||||
|
Permission []PermissionType
|
||||||
|
}
|
||||||
|
VpcId string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&describesecuritygroupattribute
|
||||||
|
func (client *Client) DescribeSecurityGroupAttribute(args *DescribeSecurityGroupAttributeArgs) (response *DescribeSecurityGroupAttributeResponse, err error) {
|
||||||
|
response = &DescribeSecurityGroupAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeSecurityGroupAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeSecurityGroupsArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
VpcId string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&securitygroupitemtype
|
||||||
|
type SecurityGroupItemType struct {
|
||||||
|
SecurityGroupId string
|
||||||
|
SecurityGroupName string
|
||||||
|
Description string
|
||||||
|
VpcId string
|
||||||
|
CreationTime util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeSecurityGroupsResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
|
||||||
|
RegionId common.Region
|
||||||
|
SecurityGroups struct {
|
||||||
|
SecurityGroup []SecurityGroupItemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeSecurityGroups describes security groups
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&describesecuritygroups
|
||||||
|
func (client *Client) DescribeSecurityGroups(args *DescribeSecurityGroupsArgs) (securityGroupItems []SecurityGroupItemType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeSecurityGroupsResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeSecurityGroups", args, &response)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.SecurityGroups.SecurityGroup, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateSecurityGroupArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
SecurityGroupName string
|
||||||
|
Description string
|
||||||
|
VpcId string
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateSecurityGroupResponse struct {
|
||||||
|
common.Response
|
||||||
|
|
||||||
|
SecurityGroupId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSecurityGroup creates security group
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&createsecuritygroup
|
||||||
|
func (client *Client) CreateSecurityGroup(args *CreateSecurityGroupArgs) (securityGroupId string, err error) {
|
||||||
|
response := CreateSecurityGroupResponse{}
|
||||||
|
err = client.Invoke("CreateSecurityGroup", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response.SecurityGroupId, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteSecurityGroupArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
SecurityGroupId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteSecurityGroupResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSecurityGroup deletes security group
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&deletesecuritygroup
|
||||||
|
func (client *Client) DeleteSecurityGroup(regionId common.Region, securityGroupId string) error {
|
||||||
|
args := DeleteSecurityGroupArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
SecurityGroupId: securityGroupId,
|
||||||
|
}
|
||||||
|
response := DeleteSecurityGroupResponse{}
|
||||||
|
err := client.Invoke("DeleteSecurityGroup", &args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifySecurityGroupAttributeArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
SecurityGroupId string
|
||||||
|
SecurityGroupName string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifySecurityGroupAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifySecurityGroupAttribute modifies attribute of security group
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&modifysecuritygroupattribute
|
||||||
|
func (client *Client) ModifySecurityGroupAttribute(args *ModifySecurityGroupAttributeArgs) error {
|
||||||
|
response := ModifySecurityGroupAttributeResponse{}
|
||||||
|
err := client.Invoke("ModifySecurityGroupAttribute", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthorizeSecurityGroupArgs struct {
|
||||||
|
SecurityGroupId string
|
||||||
|
RegionId common.Region
|
||||||
|
IpProtocol IpProtocol
|
||||||
|
PortRange string
|
||||||
|
SourceGroupId string
|
||||||
|
SourceGroupOwnerAccount string
|
||||||
|
SourceGroupOwnerID string
|
||||||
|
SourceCidrIp string // IPv4 only, default 0.0.0.0/0
|
||||||
|
Policy PermissionPolicy // enum of accept (default) | drop
|
||||||
|
Priority int // 1 - 100, default 1
|
||||||
|
NicType NicType // enum of internet | intranet (default)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthorizeSecurityGroupResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizeSecurityGroup authorize permissions to security group
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&authorizesecuritygroup
|
||||||
|
func (client *Client) AuthorizeSecurityGroup(args *AuthorizeSecurityGroupArgs) error {
|
||||||
|
response := AuthorizeSecurityGroupResponse{}
|
||||||
|
err := client.Invoke("AuthorizeSecurityGroup", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type RevokeSecurityGroupArgs struct {
|
||||||
|
AuthorizeSecurityGroupArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
type RevokeSecurityGroupResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/25557.html?spm=5176.doc25554.6.755.O6Tjz0
|
||||||
|
func (client *Client) RevokeSecurityGroup(args *RevokeSecurityGroupArgs) error {
|
||||||
|
response := RevokeSecurityGroupResponse{}
|
||||||
|
err := client.Invoke("RevokeSecurityGroup", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthorizeSecurityGroupEgressArgs struct {
|
||||||
|
SecurityGroupId string
|
||||||
|
RegionId common.Region
|
||||||
|
IpProtocol IpProtocol
|
||||||
|
PortRange string
|
||||||
|
DestGroupId string
|
||||||
|
DestGroupOwnerAccount string
|
||||||
|
DestGroupOwnerId string
|
||||||
|
DestCidrIp string // IPv4 only, default 0.0.0.0/0
|
||||||
|
Policy PermissionPolicy // enum of accept (default) | drop
|
||||||
|
Priority int // 1 - 100, default 1
|
||||||
|
NicType NicType // enum of internet | intranet (default)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthorizeSecurityGroupEgressResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizeSecurityGroup authorize permissions to security group
|
||||||
|
//
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/25560.html
|
||||||
|
func (client *Client) AuthorizeSecurityGroupEgress(args *AuthorizeSecurityGroupEgressArgs) error {
|
||||||
|
response := AuthorizeSecurityGroupEgressResponse{}
|
||||||
|
err := client.Invoke("AuthorizeSecurityGroupEgress", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type RevokeSecurityGroupEgressArgs struct {
|
||||||
|
AuthorizeSecurityGroupEgressArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
type RevokeSecurityGroupEgressResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/25561.html?spm=5176.doc25557.6.759.qcR4Az
|
||||||
|
func (client *Client) RevokeSecurityGroupEgress(args *RevokeSecurityGroupEgressArgs) error {
|
||||||
|
response := RevokeSecurityGroupEgressResponse{}
|
||||||
|
err := client.Invoke("RevokeSecurityGroupEgress", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DescribeSnapshotsArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
InstanceId string
|
||||||
|
DiskId string
|
||||||
|
SnapshotIds []string //["s-xxxxxxxxx", "s-yyyyyyyyy", ..."s-zzzzzzzzz"]
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&snapshottype
|
||||||
|
type SnapshotType struct {
|
||||||
|
SnapshotId string
|
||||||
|
SnapshotName string
|
||||||
|
Description string
|
||||||
|
Progress string
|
||||||
|
SourceDiskId string
|
||||||
|
SourceDiskSize int
|
||||||
|
SourceDiskType string //enum for System | Data
|
||||||
|
ProductCode string
|
||||||
|
CreationTime util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeSnapshotsResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
Snapshots struct {
|
||||||
|
Snapshot []SnapshotType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeSnapshots describe snapshots
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/snapshot&describesnapshots
|
||||||
|
func (client *Client) DescribeSnapshots(args *DescribeSnapshotsArgs) (snapshots []SnapshotType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeSnapshotsResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeSnapshots", args, &response)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return response.Snapshots.Snapshot, &response.PaginationResult, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteSnapshotArgs struct {
|
||||||
|
SnapshotId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteSnapshotResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSnapshot deletes snapshot
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/snapshot&deletesnapshot
|
||||||
|
func (client *Client) DeleteSnapshot(snapshotId string) error {
|
||||||
|
args := DeleteSnapshotArgs{SnapshotId: snapshotId}
|
||||||
|
response := DeleteSnapshotResponse{}
|
||||||
|
|
||||||
|
return client.Invoke("DeleteSnapshot", &args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateSnapshotArgs struct {
|
||||||
|
DiskId string
|
||||||
|
SnapshotName string
|
||||||
|
Description string
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateSnapshotResponse struct {
|
||||||
|
common.Response
|
||||||
|
SnapshotId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSnapshot creates a new snapshot
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/snapshot&createsnapshot
|
||||||
|
func (client *Client) CreateSnapshot(args *CreateSnapshotArgs) (snapshotId string, err error) {
|
||||||
|
|
||||||
|
response := CreateSnapshotResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("CreateSnapshot", args, &response)
|
||||||
|
if err == nil {
|
||||||
|
snapshotId = response.SnapshotId
|
||||||
|
}
|
||||||
|
return snapshotId, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default timeout value for WaitForSnapShotReady method
|
||||||
|
const SnapshotDefaultTimeout = 120
|
||||||
|
|
||||||
|
// WaitForSnapShotReady waits for snapshot ready
|
||||||
|
func (client *Client) WaitForSnapShotReady(regionId common.Region, snapshotId string, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = SnapshotDefaultTimeout
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
args := DescribeSnapshotsArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
SnapshotIds: []string{snapshotId},
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshots, _, err := client.DescribeSnapshots(&args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if snapshots == nil || len(snapshots) == 0 {
|
||||||
|
return common.GetClientErrorFromString("Not found")
|
||||||
|
}
|
||||||
|
if snapshots[0].Progress == "100%" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import "github.com/denverdino/aliyungo/common"
|
||||||
|
|
||||||
|
type TagResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TagResourceImage = TagResourceType("image")
|
||||||
|
TagResourceInstance = TagResourceType("instance")
|
||||||
|
TagResourceSnapshot = TagResourceType("snapshot")
|
||||||
|
TagResourceDisk = TagResourceType("disk")
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddTagsArgs struct {
|
||||||
|
ResourceId string
|
||||||
|
ResourceType TagResourceType //image, instance, snapshot or disk
|
||||||
|
RegionId common.Region
|
||||||
|
Tag map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddTagsResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTags Add tags to resource
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/tags&addtags
|
||||||
|
func (client *Client) AddTags(args *AddTagsArgs) error {
|
||||||
|
response := AddTagsResponse{}
|
||||||
|
err := client.Invoke("AddTags", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveTagsArgs struct {
|
||||||
|
ResourceId string
|
||||||
|
ResourceType TagResourceType //image, instance, snapshot or disk
|
||||||
|
RegionId common.Region
|
||||||
|
Tag map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveTagsResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTags remove tags to resource
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/tags&removetags
|
||||||
|
func (client *Client) RemoveTags(args *RemoveTagsArgs) error {
|
||||||
|
response := RemoveTagsResponse{}
|
||||||
|
err := client.Invoke("RemoveTags", args, &response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResourceItemType struct {
|
||||||
|
ResourceId string
|
||||||
|
ResourceType TagResourceType
|
||||||
|
RegionId common.Region
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeResourceByTagsArgs struct {
|
||||||
|
ResourceType TagResourceType //image, instance, snapshot or disk
|
||||||
|
RegionId common.Region
|
||||||
|
Tag map[string]string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeResourceByTagsResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
Resources struct {
|
||||||
|
Resource []ResourceItemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeResourceByTags describe resource by tags
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/tags&describeresourcebytags
|
||||||
|
func (client *Client) DescribeResourceByTags(args *DescribeResourceByTagsArgs) (resources []ResourceItemType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeResourceByTagsResponse{}
|
||||||
|
err = client.Invoke("DescribeResourceByTags", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return response.Resources.Resource, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TagItemType struct {
|
||||||
|
TagKey string
|
||||||
|
TagValue string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeTagsArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ResourceType TagResourceType //image, instance, snapshot or disk
|
||||||
|
ResourceId string
|
||||||
|
Tag map[string]string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeTagsResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
Tags struct {
|
||||||
|
Tag []TagItemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeResourceByTags describe resource by tags
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/tags&describeresourcebytags
|
||||||
|
func (client *Client) DescribeTags(args *DescribeTagsArgs) (tags []TagItemType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeTagsResponse{}
|
||||||
|
err = client.Invoke("DescribeTags", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return response.Tags.Tag, &response.PaginationResult, nil
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateVpcArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
CidrBlock string //192.168.0.0/16 or 172.16.0.0/16 (default)
|
||||||
|
VpcName string
|
||||||
|
Description string
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateVpcResponse struct {
|
||||||
|
common.Response
|
||||||
|
VpcId string
|
||||||
|
VRouterId string
|
||||||
|
RouteTableId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateVpc creates Virtual Private Cloud
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&createvpc
|
||||||
|
func (client *Client) CreateVpc(args *CreateVpcArgs) (resp *CreateVpcResponse, err error) {
|
||||||
|
response := CreateVpcResponse{}
|
||||||
|
err = client.Invoke("CreateVpc", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteVpcArgs struct {
|
||||||
|
VpcId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteVpcResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteVpc deletes Virtual Private Cloud
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&deletevpc
|
||||||
|
func (client *Client) DeleteVpc(vpcId string) error {
|
||||||
|
args := DeleteVpcArgs{
|
||||||
|
VpcId: vpcId,
|
||||||
|
}
|
||||||
|
response := DeleteVpcResponse{}
|
||||||
|
return client.Invoke("DeleteVpc", &args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type VpcStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
VpcStatusPending = VpcStatus("Pending")
|
||||||
|
VpcStatusAvailable = VpcStatus("Available")
|
||||||
|
)
|
||||||
|
|
||||||
|
type DescribeVpcsArgs struct {
|
||||||
|
VpcId string
|
||||||
|
RegionId common.Region
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vpcsettype
|
||||||
|
type VpcSetType struct {
|
||||||
|
VpcId string
|
||||||
|
RegionId common.Region
|
||||||
|
Status VpcStatus // enum Pending | Available
|
||||||
|
VpcName string
|
||||||
|
VSwitchIds struct {
|
||||||
|
VSwitchId []string
|
||||||
|
}
|
||||||
|
CidrBlock string
|
||||||
|
VRouterId string
|
||||||
|
Description string
|
||||||
|
CreationTime util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeVpcsResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
Vpcs struct {
|
||||||
|
Vpc []VpcSetType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeInstanceStatus describes instance status
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&describevpcs
|
||||||
|
func (client *Client) DescribeVpcs(args *DescribeVpcsArgs) (vpcs []VpcSetType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeVpcsResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeVpcs", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.Vpcs.Vpc, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyVpcAttributeArgs struct {
|
||||||
|
VpcId string
|
||||||
|
VpcName string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyVpcAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyVpcAttribute modifies attribute of Virtual Private Cloud
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&modifyvpcattribute
|
||||||
|
func (client *Client) ModifyVpcAttribute(args *ModifyVpcAttributeArgs) error {
|
||||||
|
response := ModifyVpcAttributeResponse{}
|
||||||
|
return client.Invoke("ModifyVpcAttribute", args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForInstance waits for instance to given status
|
||||||
|
func (client *Client) WaitForVpcAvailable(regionId common.Region, vpcId string, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = DefaultTimeout
|
||||||
|
}
|
||||||
|
args := DescribeVpcsArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
VpcId: vpcId,
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
vpcs, _, err := client.DescribeVpcs(&args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(vpcs) > 0 && vpcs[0].Status == VpcStatusAvailable {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DescribeVRoutersArgs struct {
|
||||||
|
VRouterId string
|
||||||
|
RegionId common.Region
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vroutersettype
|
||||||
|
type VRouterSetType struct {
|
||||||
|
VRouterId string
|
||||||
|
RegionId common.Region
|
||||||
|
VpcId string
|
||||||
|
RouteTableIds struct {
|
||||||
|
RouteTableId []string
|
||||||
|
}
|
||||||
|
VRouterName string
|
||||||
|
Description string
|
||||||
|
CreationTime util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeVRoutersResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
VRouters struct {
|
||||||
|
VRouter []VRouterSetType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeVRouters describes Virtual Routers
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vrouter&describevrouters
|
||||||
|
func (client *Client) DescribeVRouters(args *DescribeVRoutersArgs) (vrouters []VRouterSetType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeVRoutersResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeVRouters", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.VRouters.VRouter, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyVRouterAttributeArgs struct {
|
||||||
|
VRouterId string
|
||||||
|
VRouterName string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyVRouterAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyVRouterAttribute modifies attribute of Virtual Router
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vrouter&modifyvrouterattribute
|
||||||
|
func (client *Client) ModifyVRouterAttribute(args *ModifyVRouterAttributeArgs) error {
|
||||||
|
response := ModifyVRouterAttributeResponse{}
|
||||||
|
return client.Invoke("ModifyVRouterAttribute", args, &response)
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateVSwitchArgs struct {
|
||||||
|
ZoneId string
|
||||||
|
CidrBlock string
|
||||||
|
VpcId string
|
||||||
|
VSwitchName string
|
||||||
|
Description string
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateVSwitchResponse struct {
|
||||||
|
common.Response
|
||||||
|
VSwitchId string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateVSwitch creates Virtual Switch
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vswitch&createvswitch
|
||||||
|
func (client *Client) CreateVSwitch(args *CreateVSwitchArgs) (vswitchId string, err error) {
|
||||||
|
response := CreateVSwitchResponse{}
|
||||||
|
err = client.Invoke("CreateVSwitch", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return response.VSwitchId, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteVSwitchArgs struct {
|
||||||
|
VSwitchId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteVSwitchResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteVSwitch deletes Virtual Switch
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vswitch&deletevswitch
|
||||||
|
func (client *Client) DeleteVSwitch(VSwitchId string) error {
|
||||||
|
args := DeleteVSwitchArgs{
|
||||||
|
VSwitchId: VSwitchId,
|
||||||
|
}
|
||||||
|
response := DeleteVSwitchResponse{}
|
||||||
|
return client.Invoke("DeleteVSwitch", &args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeVSwitchesArgs struct {
|
||||||
|
VpcId string
|
||||||
|
VSwitchId string
|
||||||
|
ZoneId string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
type VSwitchStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
VSwitchStatusPending = VSwitchStatus("Pending")
|
||||||
|
VSwitchStatusAvailable = VSwitchStatus("Available")
|
||||||
|
)
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vswitchsettype
|
||||||
|
type VSwitchSetType struct {
|
||||||
|
VSwitchId string
|
||||||
|
VpcId string
|
||||||
|
Status VSwitchStatus // enum Pending | Available
|
||||||
|
CidrBlock string
|
||||||
|
ZoneId string
|
||||||
|
AvailableIpAddressCount int
|
||||||
|
Description string
|
||||||
|
VSwitchName string
|
||||||
|
CreationTime util.ISO6801Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeVSwitchesResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
VSwitches struct {
|
||||||
|
VSwitch []VSwitchSetType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeVSwitches describes Virtual Switches
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vswitch&describevswitches
|
||||||
|
func (client *Client) DescribeVSwitches(args *DescribeVSwitchesArgs) (vswitches []VSwitchSetType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeVSwitchesResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeVSwitches", args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.VSwitches.VSwitch, &response.PaginationResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyVSwitchAttributeArgs struct {
|
||||||
|
VSwitchId string
|
||||||
|
VSwitchName string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyVSwitchAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyVSwitchAttribute modifies attribute of Virtual Private Cloud
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vswitch&modifyvswitchattribute
|
||||||
|
func (client *Client) ModifyVSwitchAttribute(args *ModifyVSwitchAttributeArgs) error {
|
||||||
|
response := ModifyVSwitchAttributeResponse{}
|
||||||
|
return client.Invoke("ModifyVSwitchAttribute", args, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForVSwitchAvailable waits for VSwitch to given status
|
||||||
|
func (client *Client) WaitForVSwitchAvailable(vpcId string, vswitchId string, timeout int) error {
|
||||||
|
if timeout <= 0 {
|
||||||
|
timeout = DefaultTimeout
|
||||||
|
}
|
||||||
|
args := DescribeVSwitchesArgs{
|
||||||
|
VpcId: vpcId,
|
||||||
|
VSwitchId: vswitchId,
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
vswitches, _, err := client.DescribeVSwitches(&args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(vswitches) == 0 {
|
||||||
|
return common.GetClientErrorFromString("Not found")
|
||||||
|
}
|
||||||
|
if vswitches[0].Status == VSwitchStatusAvailable {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import "github.com/denverdino/aliyungo/common"
|
||||||
|
|
||||||
|
type ResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ResourceTypeInstance = ResourceType("Instance")
|
||||||
|
ResourceTypeDisk = ResourceType("Disk")
|
||||||
|
ResourceTypeVSwitch = ResourceType("VSwitch")
|
||||||
|
ResourceTypeIOOptimizedInstance = ResourceType("IoOptimized")
|
||||||
|
)
|
||||||
|
|
||||||
|
type DescribeZonesArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&availableresourcecreationtype
|
||||||
|
type AvailableResourceCreationType struct {
|
||||||
|
ResourceTypes []ResourceType //enum for Instance, Disk, VSwitch
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&availablediskcategoriestype
|
||||||
|
type AvailableDiskCategoriesType struct {
|
||||||
|
DiskCategories []DiskCategory //enum for cloud, ephemeral, ephemeral_ssd
|
||||||
|
}
|
||||||
|
|
||||||
|
type AvailableInstanceTypesType struct {
|
||||||
|
InstanceTypes []string
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&zonetype
|
||||||
|
type ZoneType struct {
|
||||||
|
ZoneId string
|
||||||
|
LocalName string
|
||||||
|
AvailableInstanceTypes AvailableInstanceTypesType
|
||||||
|
AvailableResourceCreation AvailableResourceCreationType
|
||||||
|
AvailableDiskCategories AvailableDiskCategoriesType
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeZonesResponse struct {
|
||||||
|
common.Response
|
||||||
|
Zones struct {
|
||||||
|
Zone []ZoneType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeZones describes zones
|
||||||
|
func (client *Client) DescribeZones(regionId common.Region) (zones []ZoneType, err error) {
|
||||||
|
args := DescribeZonesArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
}
|
||||||
|
response := DescribeZonesResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeZones", &args, &response)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return response.Zones.Zone, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return []ZoneType{}, err
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package slb
|
||||||
|
|
||||||
|
import "github.com/denverdino/aliyungo/common"
|
||||||
|
|
||||||
|
type UploadServerCertificateArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ServerCertificate string
|
||||||
|
ServerCertificateName string
|
||||||
|
PrivateKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
type UploadServerCertificateResponse struct {
|
||||||
|
common.Response
|
||||||
|
ServerCertificateId string
|
||||||
|
ServerCertificateName string
|
||||||
|
Fingerprint string
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadServerCertificate Upload server certificate
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#pub/slb/api-reference/api-servercertificate&UploadServerCertificate
|
||||||
|
func (client *Client) UploadServerCertificate(args *UploadServerCertificateArgs) (response *UploadServerCertificateResponse, err error) {
|
||||||
|
response = &UploadServerCertificateResponse{}
|
||||||
|
err = client.Invoke("UploadServerCertificate", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteServerCertificateArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ServerCertificateId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteServerCertificateResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteServerCertificate Delete server certificate
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#pub/slb/api-reference/api-servercertificate&DeleteServerCertificate
|
||||||
|
func (client *Client) DeleteServerCertificate(regionId common.Region, serverCertificateId string) (err error) {
|
||||||
|
args := &DeleteServerCertificateArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
ServerCertificateId: serverCertificateId,
|
||||||
|
}
|
||||||
|
response := &DeleteServerCertificateResponse{}
|
||||||
|
return client.Invoke("DeleteServerCertificate", args, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetServerCertificateNameArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ServerCertificateId string
|
||||||
|
ServerCertificateName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetServerCertificateNameResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetServerCertificateName Set name of server certificate
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#pub/slb/api-reference/api-servercertificate&SetServerCertificateName
|
||||||
|
func (client *Client) SetServerCertificateName(regionId common.Region, serverCertificateId string, name string) (err error) {
|
||||||
|
args := &SetServerCertificateNameArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
ServerCertificateId: serverCertificateId,
|
||||||
|
ServerCertificateName: name,
|
||||||
|
}
|
||||||
|
response := &SetServerCertificateNameResponse{}
|
||||||
|
return client.Invoke("SetServerCertificateName", args, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeServerCertificatesArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ServerCertificateId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServerCertificateType struct {
|
||||||
|
RegionId common.Region
|
||||||
|
ServerCertificateId string
|
||||||
|
ServerCertificateName string
|
||||||
|
Fingerprint string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeServerCertificatesResponse struct {
|
||||||
|
common.Response
|
||||||
|
ServerCertificates struct {
|
||||||
|
ServerCertificate []ServerCertificateType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeServerCertificates Describe server certificates
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#pub/slb/api-reference/api-servercertificate&DescribeServerCertificates
|
||||||
|
func (client *Client) DescribeServerCertificatesArgs(regionId common.Region, serverCertificateId string) (serverCertificates []ServerCertificateType, err error) {
|
||||||
|
args := &DescribeServerCertificatesArgs{
|
||||||
|
RegionId: regionId,
|
||||||
|
ServerCertificateId: serverCertificateId,
|
||||||
|
}
|
||||||
|
response := &DescribeServerCertificatesResponse{}
|
||||||
|
err = client.Invoke("DescribeServerCertificates", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response.ServerCertificates.ServerCertificate, err
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package slb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
common.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SLBDefaultEndpoint is the default API endpoint of SLB services
|
||||||
|
SLBDefaultEndpoint = "https://slb.aliyuncs.com"
|
||||||
|
SLBAPIVersion = "2014-05-15"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewClient creates a new instance of ECS client
|
||||||
|
func NewClient(accessKeyId, accessKeySecret string) *Client {
|
||||||
|
endpoint := os.Getenv("SLB_ENDPOINT")
|
||||||
|
if endpoint == "" {
|
||||||
|
endpoint = SLBDefaultEndpoint
|
||||||
|
}
|
||||||
|
return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client {
|
||||||
|
client := &Client{}
|
||||||
|
client.Init(endpoint, SLBAPIVersion, accessKeyId, accessKeySecret)
|
||||||
|
return client
|
||||||
|
}
|
|
@ -0,0 +1,495 @@
|
||||||
|
package slb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ListenerStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Starting = ListenerStatus("starting")
|
||||||
|
Running = ListenerStatus("running")
|
||||||
|
Configuring = ListenerStatus("configuring")
|
||||||
|
Stopping = ListenerStatus("stopping")
|
||||||
|
Stopped = ListenerStatus("stopped")
|
||||||
|
)
|
||||||
|
|
||||||
|
type SchedulerType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
WRRScheduler = SchedulerType("wrr")
|
||||||
|
WLCScheduler = SchedulerType("wlc")
|
||||||
|
)
|
||||||
|
|
||||||
|
type FlagType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
OnFlag = FlagType("on")
|
||||||
|
OffFlag = FlagType("off")
|
||||||
|
)
|
||||||
|
|
||||||
|
type StickySessionType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
InsertStickySessionType = StickySessionType("insert")
|
||||||
|
ServerStickySessionType = StickySessionType("server")
|
||||||
|
)
|
||||||
|
|
||||||
|
const BackendServerPort = -520
|
||||||
|
|
||||||
|
type HealthCheckHttpCodeType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
HTTP_2XX = HealthCheckHttpCodeType("http_2xx")
|
||||||
|
HTTP_3XX = HealthCheckHttpCodeType("http_3xx")
|
||||||
|
HTTP_4XX = HealthCheckHttpCodeType("http_4xx")
|
||||||
|
HTTP_5XX = HealthCheckHttpCodeType("http_5xx")
|
||||||
|
)
|
||||||
|
|
||||||
|
func EncodeHealthCheckHttpCodeType(healthCheckHttpCodes []HealthCheckHttpCodeType) (HealthCheckHttpCodeType, error) {
|
||||||
|
code := ""
|
||||||
|
|
||||||
|
if nil == healthCheckHttpCodes || len(healthCheckHttpCodes) < 1 {
|
||||||
|
return "", fmt.Errorf("Invalid size of healthCheckHttpCodes")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, healthCheckHttpCode := range healthCheckHttpCodes {
|
||||||
|
if strings.EqualFold(string(HTTP_2XX), string(healthCheckHttpCode)) ||
|
||||||
|
strings.EqualFold(string(HTTP_3XX), string(healthCheckHttpCode)) ||
|
||||||
|
strings.EqualFold(string(HTTP_4XX), string(healthCheckHttpCode)) ||
|
||||||
|
strings.EqualFold(string(HTTP_5XX), string(healthCheckHttpCode)) {
|
||||||
|
if "" == code {
|
||||||
|
code = string(healthCheckHttpCode)
|
||||||
|
} else {
|
||||||
|
if strings.Contains(code, string(healthCheckHttpCode)) {
|
||||||
|
return "", fmt.Errorf("Duplicates healthCheckHttpCode(%v in %v)", healthCheckHttpCode, healthCheckHttpCodes)
|
||||||
|
}
|
||||||
|
code += code + "," + string(healthCheckHttpCode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("Invalid healthCheckHttpCode(%v in %v)", healthCheckHttpCode, healthCheckHttpCodes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return HealthCheckHttpCodeType(code), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommonLoadBalancerListenerResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPListenerType struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
ListenerPort int
|
||||||
|
BackendServerPort int
|
||||||
|
Bandwidth int
|
||||||
|
Scheduler SchedulerType
|
||||||
|
StickySession FlagType
|
||||||
|
StickySessionType StickySessionType
|
||||||
|
CookieTimeout int
|
||||||
|
Cookie string
|
||||||
|
HealthCheck FlagType
|
||||||
|
HealthCheckDomain string
|
||||||
|
HealthCheckURI string
|
||||||
|
HealthCheckConnectPort int
|
||||||
|
HealthyThreshold int
|
||||||
|
UnhealthyThreshold int
|
||||||
|
HealthCheckTimeout int
|
||||||
|
HealthCheckInterval int
|
||||||
|
HealthCheckHttpCode HealthCheckHttpCodeType
|
||||||
|
VServerGroupId string
|
||||||
|
Gzip FlagType
|
||||||
|
}
|
||||||
|
type CreateLoadBalancerHTTPListenerArgs HTTPListenerType
|
||||||
|
|
||||||
|
// CreateLoadBalancerHTTPListener create HTTP listener on loadbalancer
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&CreateLoadBalancerHTTPListener
|
||||||
|
func (client *Client) CreateLoadBalancerHTTPListener(args *CreateLoadBalancerHTTPListenerArgs) (err error) {
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("CreateLoadBalancerHTTPListener", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPSListenerType struct {
|
||||||
|
HTTPListenerType
|
||||||
|
ServerCertificateId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateLoadBalancerHTTPSListenerArgs HTTPSListenerType
|
||||||
|
|
||||||
|
// CreateLoadBalancerHTTPSListener create HTTPS listener on loadbalancer
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&CreateLoadBalancerHTTPSListener
|
||||||
|
func (client *Client) CreateLoadBalancerHTTPSListener(args *CreateLoadBalancerHTTPSListenerArgs) (err error) {
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("CreateLoadBalancerHTTPSListener", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type HealthCheckType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TCPHealthCheckType = HealthCheckType("tcp")
|
||||||
|
HTTPHealthCheckType = HealthCheckType("http")
|
||||||
|
)
|
||||||
|
|
||||||
|
type TCPListenerType struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
ListenerPort int
|
||||||
|
BackendServerPort int
|
||||||
|
Bandwidth int
|
||||||
|
Scheduler SchedulerType
|
||||||
|
PersistenceTimeout int
|
||||||
|
HealthCheckType HealthCheckType
|
||||||
|
HealthCheckDomain string
|
||||||
|
HealthCheckURI string
|
||||||
|
HealthCheckConnectPort int
|
||||||
|
HealthyThreshold int
|
||||||
|
UnhealthyThreshold int
|
||||||
|
HealthCheckTimeout int
|
||||||
|
HealthCheckInterval int
|
||||||
|
HealthCheckHttpCode HealthCheckHttpCodeType
|
||||||
|
VServerGroupId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateLoadBalancerTCPListenerArgs TCPListenerType
|
||||||
|
|
||||||
|
// CreateLoadBalancerTCPListener create TCP listener on loadbalancer
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&CreateLoadBalancerTCPListener
|
||||||
|
func (client *Client) CreateLoadBalancerTCPListener(args *CreateLoadBalancerTCPListenerArgs) (err error) {
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("CreateLoadBalancerTCPListener", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type UDPListenerType struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
ListenerPort int
|
||||||
|
BackendServerPort int
|
||||||
|
Bandwidth int
|
||||||
|
Scheduler SchedulerType
|
||||||
|
PersistenceTimeout int
|
||||||
|
HealthCheckConnectPort int
|
||||||
|
HealthyThreshold int
|
||||||
|
UnhealthyThreshold int
|
||||||
|
HealthCheckTimeout int
|
||||||
|
HealthCheckInterval int
|
||||||
|
VServerGroupId string
|
||||||
|
}
|
||||||
|
type CreateLoadBalancerUDPListenerArgs UDPListenerType
|
||||||
|
|
||||||
|
// CreateLoadBalancerUDPListener create UDP listener on loadbalancer
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&CreateLoadBalancerUDPListener
|
||||||
|
func (client *Client) CreateLoadBalancerUDPListener(args *CreateLoadBalancerUDPListenerArgs) (err error) {
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("CreateLoadBalancerUDPListener", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommonLoadBalancerListenerArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
ListenerPort int
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteLoadBalancerListener Delete listener
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&DeleteLoadBalancerListener
|
||||||
|
func (client *Client) DeleteLoadBalancerListener(loadBalancerId string, port int) (err error) {
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("DeleteLoadBalancerListener", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartLoadBalancerListener Start listener
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&StartLoadBalancerListener
|
||||||
|
func (client *Client) StartLoadBalancerListener(loadBalancerId string, port int) (err error) {
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("StartLoadBalancerListener", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopLoadBalancerListener Stop listener
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&StopLoadBalancerListener
|
||||||
|
func (client *Client) StopLoadBalancerListener(loadBalancerId string, port int) (err error) {
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("StopLoadBalancerListener", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccessControlStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
OpenWhileList = AccessControlStatus("open_white_list")
|
||||||
|
Close = AccessControlStatus("close")
|
||||||
|
)
|
||||||
|
|
||||||
|
type SetListenerAccessControlStatusArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
ListenerPort int
|
||||||
|
AccessControlStatus AccessControlStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetListenerAccessControlStatus Set listener access control status
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&SetListenerAccessControlStatus
|
||||||
|
func (client *Client) SetListenerAccessControlStatus(loadBalancerId string, port int, status AccessControlStatus) (err error) {
|
||||||
|
args := &SetListenerAccessControlStatusArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
AccessControlStatus: status,
|
||||||
|
}
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("SetListenerAccessControlStatus", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommonListenerWhiteListItemArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
ListenerPort int
|
||||||
|
SourceItems string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddListenerWhiteListItem Add listener white-list item
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&AddListenerWhiteListItem
|
||||||
|
func (client *Client) AddListenerWhiteListItem(loadBalancerId string, port int, sourceItems string) (err error) {
|
||||||
|
args := &CommonListenerWhiteListItemArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
SourceItems: sourceItems,
|
||||||
|
}
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("AddListenerWhiteListItem", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveListenerWhiteListItem Remove listener white-list item
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&RemoveListenerWhiteListItem
|
||||||
|
func (client *Client) RemoveListenerWhiteListItem(loadBalancerId string, port int, sourceItems string) (err error) {
|
||||||
|
args := &CommonListenerWhiteListItemArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
SourceItems: sourceItems,
|
||||||
|
}
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("RemoveListenerWhiteListItem", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetLoadBalancerHTTPListenerAttributeArgs CreateLoadBalancerHTTPListenerArgs
|
||||||
|
|
||||||
|
// SetLoadBalancerHTTPListenerAttribute Set HTTP listener attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&SetLoadBalancerHTTPListenerAttribute
|
||||||
|
func (client *Client) SetLoadBalancerHTTPListenerAttribute(args *SetLoadBalancerHTTPListenerAttributeArgs) (err error) {
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("SetLoadBalancerHTTPListenerAttribute", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetLoadBalancerHTTPSListenerAttributeArgs CreateLoadBalancerHTTPSListenerArgs
|
||||||
|
|
||||||
|
// SetLoadBalancerHTTPSListenerAttribute Set HTTPS listener attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&SetLoadBalancerHTTPSListenerAttribute
|
||||||
|
func (client *Client) SetLoadBalancerHTTPSListenerAttribute(args *SetLoadBalancerHTTPSListenerAttributeArgs) (err error) {
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("SetLoadBalancerHTTPSListenerAttribute", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetLoadBalancerTCPListenerAttributeArgs CreateLoadBalancerTCPListenerArgs
|
||||||
|
|
||||||
|
// SetLoadBalancerTCPListenerAttribute Set TCP listener attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&SetLoadBalancerTCPListenerAttribute
|
||||||
|
func (client *Client) SetLoadBalancerTCPListenerAttribute(args *SetLoadBalancerTCPListenerAttributeArgs) (err error) {
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("SetLoadBalancerTCPListenerAttribute", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetLoadBalancerUDPListenerAttributeArgs CreateLoadBalancerUDPListenerArgs
|
||||||
|
|
||||||
|
// SetLoadBalancerUDPListenerAttribute Set UDP listener attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&SetLoadBalancerUDPListenerAttribute
|
||||||
|
func (client *Client) SetLoadBalancerUDPListenerAttribute(args *SetLoadBalancerUDPListenerAttributeArgs) (err error) {
|
||||||
|
response := &CommonLoadBalancerListenerResponse{}
|
||||||
|
err = client.Invoke("SetLoadBalancerUDPListenerAttribute", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancerListenerAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
Status ListenerStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancerHTTPListenerAttributeResponse struct {
|
||||||
|
DescribeLoadBalancerListenerAttributeResponse
|
||||||
|
HTTPListenerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeLoadBalancerHTTPListenerAttribute Describe HTTP listener attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&DescribeLoadBalancerHTTPListenerAttribute
|
||||||
|
func (client *Client) DescribeLoadBalancerHTTPListenerAttribute(loadBalancerId string, port int) (response *DescribeLoadBalancerHTTPListenerAttributeResponse, err error) {
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
response = &DescribeLoadBalancerHTTPListenerAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeLoadBalancerHTTPListenerAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancerHTTPSListenerAttributeResponse struct {
|
||||||
|
DescribeLoadBalancerListenerAttributeResponse
|
||||||
|
HTTPSListenerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeLoadBalancerHTTPSListenerAttribute Describe HTTPS listener attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&DescribeLoadBalancerHTTPSListenerAttribute
|
||||||
|
func (client *Client) DescribeLoadBalancerHTTPSListenerAttribute(loadBalancerId string, port int) (response *DescribeLoadBalancerHTTPSListenerAttributeResponse, err error) {
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
response = &DescribeLoadBalancerHTTPSListenerAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeLoadBalancerHTTPSListenerAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancerTCPListenerAttributeResponse struct {
|
||||||
|
DescribeLoadBalancerListenerAttributeResponse
|
||||||
|
TCPListenerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeLoadBalancerTCPListenerAttribute Describe TCP listener attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&DescribeLoadBalancerTCPListenerAttribute
|
||||||
|
func (client *Client) DescribeLoadBalancerTCPListenerAttribute(loadBalancerId string, port int) (response *DescribeLoadBalancerTCPListenerAttributeResponse, err error) {
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
response = &DescribeLoadBalancerTCPListenerAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeLoadBalancerTCPListenerAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancerUDPListenerAttributeResponse struct {
|
||||||
|
DescribeLoadBalancerListenerAttributeResponse
|
||||||
|
UDPListenerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeLoadBalancerUDPListenerAttribute Describe UDP listener attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&DescribeLoadBalancerUDPListenerAttribute
|
||||||
|
func (client *Client) DescribeLoadBalancerUDPListenerAttribute(loadBalancerId string, port int) (response *DescribeLoadBalancerUDPListenerAttributeResponse, err error) {
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
response = &DescribeLoadBalancerUDPListenerAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeLoadBalancerUDPListenerAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListenerType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
UDP = ListenerType("UDP")
|
||||||
|
TCP = ListenerType("TCP")
|
||||||
|
HTTP = ListenerType("HTTP")
|
||||||
|
HTTPS = ListenerType("HTTPS")
|
||||||
|
)
|
||||||
|
|
||||||
|
const DefaultWaitForInterval = 5 //5 seconds
|
||||||
|
const DefaultTimeout = 60 //60 seconds
|
||||||
|
|
||||||
|
// WaitForListener waits for listener to given status
|
||||||
|
func (client *Client) WaitForListener(loadBalancerId string, port int, listenerType ListenerType) (status ListenerStatus, err error) {
|
||||||
|
timeout := DefaultTimeout
|
||||||
|
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
|
||||||
|
method := fmt.Sprintf("DescribeLoadBalancer%sListenerAttribute", listenerType)
|
||||||
|
response := &DescribeLoadBalancerListenerAttributeResponse{}
|
||||||
|
|
||||||
|
for {
|
||||||
|
timeout = timeout - DefaultWaitForInterval
|
||||||
|
if timeout <= 0 {
|
||||||
|
return response.Status, common.GetClientErrorFromString("Timeout")
|
||||||
|
}
|
||||||
|
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||||
|
//Sleep first to ensure the previous request is sent
|
||||||
|
err = client.Invoke(method, args, response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if response.Status == Running || response.Status == Stopped {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.Status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeListenerAccessControlAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
AccessControlStatus AccessControlStatus
|
||||||
|
SourceItems string
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeListenerAccessControlAttribute Describe listener access control attribute
|
||||||
|
//
|
||||||
|
// You can read doc at https://docs.aliyun.com/#/pub/slb/api-reference/api-related-listener&DescribeListenerAccessControlAttribute
|
||||||
|
func (client *Client) DescribeListenerAccessControlAttribute(loadBalancerId string, port int) (response *DescribeListenerAccessControlAttributeResponse, err error) {
|
||||||
|
args := &CommonLoadBalancerListenerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
ListenerPort: port,
|
||||||
|
}
|
||||||
|
response = &DescribeListenerAccessControlAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeListenerAccessControlAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
|
@ -0,0 +1,238 @@
|
||||||
|
package slb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
"github.com/denverdino/aliyungo/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddressType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
InternetAddressType = AddressType("internet")
|
||||||
|
IntranetAddressType = AddressType("intranet")
|
||||||
|
)
|
||||||
|
|
||||||
|
type InternetChargeType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
PayByBandwidth = InternetChargeType("paybybandwidth")
|
||||||
|
PayByTraffic = InternetChargeType("paybytraffic")
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateLoadBalancerArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
LoadBalancerName string
|
||||||
|
AddressType AddressType
|
||||||
|
VSwitchId string
|
||||||
|
InternetChargeType InternetChargeType
|
||||||
|
Bandwidth int
|
||||||
|
ClientToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateLoadBalancerResponse struct {
|
||||||
|
common.Response
|
||||||
|
LoadBalancerId string
|
||||||
|
Address string
|
||||||
|
NetworkType string
|
||||||
|
VpcId string
|
||||||
|
VSwitchId string
|
||||||
|
LoadBalancerName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateLoadBalancer create loadbalancer
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&CreateLoadBalancer
|
||||||
|
func (client *Client) CreateLoadBalancer(args *CreateLoadBalancerArgs) (response *CreateLoadBalancerResponse, err error) {
|
||||||
|
response = &CreateLoadBalancerResponse{}
|
||||||
|
err = client.Invoke("CreateLoadBalancer", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteLoadBalancerArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteLoadBalancerResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteLoadBalancer delete loadbalancer
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&DeleteLoadBalancer
|
||||||
|
func (client *Client) DeleteLoadBalancer(loadBalancerId string) (err error) {
|
||||||
|
args := &DeleteLoadBalancerArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
}
|
||||||
|
response := &DeleteLoadBalancerResponse{}
|
||||||
|
err = client.Invoke("DeleteLoadBalancer", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyLoadBalancerInternetSpecArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
InternetChargeType InternetChargeType
|
||||||
|
Bandwidth int
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModifyLoadBalancerInternetSpecResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyLoadBalancerInternetSpec Modify loadbalancer internet spec
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&ModifyLoadBalancerInternetSpec
|
||||||
|
|
||||||
|
func (client *Client) ModifyLoadBalancerInternetSpec(args *ModifyLoadBalancerInternetSpecArgs) (err error) {
|
||||||
|
response := &ModifyLoadBalancerInternetSpecResponse{}
|
||||||
|
err = client.Invoke("ModifyLoadBalancerInternetSpec", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type Status string
|
||||||
|
|
||||||
|
const InactiveStatus = Status("inactive")
|
||||||
|
const ActiveStatus = Status("active")
|
||||||
|
const LockedStatus = Status("locked")
|
||||||
|
|
||||||
|
type SetLoadBalancerStatusArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
LoadBalancerStatus Status
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetLoadBalancerStatusResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLoadBalancerStatus Set loadbalancer status
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&SetLoadBalancerStatus
|
||||||
|
|
||||||
|
func (client *Client) SetLoadBalancerStatus(loadBalancerId string, status Status) (err error) {
|
||||||
|
args := &SetLoadBalancerStatusArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
LoadBalancerStatus: status,
|
||||||
|
}
|
||||||
|
response := &SetLoadBalancerStatusResponse{}
|
||||||
|
err = client.Invoke("SetLoadBalancerStatus", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetLoadBalancerNameArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
LoadBalancerName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetLoadBalancerNameResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLoadBalancerName Set loadbalancer name
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&SetLoadBalancerName
|
||||||
|
|
||||||
|
func (client *Client) SetLoadBalancerName(loadBalancerId string, name string) (err error) {
|
||||||
|
args := &SetLoadBalancerNameArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
LoadBalancerName: name,
|
||||||
|
}
|
||||||
|
response := &SetLoadBalancerNameResponse{}
|
||||||
|
err = client.Invoke("SetLoadBalancerName", args, response)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancersArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
LoadBalancerId string
|
||||||
|
LoadBalancerName string
|
||||||
|
AddressType AddressType
|
||||||
|
NetworkType string
|
||||||
|
VpcId string
|
||||||
|
VSwitchId string
|
||||||
|
Address string
|
||||||
|
InternetChargeType InternetChargeType
|
||||||
|
ServerId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListenerPortAndProtocolType struct {
|
||||||
|
ListenerPort int
|
||||||
|
ListenerProtocol string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BackendServerType struct {
|
||||||
|
ServerId string
|
||||||
|
Weight int
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoadBalancerType struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
LoadBalancerName string
|
||||||
|
LoadBalancerStatus string
|
||||||
|
Address string
|
||||||
|
RegionId common.Region
|
||||||
|
RegionIdAlias string
|
||||||
|
AddressType AddressType
|
||||||
|
VSwitchId string
|
||||||
|
VpcId string
|
||||||
|
NetworkType string
|
||||||
|
Bandwidth int
|
||||||
|
InternetChargeType InternetChargeType
|
||||||
|
CreateTime string //Why not ISO 6801
|
||||||
|
CreateTimeStamp util.ISO6801Time
|
||||||
|
ListenerPorts struct {
|
||||||
|
ListenerPort []int
|
||||||
|
}
|
||||||
|
ListenerPortsAndProtocol struct {
|
||||||
|
ListenerPortAndProtocol []ListenerPortAndProtocolType
|
||||||
|
}
|
||||||
|
BackendServers struct {
|
||||||
|
BackendServer []BackendServerType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancersResponse struct {
|
||||||
|
common.Response
|
||||||
|
LoadBalancers struct {
|
||||||
|
LoadBalancer []LoadBalancerType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeLoadBalancers Describe loadbalancers
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&DescribeLoadBalancers
|
||||||
|
|
||||||
|
func (client *Client) DescribeLoadBalancers(args *DescribeLoadBalancersArgs) (loadBalancers []LoadBalancerType, err error) {
|
||||||
|
response := &DescribeLoadBalancersResponse{}
|
||||||
|
err = client.Invoke("DescribeLoadBalancers", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response.LoadBalancers.LoadBalancer, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancerAttributeArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeLoadBalancerAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
LoadBalancerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeLoadBalancerAttribute Describe loadbalancer attribute
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&DescribeLoadBalancerAttribute
|
||||||
|
|
||||||
|
func (client *Client) DescribeLoadBalancerAttribute(loadBalancerId string) (loadBalancer *LoadBalancerType, err error) {
|
||||||
|
args := &DescribeLoadBalancersArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
}
|
||||||
|
response := &DescribeLoadBalancerAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeLoadBalancerAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &response.LoadBalancerType, err
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package slb
|
||||||
|
|
||||||
|
import "github.com/denverdino/aliyungo/common"
|
||||||
|
|
||||||
|
type DescribeRegionsArgs struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype®iontype
|
||||||
|
type RegionType struct {
|
||||||
|
RegionId common.Region
|
||||||
|
LocalName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeRegionsResponse struct {
|
||||||
|
common.Response
|
||||||
|
Regions struct {
|
||||||
|
Region []RegionType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeRegions describes regions
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&DescribeRegions
|
||||||
|
func (client *Client) DescribeRegions() (regions []RegionType, err error) {
|
||||||
|
response := DescribeRegionsResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("DescribeRegions", &DescribeRegionsArgs{}, &response)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []RegionType{}, err
|
||||||
|
}
|
||||||
|
return response.Regions.Region, nil
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package slb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddBackendServersArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
BackendServers string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetBackendServersArgs AddBackendServersArgs
|
||||||
|
|
||||||
|
type AddBackendServersResponse struct {
|
||||||
|
common.Response
|
||||||
|
LoadBalancerId string
|
||||||
|
BackendServers struct {
|
||||||
|
BackendServer []BackendServerType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetBackendServersResponse AddBackendServersResponse
|
||||||
|
|
||||||
|
|
||||||
|
// SetBackendServers set weight of backend servers
|
||||||
|
|
||||||
|
func (client *Client) SetBackendServers(loadBalancerId string, backendServers []BackendServerType) (result []BackendServerType, err error) {
|
||||||
|
bytes, _ := json.Marshal(backendServers)
|
||||||
|
|
||||||
|
args := &SetBackendServersArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
BackendServers: string(bytes),
|
||||||
|
}
|
||||||
|
response := &SetBackendServersResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("SetBackendServers", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response.BackendServers.BackendServer, err
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// AddBackendServers Add backend servers
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-backendserver&AddBackendServers
|
||||||
|
func (client *Client) AddBackendServers(loadBalancerId string, backendServers []BackendServerType) (result []BackendServerType, err error) {
|
||||||
|
|
||||||
|
bytes, _ := json.Marshal(backendServers)
|
||||||
|
|
||||||
|
args := &AddBackendServersArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
BackendServers: string(bytes),
|
||||||
|
}
|
||||||
|
response := &AddBackendServersResponse{}
|
||||||
|
|
||||||
|
err = client.Invoke("AddBackendServers", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response.BackendServers.BackendServer, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveBackendServersArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
BackendServers []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveBackendServersResponse struct {
|
||||||
|
common.Response
|
||||||
|
LoadBalancerId string
|
||||||
|
BackendServers struct {
|
||||||
|
BackendServer []BackendServerType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveBackendServers Remove backend servers
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-backendserver&RemoveBackendServers
|
||||||
|
func (client *Client) RemoveBackendServers(loadBalancerId string, backendServers []string) (result []BackendServerType, err error) {
|
||||||
|
args := &RemoveBackendServersArgs{
|
||||||
|
LoadBalancerId: loadBalancerId,
|
||||||
|
BackendServers: backendServers,
|
||||||
|
}
|
||||||
|
response := &RemoveBackendServersResponse{}
|
||||||
|
err = client.Invoke("RemoveBackendServers", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response.BackendServers.BackendServer, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type HealthStatusType struct {
|
||||||
|
ServerId string
|
||||||
|
ServerHealthStatus string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeHealthStatusArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
ListenerPort int
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeHealthStatusResponse struct {
|
||||||
|
common.Response
|
||||||
|
BackendServers struct {
|
||||||
|
BackendServer []HealthStatusType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeHealthStatus Describe health status
|
||||||
|
//
|
||||||
|
// You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-backendserver&DescribeHealthStatus
|
||||||
|
func (client *Client) DescribeHealthStatus(args *DescribeHealthStatusArgs) (response *DescribeHealthStatusResponse, err error) {
|
||||||
|
response = &DescribeHealthStatusResponse{}
|
||||||
|
err = client.Invoke("DescribeHealthStatus", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package slb
|
||||||
|
|
||||||
|
import "github.com/denverdino/aliyungo/common"
|
||||||
|
|
||||||
|
type TagItem struct {
|
||||||
|
TagKey string
|
||||||
|
TagValue string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddTagsArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
LoadBalancerID string
|
||||||
|
Tags string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddTagsResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTags Add tags to resource
|
||||||
|
//
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/42871.html
|
||||||
|
func (client *Client) AddTags(args *AddTagsArgs) error {
|
||||||
|
response := AddTagsResponse{}
|
||||||
|
err := client.Invoke("AddTags", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveTagsArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
LoadBalancerID string
|
||||||
|
Tags string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveTagsResponse struct {
|
||||||
|
common.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTags remove tags to resource
|
||||||
|
//
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/42872.html
|
||||||
|
func (client *Client) RemoveTags(args *RemoveTagsArgs) error {
|
||||||
|
response := RemoveTagsResponse{}
|
||||||
|
err := client.Invoke("RemoveTags", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type TagItemType struct {
|
||||||
|
TagItem
|
||||||
|
InstanceCount int
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeTagsArgs struct {
|
||||||
|
RegionId common.Region
|
||||||
|
LoadBalancerID string
|
||||||
|
Tags string
|
||||||
|
common.Pagination
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeTagsResponse struct {
|
||||||
|
common.Response
|
||||||
|
common.PaginationResult
|
||||||
|
TagSets struct {
|
||||||
|
TagSet []TagItemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeResourceByTags describe resource by tags
|
||||||
|
//
|
||||||
|
// You can read doc at https://help.aliyun.com/document_detail/42873.html?spm=5176.doc42872.6.267.CP1iWu
|
||||||
|
func (client *Client) DescribeTags(args *DescribeTagsArgs) (tags []TagItemType, pagination *common.PaginationResult, err error) {
|
||||||
|
args.Validate()
|
||||||
|
response := DescribeTagsResponse{}
|
||||||
|
err = client.Invoke("DescribeTags", args, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return response.TagSets.TagSet, &response.PaginationResult, nil
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
package slb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/denverdino/aliyungo/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VBackendServerType struct {
|
||||||
|
ServerId string
|
||||||
|
Weight int
|
||||||
|
Port int
|
||||||
|
}
|
||||||
|
|
||||||
|
type VServerGroup struct {
|
||||||
|
VServerGroupName string
|
||||||
|
VServerGroupId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type VBackendServers struct {
|
||||||
|
BackendServer []VBackendServerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateVServerGroupArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
RegionId common.Region
|
||||||
|
VServerGroupName string
|
||||||
|
VServerGroupId string
|
||||||
|
BackendServers string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetVServerGroupAttributeArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
RegionId common.Region
|
||||||
|
VServerGroupName string
|
||||||
|
VServerGroupId string
|
||||||
|
BackendServers string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddVServerGroupBackendServersArgs CreateVServerGroupArgs
|
||||||
|
type RemoveVServerGroupBackendServersArgs CreateVServerGroupArgs
|
||||||
|
type ModifyVServerGroupBackendServersArgs struct {
|
||||||
|
VServerGroupId string
|
||||||
|
RegionId common.Region
|
||||||
|
OldBackendServers string
|
||||||
|
NewBackendServers string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteVServerGroupArgs struct {
|
||||||
|
VServerGroupId string
|
||||||
|
RegionId common.Region
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeVServerGroupsArgs struct {
|
||||||
|
LoadBalancerId string
|
||||||
|
RegionId common.Region
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeVServerGroupAttributeArgs struct {
|
||||||
|
VServerGroupId string
|
||||||
|
RegionId common.Region
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateVServerGroupResponse struct {
|
||||||
|
common.Response
|
||||||
|
VServerGroupId string
|
||||||
|
VServerGroupName string
|
||||||
|
BackendServers VBackendServers
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetVServerGroupAttributeResponse struct {
|
||||||
|
common.Response
|
||||||
|
VServerGroupId string
|
||||||
|
VServerGroupName string
|
||||||
|
BackendServers VBackendServers
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddVServerGroupBackendServersResponse CreateVServerGroupResponse
|
||||||
|
type RemoveVServerGroupBackendServersResponse CreateVServerGroupResponse
|
||||||
|
type ModifyVServerGroupBackendServersResponse CreateVServerGroupResponse
|
||||||
|
type DeleteVServerGroupResponse struct{ common.Response }
|
||||||
|
type DescribeVServerGroupsResponse struct {
|
||||||
|
common.Response
|
||||||
|
VServerGroups struct {
|
||||||
|
VServerGroup []VServerGroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type DescribeVServerGroupAttributeResponse CreateVServerGroupResponse
|
||||||
|
|
||||||
|
|
||||||
|
func (client *Client) CreateVServerGroup(args *CreateVServerGroupArgs) (response *CreateVServerGroupResponse, err error) {
|
||||||
|
response = &CreateVServerGroupResponse{}
|
||||||
|
err = client.Invoke("CreateVServerGroup", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetVServerGroupAttribute(args *SetVServerGroupAttributeArgs) (response *SetVServerGroupAttributeResponse, err error) {
|
||||||
|
response = &SetVServerGroupAttributeResponse{}
|
||||||
|
err = client.Invoke("SetVServerGroupAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) AddVServerGroupBackendServers(args *AddVServerGroupBackendServersArgs) (response *AddVServerGroupBackendServersResponse, err error) {
|
||||||
|
response = &AddVServerGroupBackendServersResponse{}
|
||||||
|
err = client.Invoke("AddVServerGroupBackendServers", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) RemoveVServerGroupBackendServers(args *RemoveVServerGroupBackendServersArgs) (response *RemoveVServerGroupBackendServersResponse, err error) {
|
||||||
|
response = &RemoveVServerGroupBackendServersResponse{}
|
||||||
|
err = client.Invoke("RemoveVServerGroupBackendServers", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) ModifyVServerGroupBackendServers(args *ModifyVServerGroupBackendServersArgs) (response *ModifyVServerGroupBackendServersResponse, err error) {
|
||||||
|
response = &ModifyVServerGroupBackendServersResponse{}
|
||||||
|
err = client.Invoke("ModifyVServerGroupBackendServers", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) DeleteVServerGroup(args *DeleteVServerGroupArgs) (response *DeleteVServerGroupResponse, err error) {
|
||||||
|
response = &DeleteVServerGroupResponse{}
|
||||||
|
err = client.Invoke("DeleteVServerGroup", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) DescribeVServerGroups(args *DescribeVServerGroupsArgs) (response *DescribeVServerGroupsResponse, err error) {
|
||||||
|
response = &DescribeVServerGroupsResponse{}
|
||||||
|
err = client.Invoke("DescribeVServerGroups", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) DescribeVServerGroupAttribute(args *DescribeVServerGroupAttributeArgs) (response *DescribeVServerGroupAttributeResponse, err error) {
|
||||||
|
response = &DescribeVServerGroupAttributeResponse{}
|
||||||
|
err = client.Invoke("DescribeVServerGroupAttribute", args, response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AttemptStrategy is reused from the goamz package
|
||||||
|
|
||||||
|
// AttemptStrategy represents a strategy for waiting for an action
|
||||||
|
// to complete successfully. This is an internal type used by the
|
||||||
|
// implementation of other packages.
|
||||||
|
type AttemptStrategy struct {
|
||||||
|
Total time.Duration // total duration of attempt.
|
||||||
|
Delay time.Duration // interval between each try in the burst.
|
||||||
|
Min int // minimum number of retries; overrides Total
|
||||||
|
}
|
||||||
|
|
||||||
|
type Attempt struct {
|
||||||
|
strategy AttemptStrategy
|
||||||
|
last time.Time
|
||||||
|
end time.Time
|
||||||
|
force bool
|
||||||
|
count int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start begins a new sequence of attempts for the given strategy.
|
||||||
|
func (s AttemptStrategy) Start() *Attempt {
|
||||||
|
now := time.Now()
|
||||||
|
return &Attempt{
|
||||||
|
strategy: s,
|
||||||
|
last: now,
|
||||||
|
end: now.Add(s.Total),
|
||||||
|
force: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next waits until it is time to perform the next attempt or returns
|
||||||
|
// false if it is time to stop trying.
|
||||||
|
func (a *Attempt) Next() bool {
|
||||||
|
now := time.Now()
|
||||||
|
sleep := a.nextSleep(now)
|
||||||
|
if !a.force && !now.Add(sleep).Before(a.end) && a.strategy.Min <= a.count {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
a.force = false
|
||||||
|
if sleep > 0 && a.count > 0 {
|
||||||
|
time.Sleep(sleep)
|
||||||
|
now = time.Now()
|
||||||
|
}
|
||||||
|
a.count++
|
||||||
|
a.last = now
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Attempt) nextSleep(now time.Time) time.Duration {
|
||||||
|
sleep := a.strategy.Delay - now.Sub(a.last)
|
||||||
|
if sleep < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return sleep
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasNext returns whether another attempt will be made if the current
|
||||||
|
// one fails. If it returns true, the following call to Next is
|
||||||
|
// guaranteed to return true.
|
||||||
|
func (a *Attempt) HasNext() bool {
|
||||||
|
if a.force || a.strategy.Min > a.count {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
now := time.Now()
|
||||||
|
if now.Add(a.nextSleep(now)).Before(a.end) {
|
||||||
|
a.force = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/url"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//ConvertToQueryValues converts the struct to url.Values
|
||||||
|
func ConvertToQueryValues(ifc interface{}) url.Values {
|
||||||
|
values := url.Values{}
|
||||||
|
SetQueryValues(ifc, &values)
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetQueryValues sets the struct to existing url.Values following ECS encoding rules
|
||||||
|
func SetQueryValues(ifc interface{}, values *url.Values) {
|
||||||
|
setQueryValues(ifc, values, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func setQueryValues(i interface{}, values *url.Values, prefix string) {
|
||||||
|
// add to support url.Values
|
||||||
|
mapValues, ok := i.(url.Values)
|
||||||
|
if ok {
|
||||||
|
for k, _ := range mapValues {
|
||||||
|
values.Set(k, mapValues.Get(k))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
elem := reflect.ValueOf(i)
|
||||||
|
if elem.Kind() == reflect.Ptr {
|
||||||
|
elem = elem.Elem()
|
||||||
|
}
|
||||||
|
elemType := elem.Type()
|
||||||
|
for i := 0; i < elem.NumField(); i++ {
|
||||||
|
|
||||||
|
fieldName := elemType.Field(i).Name
|
||||||
|
anonymous := elemType.Field(i).Anonymous
|
||||||
|
field := elem.Field(i)
|
||||||
|
// TODO Use Tag for validation
|
||||||
|
// tag := typ.Field(i).Tag.Get("tagname")
|
||||||
|
kind := field.Kind()
|
||||||
|
if (kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map || kind == reflect.Chan) && field.IsNil() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if kind == reflect.Ptr {
|
||||||
|
field = field.Elem()
|
||||||
|
kind = field.Kind()
|
||||||
|
}
|
||||||
|
var value string
|
||||||
|
//switch field.Interface().(type) {
|
||||||
|
switch kind {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
i := field.Int()
|
||||||
|
if i != 0 {
|
||||||
|
value = strconv.FormatInt(i, 10)
|
||||||
|
}
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
i := field.Uint()
|
||||||
|
if i != 0 {
|
||||||
|
value = strconv.FormatUint(i, 10)
|
||||||
|
}
|
||||||
|
case reflect.Float32:
|
||||||
|
value = strconv.FormatFloat(field.Float(), 'f', 4, 32)
|
||||||
|
case reflect.Float64:
|
||||||
|
value = strconv.FormatFloat(field.Float(), 'f', 4, 64)
|
||||||
|
case reflect.Bool:
|
||||||
|
value = strconv.FormatBool(field.Bool())
|
||||||
|
case reflect.String:
|
||||||
|
value = field.String()
|
||||||
|
case reflect.Map:
|
||||||
|
ifc := field.Interface()
|
||||||
|
m := ifc.(map[string]string)
|
||||||
|
if m != nil {
|
||||||
|
j := 0
|
||||||
|
for k, v := range m {
|
||||||
|
j++
|
||||||
|
keyName := fmt.Sprintf("%s.%d.Key", fieldName, j)
|
||||||
|
values.Set(keyName, k)
|
||||||
|
valueName := fmt.Sprintf("%s.%d.Value", fieldName, j)
|
||||||
|
values.Set(valueName, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
switch field.Type().Elem().Kind() {
|
||||||
|
case reflect.Uint8:
|
||||||
|
value = string(field.Bytes())
|
||||||
|
case reflect.String:
|
||||||
|
l := field.Len()
|
||||||
|
if l > 0 {
|
||||||
|
strArray := make([]string, l)
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
strArray[i] = field.Index(i).String()
|
||||||
|
}
|
||||||
|
bytes, err := json.Marshal(strArray)
|
||||||
|
if err == nil {
|
||||||
|
value = string(bytes)
|
||||||
|
} else {
|
||||||
|
log.Printf("Failed to convert JSON: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
l := field.Len()
|
||||||
|
for j := 0; j < l; j++ {
|
||||||
|
prefixName := fmt.Sprintf("%s.%d.", fieldName, (j + 1))
|
||||||
|
ifc := field.Index(j).Interface()
|
||||||
|
//log.Printf("%s : %v", prefixName, ifc)
|
||||||
|
if ifc != nil {
|
||||||
|
setQueryValues(ifc, values, prefixName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch field.Interface().(type) {
|
||||||
|
case ISO6801Time:
|
||||||
|
t := field.Interface().(ISO6801Time)
|
||||||
|
value = t.String()
|
||||||
|
case time.Time:
|
||||||
|
t := field.Interface().(time.Time)
|
||||||
|
value = GetISO8601TimeStamp(t)
|
||||||
|
default:
|
||||||
|
ifc := field.Interface()
|
||||||
|
if ifc != nil {
|
||||||
|
if anonymous {
|
||||||
|
SetQueryValues(ifc, values)
|
||||||
|
} else {
|
||||||
|
prefixName := fieldName + "."
|
||||||
|
setQueryValues(ifc, values, prefixName)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if value != "" {
|
||||||
|
name := elemType.Field(i).Tag.Get("ArgName")
|
||||||
|
if name == "" {
|
||||||
|
name = fieldName
|
||||||
|
}
|
||||||
|
if prefix != "" {
|
||||||
|
name = prefix + name
|
||||||
|
}
|
||||||
|
values.Set(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetISO8601TimeStamp gets timestamp string in ISO8601 format
|
||||||
|
func GetISO8601TimeStamp(ts time.Time) string {
|
||||||
|
t := ts.UTC()
|
||||||
|
return fmt.Sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatISO8601 = "2006-01-02T15:04:05Z"
|
||||||
|
const jsonFormatISO8601 = `"` + formatISO8601 + `"`
|
||||||
|
const formatISO8601withoutSeconds = "2006-01-02T15:04Z"
|
||||||
|
const jsonFormatISO8601withoutSeconds = `"` + formatISO8601withoutSeconds + `"`
|
||||||
|
|
||||||
|
// A ISO6801Time represents a time in ISO8601 format
|
||||||
|
type ISO6801Time time.Time
|
||||||
|
|
||||||
|
// New constructs a new iso8601.Time instance from an existing
|
||||||
|
// time.Time instance. This causes the nanosecond field to be set to
|
||||||
|
// 0, and its time zone set to a fixed zone with no offset from UTC
|
||||||
|
// (but it is *not* UTC itself).
|
||||||
|
func NewISO6801Time(t time.Time) ISO6801Time {
|
||||||
|
return ISO6801Time(time.Date(
|
||||||
|
t.Year(),
|
||||||
|
t.Month(),
|
||||||
|
t.Day(),
|
||||||
|
t.Hour(),
|
||||||
|
t.Minute(),
|
||||||
|
t.Second(),
|
||||||
|
0,
|
||||||
|
time.UTC,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDefault checks if the time is default
|
||||||
|
func (it *ISO6801Time) IsDefault() bool {
|
||||||
|
return *it == ISO6801Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON serializes the ISO6801Time into JSON string
|
||||||
|
func (it ISO6801Time) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(time.Time(it).Format(jsonFormatISO8601)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON deserializes the ISO6801Time from JSON string
|
||||||
|
func (it *ISO6801Time) UnmarshalJSON(data []byte) error {
|
||||||
|
str := string(data)
|
||||||
|
|
||||||
|
if str == "\"\"" || len(data) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var t time.Time
|
||||||
|
var err error
|
||||||
|
if str[0] == '"' {
|
||||||
|
t, err = time.ParseInLocation(jsonFormatISO8601, str, time.UTC)
|
||||||
|
if err != nil {
|
||||||
|
t, err = time.ParseInLocation(jsonFormatISO8601withoutSeconds, str, time.UTC)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var i int64
|
||||||
|
i, err = strconv.ParseInt(str, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
t = time.Unix(i/1000, i%1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
*it = ISO6801Time(t)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the time in ISO6801Time format
|
||||||
|
func (it ISO6801Time) String() string {
|
||||||
|
return time.Time(it).Format(formatISO8601)
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/base64"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
//CreateSignature creates signature for string following Aliyun rules
|
||||||
|
func CreateSignature(stringToSignature, accessKeySecret string) string {
|
||||||
|
// Crypto by HMAC-SHA1
|
||||||
|
hmacSha1 := hmac.New(sha1.New, []byte(accessKeySecret))
|
||||||
|
hmacSha1.Write([]byte(stringToSignature))
|
||||||
|
sign := hmacSha1.Sum(nil)
|
||||||
|
|
||||||
|
// Encode to Base64
|
||||||
|
base64Sign := base64.StdEncoding.EncodeToString(sign)
|
||||||
|
|
||||||
|
return base64Sign
|
||||||
|
}
|
||||||
|
|
||||||
|
func percentReplace(str string) string {
|
||||||
|
str = strings.Replace(str, "+", "%20", -1)
|
||||||
|
str = strings.Replace(str, "*", "%2A", -1)
|
||||||
|
str = strings.Replace(str, "%7E", "~", -1)
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSignatureForRequest creates signature for query string values
|
||||||
|
func CreateSignatureForRequest(method string, values *url.Values, accessKeySecret string) string {
|
||||||
|
|
||||||
|
canonicalizedQueryString := percentReplace(values.Encode())
|
||||||
|
|
||||||
|
stringToSign := method + "&%2F&" + url.QueryEscape(canonicalizedQueryString)
|
||||||
|
|
||||||
|
return CreateSignature(stringToSign, accessKeySecret)
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
srand "crypto/rand"
|
||||||
|
"encoding/binary"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const dictionary = "_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
|
//CreateRandomString create random string
|
||||||
|
func CreateRandomString() string {
|
||||||
|
b := make([]byte, 32)
|
||||||
|
l := len(dictionary)
|
||||||
|
|
||||||
|
_, err := srand.Read(b)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// fail back to insecure rand
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
for i := range b {
|
||||||
|
b[i] = dictionary[rand.Int()%l]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i, v := range b {
|
||||||
|
b[i] = dictionary[v%byte(l)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encodes the values into ``URL encoded'' form
|
||||||
|
// ("acl&bar=baz&foo=quux") sorted by key.
|
||||||
|
func Encode(v url.Values) string {
|
||||||
|
if v == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
keys := make([]string, 0, len(v))
|
||||||
|
for k := range v {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
for _, k := range keys {
|
||||||
|
vs := v[k]
|
||||||
|
prefix := url.QueryEscape(k)
|
||||||
|
for _, v := range vs {
|
||||||
|
if buf.Len() > 0 {
|
||||||
|
buf.WriteByte('&')
|
||||||
|
}
|
||||||
|
buf.WriteString(prefix)
|
||||||
|
if v != "" {
|
||||||
|
buf.WriteString("=")
|
||||||
|
buf.WriteString(url.QueryEscape(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetGMTime() string {
|
||||||
|
return time.Now().UTC().Format(http.TimeFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
func randUint32() uint32 {
|
||||||
|
return randUint32Slice(1)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func randUint32Slice(c int) []uint32 {
|
||||||
|
b := make([]byte, c*4)
|
||||||
|
|
||||||
|
_, err := srand.Read(b)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// fail back to insecure rand
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
for i := range b {
|
||||||
|
b[i] = byte(rand.Int())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n := make([]uint32, c)
|
||||||
|
|
||||||
|
for i := range n {
|
||||||
|
n[i] = binary.BigEndian.Uint32(b[i*4 : i*4+4])
|
||||||
|
}
|
||||||
|
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func toByte(n uint32, st, ed byte) byte {
|
||||||
|
return byte(n%uint32(ed-st+1) + uint32(st))
|
||||||
|
}
|
||||||
|
|
||||||
|
func toDigit(n uint32) byte {
|
||||||
|
return toByte(n, '0', '9')
|
||||||
|
}
|
||||||
|
|
||||||
|
func toLowerLetter(n uint32) byte {
|
||||||
|
return toByte(n, 'a', 'z')
|
||||||
|
}
|
||||||
|
|
||||||
|
func toUpperLetter(n uint32) byte {
|
||||||
|
return toByte(n, 'A', 'Z')
|
||||||
|
}
|
||||||
|
|
||||||
|
type convFunc func(uint32) byte
|
||||||
|
|
||||||
|
var convFuncs = []convFunc{toDigit, toLowerLetter, toUpperLetter}
|
||||||
|
|
||||||
|
// tools for generating a random ECS instance password
|
||||||
|
// from 8 to 30 char MUST contain digit upper, case letter and upper case letter
|
||||||
|
// http://docs.aliyun.com/#/pub/ecs/open-api/instance&createinstance
|
||||||
|
func GenerateRandomECSPassword() string {
|
||||||
|
|
||||||
|
// [8, 30]
|
||||||
|
l := int(randUint32()%23 + 8)
|
||||||
|
|
||||||
|
n := randUint32Slice(l)
|
||||||
|
|
||||||
|
b := make([]byte, l)
|
||||||
|
|
||||||
|
b[0] = toDigit(n[0])
|
||||||
|
b[1] = toLowerLetter(n[1])
|
||||||
|
b[2] = toUpperLetter(n[2])
|
||||||
|
|
||||||
|
for i := 3; i < l; i++ {
|
||||||
|
b[i] = convFuncs[n[i]%3](n[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
s := make([]byte, l)
|
||||||
|
perm := rand.Perm(l)
|
||||||
|
for i, v := range perm {
|
||||||
|
s[v] = b[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(s)
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue