Codebase list golang-github-denverdino-aliyungo / c86d946
Import upstream version 0.0~git20220905.589a058 Debian Janitor 1 year, 7 months ago
123 changed file(s) with 5736 addition(s) and 538 deletion(s). Raw diff Collapse all Expand all
11 jobs:
22 build:
33 docker:
4 - image: circleci/golang:1.8
4 - image: circleci/golang:1.10
55 working_directory: /go/src/github.com/denverdino/aliyungo
66 steps:
77 - checkout
0 name: Go
1 on: [push]
2 jobs:
3
4 build:
5 name: Build
6 runs-on: ubuntu-latest
7 steps:
8
9 - name: Set up Go 1.13
10 uses: actions/setup-go@v1
11 with:
12 go-version: 1.13
13 id: go
14
15 - name: Check out code into the Go module directory
16 uses: actions/checkout@v1
17
18 - name: Get dependencies
19 run: |
20 go get -v -t -d ./...
21 if [ -f Gopkg.toml ]; then
22 curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
23 dep ensure
24 fi
25 - name: Run golangci-lint with reviewdog
26 uses: reviewdog/action-golangci-lint@v1.1.3
27 with:
28 github_token: ${{ secrets.github_token }}
29
30
00 language: go
1
1 arch:
2 - AMD64
3 - ppc64le
24 go:
3 - 1.7.4
5 - 1.10.8
46
57 # let us have speedy Docker-based Travis workers
68 sudo: false
00 package acm
11
22 import (
3 "crypto/hmac"
4 "crypto/sha1"
5 "encoding/base64"
6 "errors"
7 "fmt"
8 "io/ioutil"
39 "net/http"
10 "net/url"
11 "strconv"
12 "strings"
413 "time"
5 "fmt"
6 "errors"
7 "io/ioutil"
8 "strings"
9 "encoding/base64"
10 "crypto/sha1"
11 "crypto/hmac"
12 "strconv"
13 "net/url"
1414 )
1515
1616 type Client struct {
6565 servers := strings.Split(body, "\n")
6666
6767 for k, v := range servers {
68 if strings.Index(v, ":") == -1 {
68 if !strings.Contains(v, ":") {
6969 c.servers[k] = v + ":8080"
7070 } else {
7171 c.servers[k] = v
100100 timeStamp = timeStamp[:13]
101101
102102 spec := "?"
103 if strings.Index(api, "?") != -1 {
103 if strings.Contains(api, "?") {
104104 spec = "&"
105105 }
106106
132132 request.Header.Add("Spas-Signature", c.getSign([]string{probe}))
133133 c.HttpClient.Timeout = time.Duration(c.TimeOut+30) * time.Second
134134 } else {
135 request.Header.Add("Spas-Signature", c.getSign([]string{c.NameSpace, params["group"], timeStamp}))
135 if group, exists := params["group"]; exists {
136 request.Header.Add("Spas-Signature", c.getSign([]string{c.NameSpace, group, timeStamp}))
137 } else {
138 request.Header.Add("Spas-Signature", c.getSign([]string{c.NameSpace, timeStamp}))
139 }
140
136141 }
137142
138143 resp, err := c.HttpClient.Do(request)
143148 defer resp.Body.Close()
144149
145150 byt, err := ioutil.ReadAll(resp.Body)
146 if err != nil {
147 return "", err
148 }
149
150 byt, err = GbkToUtf8(byt)
151151 if err != nil {
152152 return "", err
153153 }
176176 return c.callApi("diamond-server/basestone.do?method=getAllConfigByTenant", map[string]string{
177177 "pageNo": strconv.Itoa(pageNo),
178178 "pageSize": strconv.Itoa(pageSize),
179 "tenant": c.NameSpace,
180 "method": "getAllConfigByTenant",
179181 }, "GET")
180182 }
181183
182184 func (c *Client) Publish(dataId, group, content string) (string, error) {
183 bt, err := Utf8ToGbk([]byte(content))
184 if err != nil {
185 return "", err
186 }
187
188185 return c.callApi("diamond-server/basestone.do?method=syncUpdateAll", map[string]string{
189186 "tenant": c.NameSpace,
190187 "dataId": dataId,
191188 "group": group,
192 "content": string(bt),
189 "content": content,
193190 }, "POST")
194191 }
195192
00 package acm
11
22 import (
3 "testing"
3 "fmt"
44 "log"
55 "os"
6 "fmt"
6 "testing"
77 )
88
99 func getClient() *Client {
2525 client := getClient()
2626 defer client.Delete("test", "test")
2727
28 _, err := client.Publish("test", "test", "test")
28 _, err := client.Publish("test", "test", "test测试")
2929
3030 if err != nil {
3131 t.Fatalf("pulish error:%s", err)
4949 if err != nil {
5050 t.Error(err)
5151 }
52 if ret != "test测试" {
53 t.Error("wrong respond content")
54 }
5255 fmt.Println(ret)
5356 })
5457 }
5558
5659 func TestClient_Subscribe(t *testing.T) {
5760 RunWithTest(t, func(client *Client, t *testing.T) {
58 _, err := client.Subscribe("test", "test","")
61 _, err := client.Subscribe("test", "test", "")
5962 if err != nil {
6063 t.Error(err)
6164 }
6265 })
6366 }
67
68 func TestClient_GetAllConfig(t *testing.T) {
69 RunWithTest(t, func(client *Client, t *testing.T) {
70 _, err := client.GetAllConfigs(1, 200)
71 if err != nil {
72 t.Error(err)
73 }
74 })
75 }
0 package auth
1
2 import (
3 "crypto/rand"
4 "fmt"
5 "io"
6 "os"
7 "syscall"
8 "time"
9 )
10
11 const (
12 // Bits is the number of bits in a UUID
13 Bits = 128
14
15 // Size is the number of bytes in a UUID
16 Size = Bits / 8
17
18 format = "%08x%04x%04x%04x%012x"
19 )
20
21 var (
22 // Loggerf can be used to override the default logging destination. Such
23 // log messages in this library should be logged at warning or higher.
24 Loggerf = func(format string, args ...interface{}) {}
25 )
26
27 // UUID represents a UUID value. UUIDs can be compared and set to other values
28 // and accessed by byte.
29 type UUID [Size]byte
30
31 // GenerateUUID creates a new, version 4 uuid.
32 func GenerateUUID() (u UUID) {
33 const (
34 // ensures we backoff for less than 450ms total. Use the following to
35 // select new value, in units of 10ms:
36 // n*(n+1)/2 = d -> n^2 + n - 2d -> n = (sqrt(8d + 1) - 1)/2
37 maxretries = 9
38 backoff = time.Millisecond * 10
39 )
40
41 var (
42 totalBackoff time.Duration
43 count int
44 retries int
45 )
46
47 for {
48 // This should never block but the read may fail. Because of this,
49 // we just try to read the random number generator until we get
50 // something. This is a very rare condition but may happen.
51 b := time.Duration(retries) * backoff
52 time.Sleep(b)
53 totalBackoff += b
54
55 n, err := io.ReadFull(rand.Reader, u[count:])
56 if err != nil {
57 if retryOnError(err) && retries < maxretries {
58 count += n
59 retries++
60 Loggerf("error generating version 4 uuid, retrying: %v", err)
61 continue
62 }
63
64 // Any other errors represent a system problem. What did someone
65 // do to /dev/urandom?
66 panic(fmt.Errorf("error reading random number generator, retried for %v: %v", totalBackoff.String(), err))
67 }
68
69 break
70 }
71
72 u[6] = (u[6] & 0x0f) | 0x40 // set version byte
73 u[8] = (u[8] & 0x3f) | 0x80 // set high order byte 0b10{8,9,a,b}
74
75 return u
76 }
77
78 func (u UUID) String() string {
79 return fmt.Sprintf(format, u[:4], u[4:6], u[6:8], u[8:10], u[10:])
80 }
81
82 // retryOnError tries to detect whether or not retrying would be fruitful.
83 func retryOnError(err error) bool {
84 switch err := err.(type) {
85 case *os.PathError:
86 return retryOnError(err.Err) // unpack the target error
87 case syscall.Errno:
88 if err == syscall.EPERM {
89 // EPERM represents an entropy pool exhaustion, a condition under
90 // which we backoff and retry.
91 return true
92 }
93 }
94
95 return false
96 }
0 package auth
1
2 import (
3 "testing"
4 )
5
6 const iterations = 1000
7
8 func TestUUID4Generation(t *testing.T) {
9 for i := 0; i < iterations; i++ {
10 u := GenerateUUID()
11
12 if u[6]&0xf0 != 0x40 {
13 t.Fatalf("version byte not correctly set: %v, %08b %08b", u, u[6], u[6]&0xf0)
14 }
15
16 if u[8]&0xc0 != 0x80 {
17 t.Fatalf("top order 8th byte not correctly set: %v, %b", u, u[8])
18 }
19 }
20 }
0 package auth
1
2 import (
3 "crypto/md5"
4 "fmt"
5 "net/url"
6 "time"
7 )
8
9 // An URLSigner provides URL signing utilities to sign URLs for Aliyun CDN
10 // resources.
11 // authentication document: https://help.aliyun.com/document_detail/85117.html
12 type URLSigner struct {
13 authType string
14 privKey string
15 }
16
17 // NewURLSigner returns a new signer object.
18 func NewURLSigner(authType string, privKey string) *URLSigner {
19 return &URLSigner{
20 authType: authType,
21 privKey: privKey,
22 }
23 }
24
25 // Sign returns a signed aliyuncdn url based on authentication type
26 func (s URLSigner) Sign(uri string, expires time.Time) (string, error) {
27 r, err := url.Parse(uri)
28 if err != nil {
29 return "", fmt.Errorf("unable to parse url: %s", uri)
30 }
31
32 switch s.authType {
33 case "a":
34 return aTypeSign(r, s.privKey, expires), nil
35 case "b":
36 return bTypeSign(r, s.privKey, expires), nil
37 case "c":
38 return cTypeSign(r, s.privKey, expires), nil
39 default:
40 return "", fmt.Errorf("invalid authentication type")
41 }
42 }
43
44 // sign by A type authentication method.
45 // authentication document: https://help.aliyun.com/document_detail/85113.html
46 func aTypeSign(r *url.URL, privateKey string, expires time.Time) string {
47 //rand is a random uuid without "-"
48 rand := GenerateUUID().String()
49 // not use, "0" by default
50 uid := "0"
51 secret := fmt.Sprintf("%s-%d-%s-%s-%s", r.Path, expires.Unix(), rand, uid, privateKey)
52 hashValue := md5.Sum([]byte(secret))
53 authKey := fmt.Sprintf("%d-%s-%s-%x", expires.Unix(), rand, uid, hashValue)
54 if r.RawQuery == "" {
55 return fmt.Sprintf("%s?auth_key=%s", r.String(), authKey)
56 }
57 return fmt.Sprintf("%s&auth_key=%s", r.String(), authKey)
58
59 }
60
61 // sign by B type authentication method.
62 // authentication document: https://help.aliyun.com/document_detail/85114.html
63 func bTypeSign(r *url.URL, privateKey string, expires time.Time) string {
64 formatExp := expires.Format("200601021504")
65 secret := privateKey + formatExp + r.Path
66 hashValue := md5.Sum([]byte(secret))
67 signURL := fmt.Sprintf("%s://%s/%s/%x%s?%s", r.Scheme, r.Host, formatExp, hashValue, r.Path, r.RawQuery)
68 return signURL
69 }
70
71 // sign by C type authentication method.
72 // authentication document: https://help.aliyun.com/document_detail/85115.html
73 func cTypeSign(r *url.URL, privateKey string, expires time.Time) string {
74 hexExp := fmt.Sprintf("%x", expires.Unix())
75 secret := privateKey + r.Path + hexExp
76 hashValue := md5.Sum([]byte(secret))
77 signURL := fmt.Sprintf("%s://%s/%x/%s%s?%s", r.Scheme, r.Host, hashValue, hexExp, r.Path, r.RawQuery)
78 return signURL
79 }
0 package auth
1
2 import (
3 "crypto/md5"
4 "fmt"
5 "net/url"
6 "reflect"
7 "testing"
8 "time"
9 )
10
11 var (
12 testSignTime = time.Unix(1541064730, 0)
13 testPrivKey = "12345678"
14 )
15
16 func assertEqual(t *testing.T, name string, x, y interface{}) {
17 if !reflect.DeepEqual(x, y) {
18 t.Errorf("%s: Not equal! Expected='%v', Actual='%v'\n", name, x, y)
19 t.FailNow()
20 }
21 }
22
23 func TestAtypeAuth(t *testing.T) {
24 r, _ := url.Parse("https://example.com/a?foo=bar")
25 url := aTypeTest(r, testPrivKey, testSignTime)
26 assertEqual(t, "testTypeA", "https://example.com/a?foo=bar&auth_key=1541064730-0-0-f9dd5ed1e274ab4b1d5f5745344bf28b", url)
27 }
28
29 func TestBtypeAuth(t *testing.T) {
30 signer := NewURLSigner("b", testPrivKey)
31 url, _ := signer.Sign("https://example.com/a?foo=bar", testSignTime)
32 assertEqual(t, "testTypeB", "https://example.com/201811011732/3a19d83a89ccb00a73212420791b0123/a?foo=bar", url)
33 }
34
35 func TestCtypeAuth(t *testing.T) {
36 signer := NewURLSigner("c", testPrivKey)
37 url, _ := signer.Sign("https://example.com/a?foo=bar", testSignTime)
38 assertEqual(t, "testTypeC", "https://example.com/7d6b308ce87beb16d9dba32d741220f6/5bdac81a/a?foo=bar", url)
39 }
40
41 func aTypeTest(r *url.URL, privateKey string, expires time.Time) string {
42 //rand equals "0" in test case
43 rand := "0"
44 uid := "0"
45 secret := fmt.Sprintf("%s-%d-%s-%s-%s", r.Path, expires.Unix(), rand, uid, privateKey)
46 hashValue := md5.Sum([]byte(secret))
47 authKey := fmt.Sprintf("%d-%s-%s-%x", expires.Unix(), rand, uid, hashValue)
48 if r.RawQuery == "" {
49 return fmt.Sprintf("%s?auth_key=%s", r.String(), authKey)
50 }
51 return fmt.Sprintf("%s&auth_key=%s", r.String(), authKey)
52 }
88 const (
99 Web = "web"
1010 Download = "download"
11 video = "video"
11 Video = "video"
1212 LiveStream = "liveStream"
1313 Ipaddr = "ipaddr"
1414 Domain = "domain"
2626 AccessControlMaxAge = "Access-Control-Max-Age"
2727 )
2828
29 var CdnTypes = []string{Web, Download, video, LiveStream}
29 var CdnTypes = []string{Web, Download, Video, LiveStream}
3030 var SourceTypes = []string{Ipaddr, Domain, OSS}
3131 var Scopes = []string{Domestic, Overseas, Global}
3232 var HeaderKeys = []string{ContentType, CacheControl, ContentDisposition, ContentLanguage, Expires, AccessControlAllowMethods, AccessControlAllowOrigin, AccessControlMaxAge}
0 package cen
1
2 import (
3 "os"
4
5 "github.com/denverdino/aliyungo/common"
6 )
7
8 // Interval for checking status in WaitForXXX method
9 const DefaultWaitForInterval = 5
10
11 // Default timeout value for WaitForXXX method
12 const DefaultTimeout = 60
13
14 type Client struct {
15 common.Client
16 }
17
18 const (
19 // CENDefaultEndpoint is the default API endpoint of CEN services
20 CENDefaultEndpoint = "https://cbn.aliyuncs.com"
21 CENAPIVersion = "2017-09-12"
22 CENServiceCode = "cen"
23 )
24
25 // ---------------------------------------
26 // NewCENClient creates a new instance of CEN client
27 // ---------------------------------------
28 func NewCENClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client {
29 return NewCENClientWithSecurityToken(accessKeyId, accessKeySecret, "", regionID)
30 }
31
32 func NewCENClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
33 endpoint := os.Getenv("CEN_ENDPOINT")
34 if endpoint == "" {
35 endpoint = CENDefaultEndpoint
36 }
37
38 return NewCENClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
39 }
40
41 //only for Hangzhou Regional Domain
42 func NewCENClientWithSecurityToken4RegionalDomain(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
43 endpoint := os.Getenv("CEN_ENDPOINT")
44 if endpoint == "" {
45 endpoint = CENDefaultEndpoint
46 }
47
48 return NewCENClientWithEndpointAndSecurityToken4RegionalDomain(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
49 }
50
51 func NewCENClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
52 client := &Client{}
53 client.WithEndpoint(endpoint).
54 WithVersion(CENAPIVersion).
55 WithAccessKeyId(accessKeyId).
56 WithAccessKeySecret(accessKeySecret).
57 WithSecurityToken(securityToken).
58 WithServiceCode(CENServiceCode).
59 WithRegionID(regionID).
60 InitClient()
61 return client
62 }
63
64 func NewCENClientWithEndpointAndSecurityToken4RegionalDomain(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
65 client := &Client{}
66 client.WithEndpoint(endpoint).
67 WithVersion(CENAPIVersion).
68 WithAccessKeyId(accessKeyId).
69 WithAccessKeySecret(accessKeySecret).
70 WithSecurityToken(securityToken).
71 WithServiceCode(CENServiceCode).
72 WithRegionID(regionID).
73 InitClient4RegionalDomain()
74 return client
75 }
0 package cen
1
2 import (
3 "log"
4
5 "github.com/denverdino/aliyungo/common"
6 )
7
8 type PublishRouteEntriesArgs struct {
9 CenId string
10 ChildInstanceId string
11 ChildInstanceRegionId string
12 ChildInstanceRouteTableId string
13 ChildInstanceType string
14 DestinationCidrBlock string
15 }
16
17 type DescribePublishedRouteEntriesArgs struct {
18 common.Pagination
19 CenId string
20 ChildInstanceId string
21 ChildInstanceRegionId string
22 ChildInstanceType string
23 ChildInstanceRouteTableId string
24 DestinationCidrBlock string
25 }
26
27 type DescribePublishedRouteEntriesResponse struct {
28 common.Response
29 common.PaginationResult
30 PublishedRouteEntries struct {
31 PublishedRouteEntry []PublishedRouteEntry
32 }
33 }
34
35 type ConflictStatus string
36 type NextHopType string
37
38 const (
39 ConflictStatusConflict = ConflictStatus("conflict")
40 ConflictStatusOverflow = ConflictStatus("overflow")
41 ConflictStatusProhibited = ConflictStatus("prohibited")
42 )
43
44 const (
45 NextHopTypeInstance = NextHopType("Instance")
46 NextHopTypeHaVip = NextHopType("HaVip")
47 NextHopTypeRouterInterface = NextHopType("RouterInterface")
48 )
49
50 type PublishStatus string
51
52 const (
53 PublishStatusPublished = PublishStatus("Published")
54 PublishStatusNotPublished = PublishStatus("NonPublished")
55 )
56
57 type RouteType string
58
59 const (
60 RouteTypeSystem = RouteType("System")
61 RouteTypeCustom = RouteType("Custom")
62 RouteTypeBGP = RouteType("BGP")
63 )
64
65 type PublishedRouteEntry struct {
66 ChildInstanceRouteTableId string
67 Conflicts struct {
68 Conflict []Conflict
69 }
70 DestinationCidrBlock string
71 NextHopId string
72
73 NextHopType string
74 OperationalMode bool
75 PublishStatus string
76 RouteType string
77 }
78
79 type Conflict struct {
80 DestinationCidrBlock string
81 InstanceId string
82 InstanceType string
83 RegionId string
84 Status string
85 }
86
87 // PublishRouteEntries publish route
88 //
89 // You can read doc at https://help.aliyun.com/document_detail/85470.html
90 func (client *Client) PublishRouteEntries(args *PublishRouteEntriesArgs) error {
91 response := &common.Response{}
92 err := client.Invoke("PublishRouteEntries", args, response)
93 if err != nil {
94 log.Printf("PublishRouteEntries: %s, %s\n", response.RequestId, err.Error())
95 }
96 return err
97 }
98
99 // DescribePublishedRouteEntries describe published route
100 //
101 // You can read doc at https://help.aliyun.com/document_detail/85472.html
102 func (client *Client) DescribePublishedRouteEntries(
103 args *DescribePublishedRouteEntriesArgs,
104 ) (response *DescribePublishedRouteEntriesResponse, err error) {
105
106 response = &DescribePublishedRouteEntriesResponse{}
107
108 err = client.Invoke("DescribePublishedRouteEntries", args, response)
109
110 if err != nil {
111 log.Printf("DescribePublishedRouteEntries: %v, %v\n", args, response)
112 }
113
114 return response, err
115 }
0 package cen
1
2 import (
3 "encoding/json"
4 "fmt"
5 "testing"
6 )
7
8 var (
9 ak = ""
10 sec = ""
11 )
12
13 func TestDescribePublishedRoute(t *testing.T) {
14 client := NewCENClient(ak, sec, "cn-shanghai")
15 res, err := client.DescribePublishedRouteEntries(
16 &DescribePublishedRouteEntriesArgs{
17 CenId: "cen-qhu4rn3cknrg5o4qhl",
18 ChildInstanceType: "VPC",
19 ChildInstanceRegionId: "cn-shanghai",
20 ChildInstanceRouteTableId: "vtb-uf699blmsutb4wkbzqcmt",
21 ChildInstanceId: "vpc-uf6ch2jfder4r0z51vtox",
22 },
23 )
24 if err != nil {
25 t.Errorf("describe: %s", err.Error())
26 t.FailNow()
27 }
28 fmt.Printf("Result: %+v", res)
29 b, err := json.MarshalIndent(res, "", " ")
30 fmt.Printf("%s", b)
31 }
32
33 func TestPublishedRoute(t *testing.T) {
34 client := NewCENClient(ak, sec, "cn-shanghai")
35 err := client.PublishRouteEntries(
36 &PublishRouteEntriesArgs{
37 CenId: "cen-qhu4rn3cknrg5o4qhl",
38 ChildInstanceType: "VPC",
39 ChildInstanceRegionId: "cn-shanghai",
40 ChildInstanceRouteTableId: "vtb-uf6nco4vj87ly556c589f",
41 ChildInstanceId: "vpc-uf6ch2jfder4r0z51vtox",
42 DestinationCidrBlock: "192.168.0.0/26",
43 },
44 )
45 if err != nil {
46 t.Errorf("publish: %s", err.Error())
47 t.FailNow()
48 }
49 }
3030
3131 func (client *Client) SetDebug(debug bool) {
3232 client.debug = debug
33 }
34
35 // SetTransport sets transport to the http client
36 func (client *Client) SetTransport(transport http.RoundTripper) {
37 if client.httpClient == nil {
38 client.httpClient = &http.Client{}
39 }
40 client.httpClient.Transport = transport
3341 }
3442
3543 const (
44 "encoding/json"
55 "errors"
66 "fmt"
7 "github.com/opentracing/opentracing-go/ext"
78 "io/ioutil"
89 "log"
10 "net"
911 "net/http"
1012 "net/url"
1113 "os"
1416 "time"
1517
1618 "github.com/denverdino/aliyungo/util"
19 "github.com/opentracing/opentracing-go"
1720 )
1821
1922 // RemovalPolicy.N add index to array item
3740 regionID Region
3841 businessInfo string
3942 userAgent string
43 disableTrace bool
44 span opentracing.Span
45 logger *Logger
4046 }
4147
4248 // Initialize properties of a client instance
4753 ak += "&"
4854 }
4955 client.AccessKeySecret = ak
50 client.debug = false
51 handshakeTimeout, err := strconv.Atoi(os.Getenv("TLSHandshakeTimeout"))
52 if err != nil {
53 handshakeTimeout = 0
54 }
55 if handshakeTimeout == 0 {
56 client.httpClient = &http.Client{}
57 } else {
58 t := &http.Transport{
59 TLSHandshakeTimeout: time.Duration(handshakeTimeout) * time.Second}
60 client.httpClient = &http.Client{Transport: t}
61 }
56 client.InitClient()
6257 client.endpoint = endpoint
6358 client.version = version
6459 }
7065 client.regionID = regionID
7166 }
7267
68 // Initialize properties of a client instance including regionID
69 //only for hz regional Domain
70 func (client *Client) NewInit4RegionalDomain(endpoint, version, accessKeyId, accessKeySecret, serviceCode string, regionID Region) {
71 client.Init(endpoint, version, accessKeyId, accessKeySecret)
72 client.serviceCode = serviceCode
73 client.regionID = regionID
74
75 client.setEndpoint4RegionalDomain(client.regionID, client.serviceCode, client.AccessKeyId, client.AccessKeySecret, client.securityToken)
76 }
77
7378 // Intialize client object when all properties are ready
7479 func (client *Client) InitClient() *Client {
7580 client.debug = false
76 handshakeTimeout, err := strconv.Atoi(os.Getenv("TLSHandshakeTimeout"))
77 if err != nil {
78 handshakeTimeout = 0
79 }
80 if handshakeTimeout == 0 {
81 client.httpClient = &http.Client{}
82 } else {
83 t := &http.Transport{
84 TLSHandshakeTimeout: time.Duration(handshakeTimeout) * time.Second}
85 client.httpClient = &http.Client{Transport: t}
86 }
81
82 // create DefaultTransport manully, because transport doesn't has clone method in go 1.10
83 t := &http.Transport{
84 Proxy: http.ProxyFromEnvironment,
85 DialContext: (&net.Dialer{
86 Timeout: 30 * time.Second,
87 KeepAlive: 30 * time.Second,
88 DualStack: true,
89 }).DialContext,
90 MaxIdleConns: 100,
91 IdleConnTimeout: 90 * time.Second,
92 TLSHandshakeTimeout: 10 * time.Second,
93 ExpectContinueTimeout: 1 * time.Second,
94 }
95
96 handshakeTimeoutStr, ok := os.LookupEnv("TLSHandshakeTimeout")
97 if ok {
98 handshakeTimeout, err := strconv.Atoi(handshakeTimeoutStr)
99 if err != nil {
100 log.Printf("Get TLSHandshakeTimeout from env error: %v.", err)
101 } else {
102 t.TLSHandshakeTimeout = time.Duration(handshakeTimeout) * time.Second
103 }
104 }
105
106 responseHeaderTimeoutStr, ok := os.LookupEnv("ResponseHeaderTimeout")
107 if ok {
108 responseHeaderTimeout, err := strconv.Atoi(responseHeaderTimeoutStr)
109 if err != nil {
110 log.Printf("Get ResponseHeaderTimeout from env error: %v.", err)
111 } else {
112 t.ResponseHeaderTimeout = time.Duration(responseHeaderTimeout) * time.Second
113 }
114 }
115
116 expectContinueTimeoutStr, ok := os.LookupEnv("ExpectContinueTimeout")
117 if ok {
118 expectContinueTimeout, err := strconv.Atoi(expectContinueTimeoutStr)
119 if err != nil {
120 log.Printf("Get ExpectContinueTimeout from env error: %v.", err)
121 } else {
122 t.ExpectContinueTimeout = time.Duration(expectContinueTimeout) * time.Second
123 }
124 }
125
126 idleConnTimeoutStr, ok := os.LookupEnv("IdleConnTimeout")
127 if ok {
128 idleConnTimeout, err := strconv.Atoi(idleConnTimeoutStr)
129 if err != nil {
130 log.Printf("Get IdleConnTimeout from env error: %v.", err)
131 } else {
132 t.IdleConnTimeout = time.Duration(idleConnTimeout) * time.Second
133 }
134 }
135
136 client.httpClient = &http.Client{
137 Transport: t,
138 }
139
140 httpTimeoutStr, ok := os.LookupEnv("HttpTimeout")
141 if ok {
142 httpTimeout, err := strconv.Atoi(httpTimeoutStr)
143 if err != nil {
144 log.Printf("Get HttpTimeout from env error: %v.", err)
145 } else {
146 client.httpClient.Timeout = time.Duration(httpTimeout) * time.Second
147 }
148 }
149
150 return client
151 }
152
153 // Intialize client object when all properties are ready
154 //only for regional domain hz
155 func (client *Client) InitClient4RegionalDomain() *Client {
156 client.InitClient()
157 //set endpoint
158 client.setEndpoint4RegionalDomain(client.regionID, client.serviceCode, client.AccessKeyId, client.AccessKeySecret, client.securityToken)
87159 return client
88160 }
89161
104176 locationClient := NewLocationClient(accessKeyId, accessKeySecret, securityToken)
105177 locationClient.SetDebug(true)
106178 ep := locationClient.DescribeOpenAPIEndpoint(region, serviceCode)
107 if ep == "" {
108 ep = loadEndpointFromFile(region, serviceCode)
109 }
179
180 if ep != "" {
181 client.endpoint = ep
182 }
183 }
184
185 // Get openapi endpoint accessed by ecs instance.
186 // For some UnitRegions, the endpoint pattern is https://[product].[regionid].aliyuncs.com
187 // For some CentralRegions, the endpoint pattern is https://[product].vpc-proxy.aliyuncs.com
188 // The other region, the endpoint pattern is https://[product]-vpc.[regionid].aliyuncs.com
189 func (client *Client) setEndpoint4RegionalDomain(region Region, serviceCode, accessKeyId, accessKeySecret, securityToken string) {
190 if endpoint, ok := CentralDomainServices[serviceCode]; ok {
191 client.endpoint = fmt.Sprintf("https://%s", endpoint)
192 return
193 }
194 for _, service := range RegionalDomainServices {
195 if service == serviceCode {
196 if ep, ok := UnitRegions[region]; ok {
197 client.endpoint = fmt.Sprintf("https://%s.%s.aliyuncs.com", serviceCode, ep)
198 return
199 }
200
201 client.endpoint = fmt.Sprintf("https://%s%s.%s.aliyuncs.com", serviceCode, "-vpc", region)
202 return
203 }
204 }
205 locationClient := NewLocationClient(accessKeyId, accessKeySecret, securityToken)
206 locationClient.SetDebug(true)
207 ep := locationClient.DescribeOpenAPIEndpoint(region, serviceCode)
110208
111209 if ep != "" {
112210 client.endpoint = ep
198296 return client
199297 }
200298
299 // WithUserAgent sets user agent to the request/response message
300 func (client *Client) WithDisableTrace(disableTrace bool) *Client {
301 client.SetDisableTrace(disableTrace)
302 return client
303 }
304
305 // WithUserAgent sets user agent to the request/response message
306 func (client *Client) WithSpan(span opentracing.Span) *Client {
307 client.SetSpan(span)
308 return client
309 }
310
201311 // ----------------------------------------------------
202312 // SetXXX methods
203313 // ----------------------------------------------------
205315 // SetEndpoint sets custom endpoint
206316 func (client *Client) SetEndpoint(endpoint string) {
207317 client.endpoint = endpoint
318 }
319
320 func (client *Client) GetEndpoint() string {
321 return client.endpoint
208322 }
209323
210324 // SetEndpoint sets custom version
256370 client.securityToken = securityToken
257371 }
258372
373 // SetTransport sets transport to the http client
374 func (client *Client) SetTransport(transport http.RoundTripper) {
375 if client.httpClient == nil {
376 client.httpClient = &http.Client{}
377 }
378 client.httpClient.Transport = transport
379 }
380
381 // SetDisableTrace close trace mode
382 func (client *Client) SetDisableTrace(disableTrace bool) {
383 client.disableTrace = disableTrace
384 }
385
386 // SetSpan set the parent span
387 func (client *Client) SetSpan(span opentracing.Span) {
388 client.span = span
389 }
390
259391 func (client *Client) initEndpoint() error {
260392 // if set any value to "CUSTOMIZED_ENDPOINT" could skip location service.
261393 // example: export CUSTOMIZED_ENDPOINT=true
263395 return nil
264396 }
265397
398 if client.endpoint != "" {
399 return nil
400 }
401
266402 if client.serviceCode != "" && client.regionID != "" {
267403 endpoint := client.getEndpointByLocation()
268404 if endpoint == "" {
274410 }
275411
276412 // Invoke sends the raw HTTP request for ECS services
277 func (client *Client) Invoke(action string, args interface{}, response interface{}) error {
413 func (client *Client) Invoke(action string, args interface{}, response interface{}) (err error) {
278414 if err := client.ensureProperties(); err != nil {
279415 return err
280416 }
417
418 // log request
419 fieldMap := make(map[string]string)
420 initLogMsg(fieldMap)
421 defer func() {
422 client.printLog(fieldMap, err)
423 }()
424
425 request := Request{}
426 request.init(client.version, action, client.AccessKeyId, client.securityToken, client.regionID)
427
428 query := util.ConvertToQueryValues(request)
429 util.SetQueryValues(args, &query)
430
431 // Sign request
432 signature := util.CreateSignatureForRequest(ECSRequestMethod, &query, client.AccessKeySecret)
433
434 // Generate the request URL
435 requestURL := client.endpoint + "?" + query.Encode() + "&Signature=" + url.QueryEscape(signature)
436
437 httpReq, err := http.NewRequest(ECSRequestMethod, requestURL, nil)
438
439 if err != nil {
440 return GetClientError(err)
441 }
442
443 // TODO move to util and add build val flag
444 httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo)
445 httpReq.Header.Set("User-Agent", httpReq.UserAgent()+" "+client.userAgent)
446
447 // Set tracer
448 var span opentracing.Span
449 if ok := opentracing.IsGlobalTracerRegistered(); ok && !client.disableTrace {
450 tracer := opentracing.GlobalTracer()
451 var rootCtx opentracing.SpanContext
452
453 if client.span != nil {
454 rootCtx = client.span.Context()
455 }
456
457 span = tracer.StartSpan(
458 "AliyunGO-"+request.Action,
459 opentracing.ChildOf(rootCtx),
460 opentracing.Tag{string(ext.Component), "AliyunGO"},
461 opentracing.Tag{"ActionName", request.Action})
462
463 defer span.Finish()
464 tracer.Inject(
465 span.Context(),
466 opentracing.HTTPHeaders,
467 opentracing.HTTPHeadersCarrier(httpReq.Header))
468 }
469
470 putMsgToMap(fieldMap, httpReq)
471 t0 := time.Now()
472 fieldMap["{start_time}"] = t0.Format("2006-01-02 15:04:05")
473 httpResp, err := client.httpClient.Do(httpReq)
474 t1 := time.Now()
475 fieldMap["{cost}"] = t1.Sub(t0).String()
476 if err != nil {
477 if span != nil {
478 ext.LogError(span, err)
479 }
480 return GetClientError(err)
481 }
482 fieldMap["{code}"] = strconv.Itoa(httpResp.StatusCode)
483 fieldMap["{res_headers}"] = TransToString(httpResp.Header)
484 statusCode := httpResp.StatusCode
485
486 if client.debug {
487 log.Printf("Invoke %s %s %d (%v)", ECSRequestMethod, requestURL, statusCode, t1.Sub(t0))
488 }
489
490 if span != nil {
491 ext.HTTPStatusCode.Set(span, uint16(httpResp.StatusCode))
492 }
493
494 defer httpResp.Body.Close()
495 body, err := ioutil.ReadAll(httpResp.Body)
496 fieldMap["{res_body}"] = string(body)
497
498 if err != nil {
499 return GetClientError(err)
500 }
501
502 if client.debug {
503 var prettyJSON bytes.Buffer
504 err = json.Indent(&prettyJSON, body, "", " ")
505 if err != nil {
506 log.Printf("Failed in json.Indent: %v\n", err)
507 } else {
508 log.Printf("JSON body: %s\n", prettyJSON.String())
509 }
510 }
511
512 if statusCode >= 400 && statusCode <= 599 {
513 errorResponse := ErrorResponse{}
514 err = json.Unmarshal(body, &errorResponse)
515 if err != nil {
516 log.Printf("Failed in json.Unmarshal: %v\n", err)
517 }
518 ecsError := &Error{
519 ErrorResponse: errorResponse,
520 StatusCode: statusCode,
521 }
522 return ecsError
523 }
524
525 err = json.Unmarshal(body, response)
526 //log.Printf("%++v", response)
527 if err != nil {
528 return GetClientError(err)
529 }
530
531 return nil
532 }
533
534 // Invoke sends the raw HTTP request for ECS services
535 func (client *Client) InvokeByFlattenMethod(action string, args interface{}, response interface{}) (err error) {
536 if err := client.ensureProperties(); err != nil {
537 return err
538 }
539
540 // log request
541 fieldMap := make(map[string]string)
542 initLogMsg(fieldMap)
543 defer func() {
544 client.printLog(fieldMap, err)
545 }()
281546
282547 //init endpoint
283548 if err := client.initEndpoint(); err != nil {
288553 request.init(client.version, action, client.AccessKeyId, client.securityToken, client.regionID)
289554
290555 query := util.ConvertToQueryValues(request)
291 util.SetQueryValues(args, &query)
556
557 util.SetQueryValueByFlattenMethod(args, &query)
292558
293559 // Sign request
294560 signature := util.CreateSignatureForRequest(ECSRequestMethod, &query, client.AccessKeySecret)
304570
305571 // TODO move to util and add build val flag
306572 httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo)
307
308573 httpReq.Header.Set("User-Agent", httpReq.UserAgent()+" "+client.userAgent)
309574
575 // Set tracer
576 var span opentracing.Span
577 if ok := opentracing.IsGlobalTracerRegistered(); ok && !client.disableTrace {
578 tracer := opentracing.GlobalTracer()
579 var rootCtx opentracing.SpanContext
580
581 if client.span != nil {
582 rootCtx = client.span.Context()
583 }
584
585 span = tracer.StartSpan(
586 "AliyunGO-"+request.Action,
587 opentracing.ChildOf(rootCtx),
588 opentracing.Tag{string(ext.Component), "AliyunGO"},
589 opentracing.Tag{"ActionName", request.Action})
590
591 defer span.Finish()
592 tracer.Inject(
593 span.Context(),
594 opentracing.HTTPHeaders,
595 opentracing.HTTPHeadersCarrier(httpReq.Header))
596 }
597
598 putMsgToMap(fieldMap, httpReq)
310599 t0 := time.Now()
600 fieldMap["{start_time}"] = t0.Format("2006-01-02 15:04:05")
311601 httpResp, err := client.httpClient.Do(httpReq)
312602 t1 := time.Now()
313 if err != nil {
314 return GetClientError(err)
315 }
603 fieldMap["{cost}"] = t1.Sub(t0).String()
604 if err != nil {
605 if span != nil {
606 ext.LogError(span, err)
607 }
608 return GetClientError(err)
609 }
610 fieldMap["{code}"] = strconv.Itoa(httpResp.StatusCode)
611 fieldMap["{res_headers}"] = TransToString(httpResp.Header)
316612 statusCode := httpResp.StatusCode
317613
318614 if client.debug {
319615 log.Printf("Invoke %s %s %d (%v)", ECSRequestMethod, requestURL, statusCode, t1.Sub(t0))
320616 }
321617
618 if span != nil {
619 ext.HTTPStatusCode.Set(span, uint16(httpResp.StatusCode))
620 }
621
322622 defer httpResp.Body.Close()
323623 body, err := ioutil.ReadAll(httpResp.Body)
624 fieldMap["{res_body}"] = string(body)
324625
325626 if err != nil {
326627 return GetClientError(err)
329630 if client.debug {
330631 var prettyJSON bytes.Buffer
331632 err = json.Indent(&prettyJSON, body, "", " ")
332 log.Println(string(prettyJSON.Bytes()))
633 if err != nil {
634 log.Printf("Failed in json.Indent: %v\n", err)
635 }
636 log.Println(prettyJSON.String())
333637 }
334638
335639 if statusCode >= 400 && statusCode <= 599 {
336640 errorResponse := ErrorResponse{}
337641 err = json.Unmarshal(body, &errorResponse)
642 if err != nil {
643 log.Printf("Failed in json.Unmarshal: %v\n", err)
644 }
338645 ecsError := &Error{
339646 ErrorResponse: errorResponse,
340647 StatusCode: statusCode,
352659 }
353660
354661 // Invoke sends the raw HTTP request for ECS services
355 func (client *Client) InvokeByFlattenMethod(action string, args interface{}, response interface{}) error {
662 //改进了一下上面那个方法,可以使用各种Http方法
663 //2017.1.30 增加了一个path参数,用来拓展访问的地址
664 func (client *Client) InvokeByAnyMethod(method, action, path string, args interface{}, response interface{}) (err error) {
356665 if err := client.ensureProperties(); err != nil {
357666 return err
358667 }
359668
669 // log request
670 fieldMap := make(map[string]string)
671 initLogMsg(fieldMap)
672 defer func() {
673 client.printLog(fieldMap, err)
674 }()
675
360676 //init endpoint
361 if err := client.initEndpoint(); err != nil {
362 return err
363 }
364
365 request := Request{}
366 request.init(client.version, action, client.AccessKeyId, client.securityToken, client.regionID)
367
368 query := util.ConvertToQueryValues(request)
369
370 util.SetQueryValueByFlattenMethod(args, &query)
371
372 // Sign request
373 signature := util.CreateSignatureForRequest(ECSRequestMethod, &query, client.AccessKeySecret)
374
375 // Generate the request URL
376 requestURL := client.endpoint + "?" + query.Encode() + "&Signature=" + url.QueryEscape(signature)
377
378 httpReq, err := http.NewRequest(ECSRequestMethod, requestURL, nil)
379
380 if err != nil {
381 return GetClientError(err)
382 }
383
384 // TODO move to util and add build val flag
385 httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo)
386
387 httpReq.Header.Set("User-Agent", httpReq.UserAgent()+" "+client.userAgent)
388
389 t0 := time.Now()
390 httpResp, err := client.httpClient.Do(httpReq)
391 t1 := time.Now()
392 if err != nil {
393 return GetClientError(err)
394 }
395 statusCode := httpResp.StatusCode
396
397 if client.debug {
398 log.Printf("Invoke %s %s %d (%v)", ECSRequestMethod, requestURL, statusCode, t1.Sub(t0))
399 }
400
401 defer httpResp.Body.Close()
402 body, err := ioutil.ReadAll(httpResp.Body)
403
404 if err != nil {
405 return GetClientError(err)
406 }
407
408 if client.debug {
409 var prettyJSON bytes.Buffer
410 err = json.Indent(&prettyJSON, body, "", " ")
411 log.Println(string(prettyJSON.Bytes()))
412 }
413
414 if statusCode >= 400 && statusCode <= 599 {
415 errorResponse := ErrorResponse{}
416 err = json.Unmarshal(body, &errorResponse)
417 ecsError := &Error{
418 ErrorResponse: errorResponse,
419 StatusCode: statusCode,
420 }
421 return ecsError
422 }
423
424 err = json.Unmarshal(body, response)
425 //log.Printf("%++v", response)
426 if err != nil {
427 return GetClientError(err)
428 }
429
430 return nil
431 }
432
433 // Invoke sends the raw HTTP request for ECS services
434 //改进了一下上面那个方法,可以使用各种Http方法
435 //2017.1.30 增加了一个path参数,用来拓展访问的地址
436 func (client *Client) InvokeByAnyMethod(method, action, path string, args interface{}, response interface{}) error {
437 if err := client.ensureProperties(); err != nil {
438 return err
439 }
440
441 //init endpoint
442 if err := client.initEndpoint(); err != nil {
443 return err
444 }
677 //if err := client.initEndpoint(); err != nil {
678 // return err
679 //}
445680
446681 request := Request{}
447682 request.init(client.version, action, client.AccessKeyId, client.securityToken, client.regionID)
455690 // Generate the request URL
456691 var (
457692 httpReq *http.Request
458 err error
459693 )
460694 if method == http.MethodGet {
461695 requestURL := client.endpoint + path + "?" + data.Encode()
475709 httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo)
476710 httpReq.Header.Set("User-Agent", httpReq.Header.Get("User-Agent")+" "+client.userAgent)
477711
712 // Set tracer
713 var span opentracing.Span
714 if ok := opentracing.IsGlobalTracerRegistered(); ok && !client.disableTrace {
715 tracer := opentracing.GlobalTracer()
716 var rootCtx opentracing.SpanContext
717
718 if client.span != nil {
719 rootCtx = client.span.Context()
720 }
721
722 span = tracer.StartSpan(
723 "AliyunGO-"+request.Action,
724 opentracing.ChildOf(rootCtx),
725 opentracing.Tag{string(ext.Component), "AliyunGO"},
726 opentracing.Tag{"ActionName", request.Action})
727
728 defer span.Finish()
729 tracer.Inject(
730 span.Context(),
731 opentracing.HTTPHeaders,
732 opentracing.HTTPHeadersCarrier(httpReq.Header))
733 }
734
735 putMsgToMap(fieldMap, httpReq)
478736 t0 := time.Now()
737 fieldMap["{start_time}"] = t0.Format("2006-01-02 15:04:05")
479738 httpResp, err := client.httpClient.Do(httpReq)
480739 t1 := time.Now()
481 if err != nil {
482 return GetClientError(err)
483 }
740 fieldMap["{cost}"] = t1.Sub(t0).String()
741 if err != nil {
742 if span != nil {
743 ext.LogError(span, err)
744 }
745 return GetClientError(err)
746 }
747 fieldMap["{code}"] = strconv.Itoa(httpResp.StatusCode)
748 fieldMap["{res_headers}"] = TransToString(httpResp.Header)
484749 statusCode := httpResp.StatusCode
485750
486751 if client.debug {
487752 log.Printf("Invoke %s %s %d (%v) %v", ECSRequestMethod, client.endpoint, statusCode, t1.Sub(t0), data.Encode())
488753 }
489754
755 if span != nil {
756 ext.HTTPStatusCode.Set(span, uint16(httpResp.StatusCode))
757 }
758
490759 defer httpResp.Body.Close()
491760 body, err := ioutil.ReadAll(httpResp.Body)
761 fieldMap["{res_body}"] = string(body)
492762
493763 if err != nil {
494764 return GetClientError(err)
497767 if client.debug {
498768 var prettyJSON bytes.Buffer
499769 err = json.Indent(&prettyJSON, body, "", " ")
500 log.Println(string(prettyJSON.Bytes()))
770 log.Println(prettyJSON.String())
501771 }
502772
503773 if statusCode >= 400 && statusCode <= 599 {
547817 StatusCode: 400,
548818 }
549819 }
820
821 func putMsgToMap(fieldMap map[string]string, request *http.Request) {
822 fieldMap["{host}"] = request.Host
823 fieldMap["{method}"] = request.Method
824 fieldMap["{uri}"] = request.URL.RequestURI()
825 fieldMap["{pid}"] = strconv.Itoa(os.Getpid())
826 fieldMap["{version}"] = strings.Split(request.Proto, "/")[1]
827 hostname, _ := os.Hostname()
828 fieldMap["{hostname}"] = hostname
829 fieldMap["{req_headers}"] = TransToString(request.Header)
830 fieldMap["{target}"] = request.URL.Path + request.URL.RawQuery
831 }
00 package common
11
2 import "os"
2 import (
3 "fmt"
4 "github.com/opentracing/opentracing-go"
5 "github.com/stretchr/testify/assert"
6 "github.com/uber/jaeger-client-go"
7 jaegercfg "github.com/uber/jaeger-client-go/config"
8 jaegerlog "github.com/uber/jaeger-client-go/log"
9 "net/http"
10 "os"
11 "testing"
12 )
313
414 var (
515 TestAccessKeyId = os.Getenv("AccessKeyId")
1727 }
1828 return testDebugClient
1929 }
30
31 func TestClient_SetTransport(t *testing.T) {
32 client := NewTestClientForDebug()
33 transport := &myTransport{}
34 client.SetTransport(transport)
35 if client.httpClient.Transport.(*myTransport) != transport {
36 t.Fail()
37 }
38 }
39
40 type myTransport struct{}
41
42 func (m *myTransport) RoundTrip(req *http.Request) (*http.Response, error) {
43 return http.DefaultTransport.RoundTrip(req)
44 }
45
46 func Test_InitClient4RegionalDomain(t *testing.T) {
47
48 var tests = []struct {
49 service string
50 version string
51 endpoint string
52 }{
53 {"ecs", "2014-05-26", "https://ecs-cn-hangzhou.aliyuncs.com"},
54 {"pvtz", "2018-01-01", "https://pvtz.aliyuncs.com"},
55 {"slb", "2014-05-15", "https://slb.aliyuncs.com"},
56 {"vpc", "2016-04-28", "https://vpc.aliyuncs.com"},
57 }
58
59 for _, test := range tests {
60 for _, region := range ValidRegions {
61 if region == Qingdao || region == HangZhouFinance {
62 continue
63 }
64
65 client := &Client{}
66 client.SetDebug(true)
67 client.WithEndpoint(test.endpoint).
68 WithVersion(test.version).
69 WithAccessKeyId(TestAccessKeyId).
70 WithAccessKeySecret(TestAccessKeySecret).
71 WithSecurityToken(TestSecurityToken).
72 WithServiceCode(test.service).
73 WithRegionID(region).
74 InitClient4RegionalDomain()
75
76 if endpoint, ok := CentralDomainServices[test.service]; ok {
77 domain := fmt.Sprintf("https://%s", endpoint)
78 if client.endpoint != domain {
79 t.Fail()
80 }
81 continue
82 }
83
84 if ep, ok := UnitRegions[region]; ok {
85 domain := fmt.Sprintf("https://%s.%s.aliyuncs.com", test.service, ep)
86 if client.endpoint != domain {
87 t.Fail()
88 }
89 continue
90 }
91
92 domain := fmt.Sprintf("https://%s%s.%s.aliyuncs.com", test.service, "-vpc", region)
93 if client.endpoint != domain {
94 t.Fail()
95 }
96 }
97
98 }
99 }
100
101 func Test_InvokeTracer(t *testing.T) {
102 client := NewTestClientForDebug()
103 assert.NotNil(t, client)
104 args := &DescribeEndpointsArgs{
105 Id: Hangzhou,
106 ServiceCode: "ecs",
107 Type: "openAPI",
108 }
109 // not set global tracer
110 resp, err := client.DescribeEndpoints(args)
111 t.Log(resp)
112 assert.Nil(t, err)
113
114 //set global tracer, no root span
115 var cfg = jaegercfg.Configuration{
116 ServiceName: "client test",
117 Sampler: &jaegercfg.SamplerConfig{
118 Type: jaeger.SamplerTypeConst,
119 Param: 1,
120 },
121 Reporter: &jaegercfg.ReporterConfig{
122 LogSpans: true,
123 },
124 }
125 jLogger := jaegerlog.StdLogger
126 tracer, closer, _ := cfg.NewTracer(
127 jaegercfg.Logger(jLogger),
128 )
129 opentracing.InitGlobalTracer(tracer)
130 resp, err = client.DescribeEndpoints(args)
131 t.Log(resp)
132 assert.Nil(t, err)
133
134 // set global tracer, with root span
135 parentSpan := tracer.StartSpan("root")
136 fmt.Println(parentSpan)
137 client.SetSpan(parentSpan)
138 resp, err = client.DescribeEndpoints(args)
139 t.Log(resp)
140 assert.Nil(t, err)
141
142 // set disable trace
143 client.SetDisableTrace(true)
144 client.SetSpan(parentSpan)
145 resp, err = client.DescribeEndpoints(args)
146 t.Log(resp)
147 assert.Nil(t, err)
148
149 parentSpan.Finish()
150 closer.Close()
151 }
33 "encoding/xml"
44 "fmt"
55 "io/ioutil"
6 "log"
67 "os"
78 "strings"
9 "sync"
810 "time"
9 "log"
1011 )
1112
1213 const (
1819 )
1920
2021 var (
21 endpoints = make(map[Region]map[string]string)
22 //endpoints = make(map[Region]map[string]string)
23
24 endpoints = sync.Map{}
2225
2326 SpecailEnpoints = map[Region]map[string]string{
2427 APNorthEast1: {
5053 "slb": "https://slb.eu-central-1.aliyuncs.com",
5154 "rds": "https://rds.eu-central-1.aliyuncs.com",
5255 "vpc": "https://vpc.eu-central-1.aliyuncs.com",
56 },
57 EUWest1: {
58 "ecs": "https://ecs.eu-west-1.aliyuncs.com",
59 "slb": "https://slb.eu-west-1.aliyuncs.com",
60 "rds": "https://rds.eu-west-1.aliyuncs.com",
61 "vpc": "https://vpc.eu-west-1.aliyuncs.com",
5362 },
5463 Zhangjiakou: {
5564 "ecs": "https://ecs.cn-zhangjiakou.aliyuncs.com",
122131 }
123132
124133 func getProductRegionEndpoint(region Region, serviceCode string) string {
125 if sp, ok := endpoints[region]; ok {
126 if endpoint, ok := sp[serviceCode]; ok {
127 return endpoint
128 }
129 }
130
134
135 if sp, ok := endpoints.Load(region); ok {
136 spt, ok := sp.(*sync.Map)
137 if ok {
138 if endp, ok := spt.Load(serviceCode); ok {
139 return endp.(string)
140 }
141 }
142 }
131143 return ""
132144 }
133145
134146 func setProductRegionEndpoint(region Region, serviceCode string, endpoint string) {
135 endpoints[region] = map[string]string{
136 serviceCode: endpoint,
137 }
147 m := sync.Map{}
148 m.Store(serviceCode, endpoint)
149 endpoints.Store(region, &m)
138150 }
139151
140152 func (client *LocationClient) DescribeOpenAPIEndpoint(region Region, serviceCode string) string {
160172 }
161173
162174 if err != nil || endpoint == nil || len(endpoint.Endpoints.Endpoint) <= 0 {
163 log.Printf("aliyungo: can not get endpoint from service, use default. endpoint=[%v], error=[%v]\n",endpoint, err)
175 log.Printf("aliyungo: can not get endpoint from service, use default. endpoint=[%v], error=[%v]\n", endpoint, err)
164176 return ""
165177 }
166178
13351335 <Product><ProductName>Slb</ProductName><DomainName>slb.eu-central-1.aliyuncs.com</DomainName></Product>
13361336 </Products>
13371337 </Endpoint>
1338 <Endpoint name="eu-west-1">
1339 <RegionIds><RegionId>eu-west-1</RegionId></RegionIds>
1340 <Products>
1341 <Product><ProductName>Rds</ProductName><DomainName>rds.eu-west-1.aliyuncs.com</DomainName></Product>
1342 <Product><ProductName>Ecs</ProductName><DomainName>ecs.eu-west-1.aliyuncs.com</DomainName></Product>
1343 <Product><ProductName>Vpc</ProductName><DomainName>vpc.eu-west-1.aliyuncs.com</DomainName></Product>
1344 <Product><ProductName>Kms</ProductName><DomainName>kms.eu-west-1.aliyuncs.com</DomainName></Product>
1345 <Product><ProductName>Cms</ProductName><DomainName>metrics.cn-hangzhou.aliyuncs.com</DomainName></Product>
1346 <Product><ProductName>Slb</ProductName><DomainName>slb.eu-west-1.aliyuncs.com</DomainName></Product>
1347 </Products>
1348 </Endpoint>
13381349 <Endpoint name="cn-zhangjiakou">
13391350 <RegionIds><RegionId>cn-zhangjiakou</RegionId></RegionIds>
13401351 <Products>
0 package common
1
2 import (
3 "encoding/json"
4 "github.com/denverdino/aliyungo/common/utils"
5 "io"
6 "log"
7 "os"
8 "strings"
9 "time"
10 )
11
12 var logChannel string
13 var defaultChannel = "AliyunGO"
14
15 type Logger struct {
16 *log.Logger
17 formatTemplate string
18 isOpen bool
19 lastLogMsg string
20 }
21
22 var defaultLoggerTemplate = `{time} {channel}: "{method} {uri} HTTP/{version}" {code} {cost} {hostname}`
23 var loggerParam = []string{"{time}", "{start_time}", "{ts}", "{channel}", "{pid}", "{host}", "{method}", "{uri}", "{version}", "{target}", "{hostname}", "{code}", "{error}", "{req_headers}", "{res_body}", "{res_headers}", "{cost}"}
24
25 func initLogMsg(fieldMap map[string]string) {
26 for _, value := range loggerParam {
27 fieldMap[value] = ""
28 }
29 }
30
31 func (client *Client) SetLogger(level string, channel string, out io.Writer, template string) {
32 if level == "" {
33 level = "info"
34 }
35
36 logChannel = "AliyunGO"
37 if channel != "" {
38 logChannel = channel
39 }
40 log := log.New(out, "["+strings.ToUpper(level)+"]", log.Lshortfile)
41 if template == "" {
42 template = defaultLoggerTemplate
43 }
44
45 client.logger = &Logger{
46 Logger: log,
47 formatTemplate: template,
48 isOpen: true,
49 }
50 }
51
52 func (client *Client) GetLogger() *Logger {
53 return client.logger
54 }
55
56 func (client *Client) GetLoggerMsg() string {
57 if client.logger == nil {
58 client.SetLogger("", "", os.Stdout, "")
59 }
60 return client.logger.lastLogMsg
61 }
62
63 func (client *Client) OpenLogger() {
64 if client.logger == nil {
65 client.SetLogger("", "", os.Stdout, "")
66 }
67 client.logger.isOpen = true
68 }
69
70 func (client *Client) CloseLogger() {
71 if client.logger != nil {
72 client.logger.isOpen = false
73 }
74 }
75
76 func (client *Client) SetTemplate(template string) {
77 if client.logger == nil {
78 client.SetLogger("", "", os.Stdout, "")
79 }
80 client.logger.formatTemplate = template
81 }
82
83 func (client *Client) GetTemplate() string {
84 if client.logger == nil {
85 client.SetLogger("", "", os.Stdout, "")
86 }
87 return client.logger.formatTemplate
88 }
89
90 func TransToString(object interface{}) string {
91 byt, err := json.Marshal(object)
92 if err != nil {
93 return ""
94 }
95 return string(byt)
96 }
97
98 func (client *Client) printLog(fieldMap map[string]string, err error) {
99 if err != nil {
100 fieldMap["{error}"] = err.Error()
101 }
102 fieldMap["{time}"] = time.Now().Format("2006-01-02 15:04:05")
103 fieldMap["{ts}"] = utils.GetTimeInFormatISO8601()
104 fieldMap["{channel}"] = logChannel
105 if client.logger != nil {
106 logMsg := client.logger.formatTemplate
107 for key, value := range fieldMap {
108 logMsg = strings.Replace(logMsg, key, value, -1)
109 }
110 client.logger.lastLogMsg = logMsg
111 if client.logger.isOpen == true {
112 client.logger.Output(2, logMsg)
113 }
114 }
115 }
0 package common
1
2 import (
3 "bytes"
4 "github.com/stretchr/testify/assert"
5 "testing"
6 )
7
8 func Test_Client_Logger(t *testing.T) {
9 client := NewTestClientForDebug()
10 assert.NotNil(t, client)
11 args := &DescribeEndpointsArgs{
12 Id: Hangzhou,
13 ServiceCode: "ecs",
14 Type: "openAPI",
15 }
16 // without logger
17 resp, err := client.DescribeEndpoints(args)
18 t.Log(resp)
19 assert.Nil(t, err)
20
21 // with logger
22 wr := new(bytes.Buffer)
23 assert.Nil(t, err)
24 template := `{time} {channel}: {method} {host} {uri} HTTP/{version} {code} {cost} {hostname} {req_headers} {error} {res_body}`
25 client.SetLogger("", "openapi", wr, template)
26 resp, err = client.DescribeEndpoints(args)
27 t.Log(wr.String())
28 t.Log(resp)
29 assert.Nil(t, err)
30 }
1313 Zhangjiakou = Region("cn-zhangjiakou")
1414 Huhehaote = Region("cn-huhehaote")
1515
16 Chengdu = Region("cn-chengdu")
17
1618 APSouthEast1 = Region("ap-southeast-1")
1719 APNorthEast1 = Region("ap-northeast-1")
1820 APSouthEast2 = Region("ap-southeast-2")
2729 MEEast1 = Region("me-east-1")
2830
2931 EUCentral1 = Region("eu-central-1")
32 EUWest1 = Region("eu-west-1")
3033
3134 ShenZhenFinance = Region("cn-shenzhen-finance-1")
3235 ShanghaiFinance = Region("cn-shanghai-finance-1")
36 HangZhouFinance = Region("cn-hangzhou-finance-1")
37
38 CNNorth2Gov1 = Region("cn-north-2-gov-1")
39 RUSWest1 = Region("rus-west-1")
3340 )
3441
3542 var ValidRegions = []Region{
3845 APNorthEast1, APSouthEast1, APSouthEast2, APSouthEast3, APSouthEast5,
3946 APSouth1,
4047 MEEast1,
41 EUCentral1,
42 ShenZhenFinance, ShanghaiFinance,
48 EUCentral1, EUWest1,
49 ShenZhenFinance, ShanghaiFinance, HangZhouFinance, CNNorth2Gov1,
4350 }
4451
4552 // IsValidRegion checks if r is an Ali supported region.
1212 PrePaid = InstanceChargeType("PrePaid")
1313 PostPaid = InstanceChargeType("PostPaid")
1414 )
15
16 var SpecialDeployedProducts = map[string]map[Region]interface{}{
17 "vpc": {
18 Hangzhou: Hangzhou,
19 Shenzhen: Shenzhen,
20 APSouthEast1: APSouthEast1,
21 USWest1: USWest1,
22 USEast1: USEast1,
23 Chengdu: Chengdu,
24 Zhangjiakou: Zhangjiakou,
25 Huhehaote: Huhehaote,
26 APSouthEast3: APSouthEast3,
27 EUCentral1: EUCentral1,
28 EUWest1: EUWest1,
29 APSouth1: APSouth1,
30 APNorthEast1: APNorthEast1,
31 APSouthEast5: APSouthEast5,
32 APSouthEast2: APSouthEast2,
33 MEEast1: MEEast1,
34 CNNorth2Gov1: CNNorth2Gov1,
35 },
36 }
37
38 var CentralDomainServices = map[string]string{
39 "pvtz": "pvtz.vpc-proxy.aliyuncs.com",
40 }
41
42 var RegionalDomainServices = []string{
43 "ecs",
44 "vpc",
45 "slb",
46 }
47
48 // Unit-Domain of central product
49 var UnitRegions = map[Region]interface{}{
50 Hangzhou: Hangzhou,
51 Shenzhen: Shenzhen,
52 APSouthEast1: APSouthEast1,
53 USWest1: USWest1,
54 USEast1: USEast1,
55 Chengdu: Chengdu,
56 Zhangjiakou: Zhangjiakou,
57 Huhehaote: Huhehaote,
58 APSouthEast3: APSouthEast3,
59 EUCentral1: EUCentral1,
60 EUWest1: EUWest1,
61 APSouth1: APSouth1,
62 APNorthEast1: APNorthEast1,
63 APSouthEast5: APSouthEast5,
64 APSouthEast2: APSouthEast2,
65 CNNorth2Gov1: CNNorth2Gov1,
66 //MEEast1: MEEast1,
67 //RUSWest1: RUSWest1,
68 //Beijing: Beijing,
69 //Shanghai: Shanghai,
70 //Hongkong: Hongkong,
71 //ShanghaiFinance: ShanghaiFinance,
72 //ShenZhenFinance: ShenZhenFinance,
73 HangZhouFinance: Hangzhou,
74 }
1575
1676 type DescribeEndpointArgs struct {
1777 Id Region
0 package utils
1
2 import "time"
3
4 func GetTimeInFormatISO8601() (timeStr string) {
5 gmt := time.FixedZone("GMT", 0)
6
7 return time.Now().In(gmt).Format("2006-01-02T15:04:05Z")
8 }
3131 debug bool
3232 userAgent string
3333 httpClient *http.Client
34 sourceIp string
35 secureTransport string
3436 }
3537
3638 type PaginationResult struct {
7375 // SetUserAgent sets user agent to log the request/response message
7476 func (client *Client) SetUserAgent(userAgent string) {
7577 client.userAgent = userAgent
78 }
79
80 // SetEndpoint sets customer endpoint
81 func (client *Client) SetEndpoint(endpoint string) {
82 client.endpoint = endpoint
83 }
84
85 // SetTransport sets transport to the http client
86 func (client *Client) SetTransport(transport http.RoundTripper) {
87 if client.httpClient == nil {
88 client.httpClient = &http.Client{}
89 }
90 client.httpClient.Transport = transport
91 }
92
93 // SetSourceIp set the source ip
94 func (client *Client) SetSourceIp(sourceIp string) {
95 client.sourceIp = sourceIp
96 }
97
98 // SetSecureTransport set the secure transport
99 func (client *Client) SetSecureTransport(secureTransport string) {
100 client.secureTransport = secureTransport
76101 }
77102
78103 type Request struct {
129154 if contentMD5 != "" {
130155 httpReq.Header.Set("Content-MD5", contentMD5)
131156 }
157
158 if (client.secureTransport == "false" || client.secureTransport == "true") && client.sourceIp != "" {
159 httpReq.Header["x-acs-source-ip"] = []string{client.sourceIp}
160 httpReq.Header["x-acs-secure-transport"] = []string{client.secureTransport}
161 }
162
132163 // TODO move to util and add build val flag
133164 httpReq.Header.Set("Date", util.GetGMTime())
134165 httpReq.Header.Set("Accept", "application/json")
172203
173204 if client.debug {
174205 var prettyJSON bytes.Buffer
175 err = json.Indent(&prettyJSON, body, "", " ")
176 log.Println(string(prettyJSON.Bytes()))
206 _ = json.Indent(&prettyJSON, body, "", " ")
207 log.Println(prettyJSON.String())
177208 }
178209
179210 if statusCode >= 400 && statusCode <= 599 {
180211 errorResponse := common.ErrorResponse{}
181 err = json.Unmarshal(body, &errorResponse)
212 _ = json.Unmarshal(body, &errorResponse)
182213 ecsError := &common.Error{
183214 ErrorResponse: errorResponse,
184215 StatusCode: statusCode,
186217 return ecsError
187218 }
188219
189 if response != nil {
220 if response != nil && len(body) > 0 {
190221 err = json.Unmarshal(body, response)
191222 //log.Printf("%++v", response)
192223 if err != nil {
1010 "fmt"
1111
1212 "encoding/json"
13
1314 "github.com/denverdino/aliyungo/common"
1415 "github.com/denverdino/aliyungo/ecs"
1516 )
2627 DeleteFailed = ClusterState("deleteFailed")
2728 Deleted = ClusterState("deleted")
2829 InActive = ClusterState("inactive")
30
31 ClusterTypeKubernetes = "Kubernetes"
32 ClusterTypeManagedKubernetes = "ManagedKubernetes"
33
34 ClusterTypeServerlessKubernetes = "Ask"
35
36 ProfileServerlessKubernetes = "Serverless"
2937 )
38
39 var NodeStableClusterState = []ClusterState{Running, Updating, Failed, DeleteFailed, Deleted, InActive}
40
41 var NodeUnstableClusterState = []ClusterState{Initial, Scaling, Deleting}
3042
3143 type NodeStatus struct {
3244 Health int64 `json:"health"`
5971 NodeStatus string `json:"node_status"`
6072 DockerVersion string `json:"docker_version"`
6173 ClusterType string `json:"cluster_type"`
74 Profile string `json:"profile"`
6275 }
6376
6477 func (client *Client) DescribeClusters(nameFilter string) (clusters []ClusterType, err error) {
91104 ECSImageID string `json:"ecs_image_id,omitempty"`
92105 IOOptimized ecs.IoOptimized `json:"io_optimized"`
93106 ReleaseEipFlag bool `json:"release_eip_flag"`
94 }
95
96 type ClusterCreationResponse struct {
107 NeedSLB bool `json:"need_slb"`
108 }
109
110 type ClusterCommonResponse struct {
97111 Response
98 ClusterID string `json:"cluster_id"`
99 }
100
101 func (client *Client) CreateCluster(region common.Region, args *ClusterCreationArgs) (cluster ClusterCreationResponse, err error) {
112 ClusterID string `json:"cluster_id"`
113 Token string `json:"token,omitempty"`
114 TaskId string `json:"task_id,omitempty"`
115 InstanceId string `json:"instanceId"`
116 }
117
118 //Deprecated
119 func (client *Client) CreateCluster(region common.Region, args *ClusterCreationArgs) (cluster ClusterCommonResponse, err error) {
102120 err = client.Invoke(region, http.MethodPost, "/clusters", nil, args, &cluster)
103121 return
104122 }
126144 SNatEntry bool `json:"SNatEntry,omitempty"`
127145 }
128146
147 // Deprecated
129148 type KubernetesCreationArgs struct {
130 DisableRollback bool `json:"disable_rollback"`
131 Name string `json:"name"`
132 TimeoutMins int64 `json:"timeout_mins"`
133 ZoneId string `json:"zoneid,omitempty"`
134 VPCID string `json:"vpcid,omitempty"`
135 VSwitchId string `json:"vswitchid,omitempty"`
136 ContainerCIDR string `json:"container_cidr,omitempty"`
137 ServiceCIDR string `json:"service_cidr,omitempty"`
149 DisableRollback bool `json:"disable_rollback"`
150 Name string `json:"name"`
151 TimeoutMins int64 `json:"timeout_mins"`
152 ZoneId string `json:"zoneid,omitempty"`
153 VPCID string `json:"vpcid,omitempty"`
154 RegionId string `json:"region_id,omitempty"`
155 VSwitchId string `json:"vswitchid,omitempty"`
156 VSwitchIds []string `json:"vswitch_ids,omitempty"`
157 ImageId string `json:"image_id"`
158 ContainerCIDR string `json:"container_cidr,omitempty"`
159 ServiceCIDR string `json:"service_cidr,omitempty"`
160
138161 MasterInstanceType string `json:"master_instance_type,omitempty"`
139162 MasterSystemDiskSize int64 `json:"master_system_disk_size,omitempty"`
140163 MasterSystemDiskCategory ecs.DiskCategory `json:"master_system_disk_category,omitempty"`
164
165 MasterInstanceChargeType string `json:"master_instance_charge_type"`
166 MasterPeriodUnit string `json:"master_period_unit"`
167 MasterPeriod int `json:"master_period"`
168 MasterAutoRenew bool `json:"master_auto_renew"`
169 MasterAutoRenewPeriod int `json:"master_auto_renew_period"`
170
141171 WorkerInstanceType string `json:"worker_instance_type,omitempty"`
172 WorkerInstanceTypes []string `json:"worker_instance_types,omitempty"`
142173 WorkerSystemDiskSize int64 `json:"worker_system_disk_size,omitempty"`
143174 WorkerSystemDiskCategory ecs.DiskCategory `json:"worker_system_disk_category,omitempty"`
144 WorkerDataDisk bool `json:"worker_data_disk,omitempty"`
145 WorkerDataDiskCategory string `json:"worker_data_disk_category,omitempty"`
175 WorkerDataDisk bool `json:"worker_data_disk"`
176 WorkerDataDiskCategory ecs.DiskCategory `json:"worker_data_disk_category,omitempty"`
146177 WorkerDataDiskSize int64 `json:"worker_data_disk_size,omitempty"`
147 LoginPassword string `json:"login_password,omitempty"`
148 KeyPair string `json:"key_pair,omitempty"`
149 NumOfNodes int64 `json:"num_of_nodes,omitempty"`
150 SNatEntry bool `json:"snat_entry,omitempty"`
151 SSHFlags bool `json:"ssh_flags,omitempty"`
152 CloudMonitorFlags bool `json:"cloud_monitor_flags,omitempty"`
178
179 WorkerInstanceChargeType string `json:"worker_instance_charge_type"`
180 WorkerPeriodUnit string `json:"worker_period_unit"`
181 WorkerPeriod int `json:"worker_period"`
182 WorkerAutoRenew bool `json:"worker_auto_renew"`
183 WorkerAutoRenewPeriod int `json:"worker_auto_renew_period"`
184
185 LoginPassword string `json:"login_password,omitempty"`
186 KeyPair string `json:"key_pair,omitempty"`
187 UserCA string `json:"user_ca,omitempty"`
188 NumOfNodes int64 `json:"num_of_nodes,omitempty"`
189 SNatEntry bool `json:"snat_entry"`
190 SSHFlags bool `json:"ssh_flags"`
191 CloudMonitorFlags bool `json:"cloud_monitor_flags"`
192 NodeCIDRMask string `json:"node_cidr_mask,omitempty"`
193 LoggingType string `json:"logging_type,omitempty"`
194 SLSProjectName string `json:"sls_project_name,omitempty"`
195 PublicSLB bool `json:"public_slb"`
153196
154197 ClusterType string `json:"cluster_type"`
155198 Network string `json:"network,omitempty"`
158201 StackParams KubernetesStackArgs `json:"stack_params,omitempty"`
159202 }
160203
204 // Deprecated
161205 type KubernetesMultiAZCreationArgs struct {
162 DisableRollback bool `json:"disable_rollback"`
163 Name string `json:"name"`
164 TimeoutMins int64 `json:"timeout_mins"`
165 ClusterType string `json:"cluster_type"`
166 MultiAZ bool `json:"multi_az,omitempty"`
167 VPCID string `json:"vpcid,omitempty"`
168 ContainerCIDR string `json:"container_cidr"`
169 ServiceCIDR string `json:"service_cidr"`
170 VSwitchIdA string `json:"vswitch_id_a,omitempty"`
171 VSwitchIdB string `json:"vswitch_id_b,omitempty"`
172 VSwitchIdC string `json:"vswitch_id_c,omitempty"`
206 DisableRollback bool `json:"disable_rollback"`
207 Name string `json:"name"`
208 TimeoutMins int64 `json:"timeout_mins"`
209 ClusterType string `json:"cluster_type"`
210 MultiAZ bool `json:"multi_az"`
211 VPCID string `json:"vpcid,omitempty"`
212 ImageId string `json:"image_id"`
213 ContainerCIDR string `json:"container_cidr"`
214 ServiceCIDR string `json:"service_cidr"`
215 VSwitchIdA string `json:"vswitch_id_a,omitempty"`
216 VSwitchIdB string `json:"vswitch_id_b,omitempty"`
217 VSwitchIdC string `json:"vswitch_id_c,omitempty"`
218
173219 MasterInstanceTypeA string `json:"master_instance_type_a,omitempty"`
174220 MasterInstanceTypeB string `json:"master_instance_type_b,omitempty"`
175221 MasterInstanceTypeC string `json:"master_instance_type_c,omitempty"`
176222 MasterSystemDiskCategory ecs.DiskCategory `json:"master_system_disk_category"`
177223 MasterSystemDiskSize int64 `json:"master_system_disk_size"`
224
225 MasterInstanceChargeType string `json:"master_instance_charge_type"`
226 MasterPeriodUnit string `json:"master_period_unit"`
227 MasterPeriod int `json:"master_period"`
228 MasterAutoRenew bool `json:"master_auto_renew"`
229 MasterAutoRenewPeriod int `json:"master_auto_renew_period"`
230
178231 WorkerInstanceTypeA string `json:"worker_instance_type_a,omitempty"`
179232 WorkerInstanceTypeB string `json:"worker_instance_type_b,omitempty"`
180233 WorkerInstanceTypeC string `json:"worker_instance_type_c,omitempty"`
181234 WorkerSystemDiskCategory ecs.DiskCategory `json:"worker_system_disk_category"`
182235 WorkerSystemDiskSize int64 `json:"worker_system_disk_size"`
183236 WorkerDataDisk bool `json:"worker_data_disk"`
184 WorkerDataDiskCategory string `json:"worker_data_disk_category"`
237 WorkerDataDiskCategory ecs.DiskCategory `json:"worker_data_disk_category"`
185238 WorkerDataDiskSize int64 `json:"worker_data_disk_size"`
186 NumOfNodesA int64 `json:"num_of_nodes_a"`
187 NumOfNodesB int64 `json:"num_of_nodes_b"`
188 NumOfNodesC int64 `json:"num_of_nodes_c"`
189 LoginPassword string `json:"login_password,omitempty"`
190 KeyPair string `json:"key_pair,omitempty"`
191 SSHFlags bool `json:"ssh_flags"`
192 CloudMonitorFlags bool `json:"cloud_monitor_flags"`
239
240 WorkerInstanceChargeType string `json:"worker_instance_charge_type"`
241 WorkerPeriodUnit string `json:"worker_period_unit"`
242 WorkerPeriod int `json:"worker_period"`
243 WorkerAutoRenew bool `json:"worker_auto_renew"`
244 WorkerAutoRenewPeriod int `json:"worker_auto_renew_period"`
245
246 NumOfNodesA int64 `json:"num_of_nodes_a"`
247 NumOfNodesB int64 `json:"num_of_nodes_b"`
248 NumOfNodesC int64 `json:"num_of_nodes_c"`
249 LoginPassword string `json:"login_password,omitempty"`
250 KeyPair string `json:"key_pair,omitempty"`
251 UserCA string `json:"user_ca,omitempty"`
252 SSHFlags bool `json:"ssh_flags"`
253 CloudMonitorFlags bool `json:"cloud_monitor_flags"`
254 NodeCIDRMask string `json:"node_cidr_mask,omitempty"`
255 LoggingType string `json:"logging_type,omitempty"`
256 SLSProjectName string `json:"sls_project_name,omitempty"`
257 PublicSLB bool `json:"public_slb"`
193258
194259 KubernetesVersion string `json:"kubernetes_version,omitempty"`
195260 Network string `json:"network,omitempty"`
196261 }
197262
198 func (client *Client) CreateKubernetesMultiAZCluster(region common.Region, args *KubernetesMultiAZCreationArgs) (cluster ClusterCreationResponse, err error) {
263 // Deprecated
264 func (client *Client) CreateKubernetesMultiAZCluster(region common.Region, args *KubernetesMultiAZCreationArgs) (cluster ClusterCommonResponse, err error) {
199265 err = client.Invoke(region, http.MethodPost, "/clusters", nil, args, &cluster)
200266 return
201267 }
202268
203 func (client *Client) CreateKubernetesCluster(region common.Region, args *KubernetesCreationArgs) (cluster ClusterCreationResponse, err error) {
269 // Deprecated
270 func (client *Client) CreateKubernetesCluster(region common.Region, args *KubernetesCreationArgs) (cluster ClusterCommonResponse, err error) {
204271 err = client.Invoke(region, http.MethodPost, "/clusters", nil, args, &cluster)
205272 return
206273 }
213280 SubClass string `json:"SubClass"`
214281 }
215282
283 // deprecated
216284 type KubernetesClusterParameter struct {
217 ServiceCidr string `json:"ServiceCIDR"`
218 ContainerCidr string `json:"ContainerCIDR"`
219 DockerVersion string `json:"DockerVersion"`
220 EtcdVersion string `json:"EtcdVersion"`
221 KubernetesVersion string `json:"KubernetesVersion"`
222 VPCID string `json:"VpcId"`
223 KeyPair string `json:"KeyPair"`
224 MasterSystemDiskCategory string `json:"MasterSystemDiskCategory"`
225 MasterSystemDiskSize string `json:"MasterSystemDiskSize"`
226 WorkerSystemDiskCategory string `json:"WorkerSystemDiskCategory"`
227 WorkerSystemDiskSize string `json:"WorkerSystemDiskSize"`
228 ZoneId string `json:"ZoneId"`
285 ServiceCidr string `json:"ServiceCIDR"`
286 ContainerCidr string `json:"ContainerCIDR"`
287 DockerVersion string `json:"DockerVersion"`
288 EtcdVersion string `json:"EtcdVersion"`
289 KubernetesVersion string `json:"KubernetesVersion"`
290 VPCID string `json:"VpcId"`
291 ImageId string `json:"ImageId"`
292 KeyPair string `json:"KeyPair"`
293
294 MasterSystemDiskCategory ecs.DiskCategory `json:"MasterSystemDiskCategory"`
295 MasterSystemDiskSize string `json:"MasterSystemDiskSize"`
296 MasterImageId string `json:"MasterImageId"`
297
298 MasterInstanceChargeType string `json:"MasterInstanceChargeType"`
299 MasterPeriodUnit string `json:"MasterPeriodUnit"`
300 MasterPeriod string `json:"MasterPeriod"`
301 MasterAutoRenew *bool
302 RawMasterAutoRenew string `json:"MasterAutoRenew"`
303 MasterAutoRenewPeriod string `json:"MasterAutoRenewPeriod"`
304
305 WorkerSystemDiskCategory ecs.DiskCategory `json:"WorkerSystemDiskCategory"`
306 WorkerSystemDiskSize string `json:"WorkerSystemDiskSize"`
307 WorkerImageId string `json:"WorkerImageId"`
308 WorkerDataDisk *bool
309 RawWorkerDataDisk string `json:"WorkerDataDisk"`
310 WorkerDataDiskCategory ecs.DiskCategory `json:"WorkerDataDiskCategory"`
311 WorkerDataDiskSize string `json:"WorkerDataDiskSize"`
312
313 WorkerInstanceChargeType string `json:"WorkerInstanceChargeType"`
314 WorkerPeriodUnit string `json:"WorkerPeriodUnit"`
315 WorkerPeriod string `json:"WorkerPeriod"`
316 WorkerAutoRenew *bool
317 RawWorkerAutoRenew string `json:"WorkerAutoRenew"`
318 WorkerAutoRenewPeriod string `json:"WorkerAutoRenewPeriod"`
319
320 ZoneId string `json:"ZoneId"`
321 NodeCIDRMask string `json:"NodeCIDRMask"`
322 LoggingType string `json:"LoggingType"`
323 SLSProjectName string `json:"SLSProjectName"`
324 PublicSLB *bool
325 RawPublicSLB string `json:"PublicSLB"`
229326
230327 // Single AZ
231328 MasterInstanceType string `json:"MasterInstanceType"`
248345 VSwitchIdC string `json:"VSwitchIdC"`
249346 }
250347
348 // Deprecated
251349 type KubernetesCluster struct {
252350 ClusterType
253351
277375 Parameters KubernetesClusterParameter `json:"parameters"`
278376 }
279377
378 // Deprecated
280379 func (client *Client) DescribeKubernetesCluster(id string) (cluster KubernetesCluster, err error) {
281380 err = client.Invoke("", http.MethodGet, "/clusters/"+id, nil, nil, &cluster)
282381 if err != nil {
283382 return cluster, err
284383 }
384
285385 var metaData KubernetesClusterMetaData
286386 err = json.Unmarshal([]byte(cluster.RawMetaData), &metaData)
387 if err != nil {
388 return cluster, err
389 }
287390 cluster.MetaData = metaData
288391 cluster.RawMetaData = ""
289 return
290 }
291
392
393 return
394 }
395
396 // Deprecated
292397 type ClusterResizeArgs struct {
293398 Size int64 `json:"size"`
294399 InstanceType string `json:"instance_type"`
303408 Name string `json:"name"`
304409 }
305410
411 // Deprecated
306412 func (client *Client) ResizeCluster(clusterID string, args *ClusterResizeArgs) error {
307413 return client.Invoke("", http.MethodPut, "/clusters/"+clusterID, nil, args, nil)
308414 }
309415
310416 // deprecated
311 // use ResizeKubernetesCluster instead
417 // use ScaleKubernetesCluster instead
312418 func (client *Client) ResizeKubernetes(clusterID string, args *KubernetesCreationArgs) error {
313419 return client.Invoke("", http.MethodPut, "/clusters/"+clusterID, nil, args, nil)
314420 }
315421
422 // Deprecated
316423 type KubernetesClusterResizeArgs struct {
317424 DisableRollback bool `json:"disable_rollback"`
318425 TimeoutMins int64 `json:"timeout_mins"`
319426 LoginPassword string `json:"login_password,omitempty"`
320427
321428 // Single AZ
322 WorkerInstanceType string `json:"worker_instance_type"`
323 NumOfNodes int64 `json:"num_of_nodes"`
429 WorkerInstanceType string `json:"worker_instance_type"`
430 WorkerInstanceTypes []string `json:"worker_instance_types"`
431 NumOfNodes int64 `json:"num_of_nodes"`
324432
325433 // Multi AZ
326434 WorkerInstanceTypeA string `json:"worker_instance_type_a"`
331439 NumOfNodesC int64 `json:"num_of_nodes_c"`
332440 }
333441
442 // deprecated
443 // use ScaleKubernetesCluster instead
334444 func (client *Client) ResizeKubernetesCluster(clusterID string, args *KubernetesClusterResizeArgs) error {
335445 return client.Invoke("", http.MethodPut, "/clusters/"+clusterID, nil, args, nil)
336446 }
337447
448 // Deprecated
449 type KubernetesClusterScaleArgs struct {
450 LoginPassword string `json:"login_password,omitempty"`
451 KeyPair string `json:"key_pair,omitempty"`
452 WorkerInstanceTypes []string `json:"worker_instance_types"`
453 WorkerSystemDiskSize int64 `json:"worker_system_disk_size"`
454 WorkerSystemDiskCategory ecs.DiskCategory `json:"worker_system_disk_category"`
455 WorkerDataDisk bool `json:"worker_data_disk"`
456 Count int `json:"count"`
457
458 // Edge worker related args
459 IsEdgeWorker bool `json:"is_edge_worker"`
460 EnsRegionId string `json:"ens_region_id"`
461 EnsInternetChargeType string `json:"ens_internet_charge_type"`
462
463 //data disk
464 WorkerDataDiskCategory ecs.DiskCategory `json:"worker_data_disk_category"`
465 WorkerDataDiskSize int64 `json:"worker_data_disk_size"`
466 WorkerDataDiskEncrypted string `json:"worker_data_disk_encrypted"`
467 WorkerDataDiskKMSKeyId string `json:"worker_data_disk_kms_key_id"`
468 }
469
470 // Deprecated
471 func (client *Client) ScaleKubernetesCluster(clusterID string, args *KubernetesClusterScaleArgs) error {
472 return client.Invoke("", http.MethodPost, "/api/v2/clusters/"+clusterID, nil, args, nil)
473 }
474
475 // Deprecated
338476 func (client *Client) ModifyClusterName(clusterID, clusterName string) error {
339477 return client.Invoke("", http.MethodPost, "/clusters/"+clusterID+"/name/"+clusterName, nil, nil, nil)
340478 }
341479
480 // Deprecated
342481 func (client *Client) DeleteCluster(clusterID string) error {
343482 return client.Invoke("", http.MethodDelete, "/clusters/"+clusterID, nil, nil, nil)
344483 }
354493 return
355494 }
356495
496 type ClusterEndpoints struct {
497 ApiServerEndpoint string `json:"api_server_endpoint"`
498 DashboardEndpoint string `json:"dashboard_endpoint"`
499 MiranaEndpoint string `json:"mirana_endpoint"`
500 ReverseTunnelEndpoint string `json:"reverse_tunnel_endpoint"`
501 IntranetApiServerEndpoint string `json:"intranet_api_server_endpoint"`
502 }
503
504 func (client *Client) GetClusterEndpoints(id string) (clusterEndpoints ClusterEndpoints, err error) {
505 err = client.Invoke("", http.MethodGet, "/clusters/"+id+"/endpoints", nil, nil, &clusterEndpoints)
506 return
507 }
508
357509 type ClusterConfig struct {
358510 Config string `json:"config"`
359511 }
360512
513 // deprecated
514 // Please use new api DescribeClusterUserConfig
361515 func (client *Client) GetClusterConfig(id string) (config ClusterConfig, err error) {
362516 err = client.Invoke("", http.MethodGet, "/k8s/"+id+"/user_config", nil, nil, &config)
363517 return
374528 HostName string `json:"host_name"`
375529 ImageId string `json:"image_id"`
376530 InstanceId string `json:"instance_id"`
531 NodeName string `json:"node_name"`
377532 }
378533
379534 type GetKubernetesClusterNodesResponse struct {
382537 Nodes []KubernetesNodeType `json:"nodes"`
383538 }
384539
385 func (client *Client) GetKubernetesClusterNodes(id string, pagination common.Pagination) (nodes []KubernetesNodeType, paginationResult *PaginationResult, err error) {
540 // GetKubernetesClusterNodes is used to get cluster nodes or node pool nodes
541 func (client *Client) GetKubernetesClusterNodes(id string, pagination common.Pagination, nodepoolId string) (nodes []KubernetesNodeType, paginationResult *PaginationResult, err error) {
386542 response := &GetKubernetesClusterNodesResponse{}
387 err = client.Invoke("", http.MethodGet, "/clusters/"+id+"/nodes?pageNumber="+strconv.Itoa(pagination.PageNumber)+"&pageSize="+strconv.Itoa(pagination.PageSize), nil, nil, &response)
543 if nodepoolId != "" {
544 err = client.Invoke("", http.MethodGet, "/clusters/"+id+"/nodes?nodepool_id="+nodepoolId+"&pageNumber="+strconv.Itoa(pagination.PageNumber)+"&pageSize="+strconv.Itoa(pagination.PageSize), nil, nil, &response)
545 } else {
546 err = client.Invoke("", http.MethodGet, "/clusters/"+id+"/nodes?pageNumber="+strconv.Itoa(pagination.PageNumber)+"&pageSize="+strconv.Itoa(pagination.PageSize), nil, nil, &response)
547 }
388548 if err != nil {
389549 return nil, nil, err
390550 }
394554
395555 const ClusterDefaultTimeout = 300
396556 const DefaultWaitForInterval = 10
397 const DefaultPreSleepTime = 240
557 const DefaultPreCheckSleepTime = 20
558 const DefaultPreSleepTime = 220
398559
399560 // WaitForCluster waits for instance to given status
400561 // when instance.NotFound wait until timeout
402563 if timeout <= 0 {
403564 timeout = ClusterDefaultTimeout
404565 }
566
567 // Sleep 20 second to check cluster creating or failed
568 sleep := math.Min(float64(timeout), float64(DefaultPreCheckSleepTime))
569 time.Sleep(time.Duration(sleep) * time.Second)
570
405571 cluster, err := client.DescribeCluster(clusterId)
406572 if err != nil {
407573 return err
574 } else if cluster.State == Failed {
575 return fmt.Errorf("Waitting for cluster %s %s failed. Looking the specified reason in the web console.", clusterId, status)
408576 } else if cluster.State == status {
409577 //TODO
410578 return nil
411579 }
580
412581 // Create or Reset cluster usually cost at least 4 min, so there will sleep a long time before polling
413 sleep := math.Min(float64(timeout), float64(DefaultPreSleepTime))
582 sleep = math.Min(float64(timeout), float64(DefaultPreSleepTime))
414583 time.Sleep(time.Duration(sleep) * time.Second)
415584
416585 for {
4141 }
4242
4343 for _, cluster := range clusters {
44 if cluster.ClusterType != "Kubernetes" {
44 if cluster.ClusterType != "Kubernetes" && cluster.ClusterType != "ManagedKubernetes" {
4545 continue
4646 }
4747 t.Logf("Cluster: %++v", cluster)
5050 t.Errorf("Failed to DescribeCluster: %v", err)
5151 }
5252 t.Logf("Cluster Describe: %++v", c)
53 t.Logf("Cluster KeyPair %v", c.Parameters.KeyPair)
5453
5554 if c.MetaData.MultiAZ || c.MetaData.SubClass == "3az" {
5655 t.Logf("%v is a MultiAZ kubernetes cluster", c.ClusterID)
57 t.Logf("Cluster VSWA ID %v", c.Parameters.VSwitchIdA)
58 t.Logf("Cluster VSWB ID %v", c.Parameters.VSwitchIdB)
59 t.Logf("Cluster VSWC ID %v", c.Parameters.VSwitchIdC)
60 t.Logf("Cluster MasterInstanceTypeA %v", c.Parameters.MasterInstanceTypeA)
61 t.Logf("Cluster MasterInstanceTypeB %v", c.Parameters.MasterInstanceTypeB)
62 t.Logf("Cluster MasterInstanceTypeC %v", c.Parameters.MasterInstanceTypeC)
63 t.Logf("Cluster NumOfNodeA %v", c.Parameters.NumOfNodesA)
64 t.Logf("Cluster NumOfNodeB %v", c.Parameters.NumOfNodesB)
65 t.Logf("Cluster NumOfNodeC %v", c.Parameters.NumOfNodesC)
6656 } else {
67 t.Logf("%v is a single kubernetes cluster", c.ClusterID)
68 t.Logf("Cluster VSW ID %v", c.Parameters.VSwitchID)
69 t.Logf("Cluster MasterInstanceType %v", c.Parameters.MasterInstanceType)
70 t.Logf("Cluster NumOfNode %v", c.Parameters.NumOfNodes)
57 if cluster.ClusterType == "ManagedKubernetes" {
58 t.Logf("%v is a Managed kubernetes cluster", c.ClusterID)
59 } else {
60 t.Logf("%v is a SingleAZ kubernetes cluster", c.ClusterID)
61 }
7162 }
7263 }
7364 }
9586 t.Logf("Cluster certs: %++v", certs)
9687
9788 }
89 }
90
91 func _TestGetClusterEndpoints(t *testing.T) {
92 client := NewTestClientForDebug()
93 clusterId := "c213c31b97430433c87afe4852b6a08ef"
94 clusterEndpoints, err := client.GetClusterEndpoints(clusterId)
95 if err != nil {
96 t.Fatalf("Failed to GetClusterEndpoints: %v", err)
97 }
98 t.Logf("Succeed getting clusterEndpoints %v", clusterEndpoints)
9899 }
99100
100101 func _TestCreateClusters(t *testing.T) {
154155 WorkerDataDisk: true,
155156 WorkerDataDiskCategory: "cloud_efficiency",
156157 WorkerDataDiskSize: 100,
158 PublicSLB: true,
159 NodeCIDRMask: "25",
160 LoggingType: "SLS",
161 SLSProjectName: "k8s-test-my-terraform-singleaz",
157162 }
158163 cluster, err := client.CreateKubernetesCluster(common.Hangzhou, &args)
159164 if err != nil {
163168 t.Logf("Cluster: %++v", cluster)
164169 }
165170
166 func _TestCreateKubernetesMultiAZCluster(t *testing.T) {
167
168 client := NewTestClientForDebug()
169
170 args := KubernetesMultiAZCreationArgs{
171 Name: "multiaz-test1",
172 ClusterType: "Kubernetes",
173 DisableRollback: true,
174 MultiAZ: true,
175 VPCID: "vpc-id",
176 VSwitchIdA: "vsw-id1",
177 VSwitchIdB: "vsw-id2",
178 VSwitchIdC: "vsw-id3",
179 NumOfNodesA: 1,
180 NumOfNodesB: 1,
181 NumOfNodesC: 1,
182 MasterInstanceTypeA: "ecs.sn1ne.large",
183 MasterInstanceTypeB: "ecs.sn1ne.large",
184 MasterInstanceTypeC: "ecs.sn1ne.large",
171 func _TestCreateManagedKubernetesCluster(t *testing.T) {
172
173 client := NewTestClientForDebug()
174
175 args := KubernetesCreationArgs{
176 Name: "single-managed-az-k8s",
177 ClusterType: "ManagedKubernetes",
178 DisableRollback: true,
179 //VPCID: "vpc-id",
180 //VSwitchId: "vsw-id",
181 ZoneId: "cn-hangzhou-g",
182 SNatEntry: true,
183 NumOfNodes: 2,
184 MasterInstanceType: "ecs.sn1ne.large",
185185 MasterSystemDiskCategory: "cloud_efficiency",
186186 MasterSystemDiskSize: 40,
187 WorkerInstanceTypeA: "ecs.sn1ne.large",
188 WorkerInstanceTypeB: "ecs.sn1ne.large",
189 WorkerInstanceTypeC: "ecs.sn1ne.large",
187 WorkerInstanceType: "ecs.sn1ne.large",
190188 WorkerSystemDiskCategory: "cloud_efficiency",
191189 WorkerSystemDiskSize: 40,
192190 SSHFlags: true,
193 ContainerCIDR: "172.17.0.0/16",
194 ServiceCIDR: "172.20.0.0/20",
191 ContainerCIDR: "172.16.0.0/16",
192 ServiceCIDR: "172.19.0.0/20",
195193 LoginPassword: "test-password123",
196194 WorkerDataDisk: true,
197195 WorkerDataDiskCategory: "cloud_efficiency",
198196 WorkerDataDiskSize: 100,
197 PublicSLB: true,
198 NodeCIDRMask: "25",
199 LoggingType: "SLS",
200 SLSProjectName: "k8s-test-my-terraform-singleaz",
201 }
202 cluster, err := client.CreateKubernetesCluster(common.Hangzhou, &args)
203 if err != nil {
204 t.Fatalf("Failed to CreateKubernetesCluster: %v", err)
205 }
206
207 t.Logf("Cluster: %++v", cluster)
208 }
209
210 func _TestCreateKubernetesMultiAZCluster(t *testing.T) {
211
212 client := NewTestClientForDebug()
213
214 args := KubernetesMultiAZCreationArgs{
215 Name: "multiaz-test",
216 ClusterType: "Kubernetes",
217 DisableRollback: true,
218 MultiAZ: true,
219 VPCID: "vpc-id",
220 VSwitchIdA: "vsw-id1",
221 VSwitchIdB: "vsw-id2",
222 VSwitchIdC: "vsw-id3",
223 NumOfNodesA: 1,
224 NumOfNodesB: 1,
225 NumOfNodesC: 1,
226
227 MasterInstanceTypeA: "ecs.ic5.xlarge",
228 MasterInstanceTypeB: "ecs.ic5.xlarge",
229 MasterInstanceTypeC: "ecs.ic5.xlarge",
230 MasterSystemDiskCategory: "cloud_efficiency",
231 MasterSystemDiskSize: 40,
232
233 MasterInstanceChargeType: "PrePaid",
234 MasterPeriodUnit: "Week",
235 MasterPeriod: 1,
236 MasterAutoRenew: true,
237 MasterAutoRenewPeriod: 1,
238
239 WorkerInstanceTypeA: "ecs.ic5.xlarge",
240 WorkerInstanceTypeB: "ecs.ic5.xlarge",
241 WorkerInstanceTypeC: "ecs.ic5.xlarge",
242 WorkerSystemDiskCategory: "cloud_efficiency",
243 WorkerSystemDiskSize: 40,
244
245 WorkerInstanceChargeType: "PrePaid",
246 WorkerPeriodUnit: "Week",
247 WorkerPeriod: 1,
248 WorkerAutoRenew: true,
249 WorkerAutoRenewPeriod: 1,
250
251 SSHFlags: true,
252 ContainerCIDR: "172.20.0.0/16",
253 ServiceCIDR: "172.21.0.0/20",
254 LoginPassword: "test-password123",
255 ImageId: "centos_7_03_64_20G_alibase_20170818.vhd",
256 KubernetesVersion: "1.11.2",
257 WorkerDataDisk: true,
258 WorkerDataDiskCategory: "cloud_efficiency",
259 WorkerDataDiskSize: 100,
260 NodeCIDRMask: "25",
261 LoggingType: "SLS",
262 SLSProjectName: "k8s-test-my-terraform",
199263 }
200264 cluster, err := client.CreateKubernetesMultiAZCluster(common.Hangzhou, &args)
201265 if err != nil {
205269 t.Logf("Cluster: %++v", cluster)
206270 }
207271
208 func _TestResizeKubernetesCluster(t *testing.T) {
209 client := NewTestClientForDebug()
210
211 args := KubernetesClusterResizeArgs{
212 DisableRollback: true,
213 TimeoutMins: 60,
214 LoginPassword: "test-password123",
215 WorkerInstanceType: "ecs.sn1ne.large",
216 NumOfNodes: 2,
217 }
218
219 err := client.ResizeKubernetesCluster("c3419330390a94906bcacc55bfa9dd21f", &args)
220 if err != nil {
221 t.Fatalf("Failed to TestResizeKubernetesCluster: %v", err)
222 }
223 }
272 func TestScaleKubernetesCluster(t *testing.T) {
273 // Comment below to test
274 //t.SkipNow()
275
276 client := NewTestClientForDebug()
277
278 args := KubernetesClusterScaleArgs{
279 LoginPassword: "test-password123",
280 WorkerInstanceTypes: []string{"ecs.sn1ne.large"},
281 WorkerSystemDiskCategory: "cloud_ssd",
282 WorkerSystemDiskSize: int64(40),
283 Count: 2,
284 WorkerDataDisk: true,
285 WorkerDataDiskCategory: "cloud_ssd",
286 WorkerDataDiskSize: int64(200),
287 }
288
289 err := client.ScaleKubernetesCluster(TestClusterId, &args)
290 if err != nil {
291 t.Fatalf("Failed to TestScaleKubernetesCluster: %v", err)
292 }
293 }
294
295 func Test_GetKubernetesClusterNodes(t *testing.T) {
296 client := NewTestClientForDebug()
297
298 resp, _, err := client.GetKubernetesClusterNodes(TestClusterId, common.Pagination{PageNumber: 1, PageSize: 1000}, NodePoolId)
299 if err != nil {
300 t.Errorf("Error %++v", err)
301 } else {
302 t.Logf("response: %++v", resp)
303 }
304 }
11
22 import (
33 "os"
4 "strconv"
45
56 "github.com/denverdino/aliyungo/common"
67 )
89 //Modify with your Access Key Id and Access Key Secret
910
1011 var (
11 TestAccessKeyId = os.Getenv("AccessKeyId")
12 TestAccessKeySecret = os.Getenv("AccessKeySecret")
13 TestSecurityToken = os.Getenv("SecurityToken")
14 TestRegionID = common.Region(os.Getenv("RegionId"))
12 TestAccessKeyId = os.Getenv("AccessKeyId")
13 TestAccessKeySecret = os.Getenv("AccessKeySecret")
14 TestSecurityToken = os.Getenv("SecurityToken")
15 TestRegionID = common.Region(os.Getenv("RegionId"))
16 TestVpcId = os.Getenv("VpcId")
17 TestVSwitchId = os.Getenv("VSwitchId")
18 TestServiceCIDR = os.Getenv("ServiceCIDR")
19 TestClusterId = os.Getenv("ClusterId")
20 TestPrivateIpAddress, _ = strconv.ParseBool(os.Getenv("PrivateIpAddress"))
21 TestToken = os.Getenv("Token")
22 TestLoggingType = os.Getenv("LoggingType")
1523 )
1624
1725 var testClient *Client
0 package cs
1
2 import (
3 "testing"
4 )
5
6 func Test_ModifyCluster(t *testing.T) {
7 client := NewTestClientForDebug()
8
9 args := &ModifyClusterArgs{
10 DeletionProtection: false,
11 MaintenanceWindow: MaintenanceWindow{
12 Enable: true,
13 MaintenanceTime: "2020-12-02T13:06:50.224Z",
14 Duration: "3h",
15 WeeklyPeriod: "Wednesday",
16 },
17 }
18
19 err := client.ModifyCluster(TestClusterId, args)
20 if err != nil {
21 t.Errorf("Error %++v", err)
22 } else {
23 t.Logf("OK")
24 }
25 }
26
27 func Test_UpgradeCluster(t *testing.T) {
28 client := NewTestClientForDebug()
29
30 args := &UpgradeClusterArgs{
31 Version: "1.14.8-aliyun.1",
32 }
33
34 err := client.UpgradeCluster(TestClusterId, args)
35 if err != nil {
36 t.Errorf("Error %++v", err)
37 } else {
38 t.Logf("OK")
39 }
40 }
41
42 func Test_CancelUpgradeCluster(t *testing.T) {
43 client := NewTestClientForDebug()
44
45 err := client.CancelUpgradeCluster(TestClusterId)
46 if err != nil {
47 t.Errorf("Error %++v", err)
48 } else {
49 t.Logf("OK")
50 }
51 }
52
53 func Test_QueryUpgradeClusterResult(t *testing.T) {
54 client := NewTestClientForDebug()
55
56 result, err := client.QueryUpgradeClusterResult(TestClusterId)
57 if err != nil {
58 t.Errorf("Error %++v", err)
59 } else {
60 t.Logf("OK, result: %++v", result)
61 }
62 }
63
64 func Test_CreateDelicatedKubernetesCluster(t *testing.T) {
65 t.SkipNow()
66 client := NewTestClientForDebug()
67
68 request := &DelicatedKubernetesClusterCreationRequest{}
69 response, err := client.CreateDelicatedKubernetesCluster(request)
70 if err != nil {
71 t.Fatalf("Error %++v", err)
72 } else {
73 t.Logf("Response %++v", response)
74 }
75 }
76
77 func Test_CreateManagedKubernetesCluster(t *testing.T) {
78 t.SkipNow()
79 client := NewTestClientForDebug()
80
81 request := &ManagedKubernetesClusterCreationRequest{}
82
83 response, err := client.CreateManagedKubernetesCluster(request)
84 if err != nil {
85 t.Fatalf("Error %++v", err)
86 } else {
87 t.Logf("Response %++v", response)
88 }
89 }
90
91 func Test_DescribeKubernetesClusterDetail(t *testing.T) {
92 client := NewTestClientForDebug()
93
94 cluster, err := client.DescribeKubernetesClusterDetail(TestClusterId)
95
96 if err != nil {
97 t.Fatalf("Error %++v", err)
98 } else {
99 t.Logf("Response = %++v", cluster)
100 t.Logf("MetaData = %++v", cluster.GetMetaData())
101 }
102 }
103
104 func Test_ScaleOutKubernetesCluster(t *testing.T) {
105 client := NewTestClientForDebug()
106
107 request := &ScaleOutKubernetesClusterRequest{
108 LoginPassword: "Hello1234",
109 WorkerVSwitchIds: []string{"vsw-xxxx"},
110 WorkerInstanceTypes: []string{"ecs.n4.xlarge"},
111 WorkerInstanceChargeType: "PostPaid",
112 WorkerPeriod: 1,
113 WorkerPeriodUnit: "1",
114 WorkerAutoRenew: true,
115 WorkerAutoRenewPeriod: 1,
116 WorkerDataDisk: true,
117 WorkerDataDisks: []DataDisk{
118 {
119 Category: "cloud_ssd",
120 Size: "200",
121 },
122 {
123 Category: "cloud_ssd",
124 Size: "300",
125 },
126 },
127 Tags: []Tag{
128 {Key: "k-aaa",
129 Value: "v-aaa",
130 },
131 },
132 Count: 2,
133 }
134
135 response, err := client.ScaleOutKubernetesCluster(TestClusterId, request)
136 if err != nil {
137 t.Fatalf("Error %++v", err)
138 } else {
139 t.Logf("Response %++v", response)
140 }
141 }
142
143 func Test_DeleteKubernetesClusterNodes(t *testing.T) {
144 client := NewTestClientForDebug()
145
146 request := &DeleteKubernetesClusterNodesRequest{
147 ReleaseNode: false,
148 Nodes: []string{"cn-beijing.192.168.0.128"},
149 }
150
151 response, err := client.DeleteKubernetesClusterNodes(TestClusterId, request)
152 if err != nil {
153 t.Fatalf("Error %++v", err)
154 } else {
155 t.Logf("Response %++v", response)
156 }
157 }
0 package cs
1
2 import (
3 "encoding/json"
4 "fmt"
5 "net/http"
6 "time"
7
8 "github.com/denverdino/aliyungo/ecs"
9
10 "github.com/denverdino/aliyungo/common"
11 )
12
13 type TaskState string
14
15 const (
16 // task status
17 Task_Status_Running = "running"
18 Task_Status_Success = "Success"
19 Task_Status_Failed = "Failed"
20
21 // upgrade state
22 UpgradeStep_NotStart = "not_start"
23 UpgradeStep_Prechecking = "prechecking"
24 UpgradeStep_Upgrading = "upgrading"
25 UpgradeStep_Pause = "pause"
26 UpgradeStep_Success = "success"
27 )
28
29 type WeeklyPeriod string
30 type MaintenanceTime string
31
32 // maintenance window
33 type MaintenanceWindow struct {
34 Enable bool `json:"enable"`
35 MaintenanceTime MaintenanceTime `json:"maintenance_time"`
36 Duration string `json:"duration"`
37 Recurrence string `json:"recurrence,omitempty"`
38 WeeklyPeriod WeeklyPeriod `json:"weekly_period"`
39 }
40
41 //modify cluster,include DeletionProtection and so on
42 type ModifyClusterArgs struct {
43 DeletionProtection bool `json:"deletion_protection"`
44 ResourceGroupId string `json:"resource_group_id"`
45 MaintenanceWindow MaintenanceWindow `json:"maintenance_window"`
46 EnableRRSA bool `json:"enable_rrsa"`
47 }
48
49 type UpgradeClusterArgs struct {
50 Version string `json:"version"`
51 }
52
53 type UpgradeClusterResult struct {
54 Status TaskState `json:"status"`
55 PrecheckReportId string `json:"precheck_report_id"`
56 UpgradeStep string `json:"upgrade_step"`
57 ErrorMessage string `json:"error_message"`
58 *UpgradeTask `json:"upgrade_task,omitempty"`
59 }
60
61 type UpgradeTask struct {
62 FieldRetries int `json:"retries,omitempty"`
63 FieldCreatedAt time.Time `json:"created_at"`
64 FieldMessage string `json:"message,omitempty"`
65 FieldStatus string `json:"status"` // empty|running|success|failed
66 FieldFinishedAt time.Time `json:"finished_at,omitempty"`
67 UpgradeStatus UpgradeStatus `json:"upgrade_status"`
68 }
69
70 type UpgradeStatus struct {
71 State string `json:"state"`
72 Phase string `json:"phase"` // {Master1, Master2, Master3, Nodes}
73 Total int `json:"total"`
74 Succeeded int `json:"succeeded"`
75 Failed string `json:"failed"`
76 Events []Event `json:"events"`
77 IsCanceled bool `json:"is_canceled"`
78 }
79
80 type Event struct {
81 Timestamp time.Time
82 Type string
83 Reason string
84 Message string
85 Source string
86 }
87
88 //modify cluster
89 func (client *Client) ModifyCluster(clusterId string, args *ModifyClusterArgs) error {
90 return client.Invoke("", http.MethodPut, "/api/v2/clusters/"+clusterId, nil, args, nil)
91 }
92
93 //upgrade cluster
94 func (client *Client) UpgradeCluster(clusterId string, args *UpgradeClusterArgs) error {
95 return client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/upgrade", clusterId), nil, args, nil)
96 }
97
98 //cancel upgrade cluster
99 func (client *Client) CancelUpgradeCluster(clusterId string) error {
100 return client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/upgrade/cancel", clusterId), nil, nil, nil)
101 }
102
103 func (client *Client) QueryUpgradeClusterResult(clusterId string) (*UpgradeClusterResult, error) {
104 cluster := &UpgradeClusterResult{}
105 err := client.Invoke("", http.MethodGet, fmt.Sprintf("/api/v2/clusters/%s/upgrade/status", clusterId), nil, nil, cluster)
106 if err != nil {
107 return nil, err
108 }
109 return cluster, nil
110 }
111
112 //Cluster Info
113 type KubernetesClusterType string
114
115 var (
116 DelicatedKubernetes = KubernetesClusterType("Kubernetes")
117 ManagedKubernetes = KubernetesClusterType("ManagedKubernetes")
118 )
119
120 type KubernetesClusterProfile string
121
122 var (
123 Profile4Serverless = KubernetesClusterProfile("Serverless")
124 )
125
126 type ProxyMode string
127
128 var (
129 IPTables = "iptables"
130 IPVS = "ipvs"
131 )
132
133 type Effect string
134
135 var (
136 TaintNoExecute = "NoExecute"
137 TaintNoSchedule = "NoSchedule"
138 TaintPreferNoSchedule = "PreferNoSchedule"
139 )
140
141 type ClusterArgs struct {
142 DisableRollback bool `json:"disable_rollback"`
143 TimeoutMins int `json:"timeout_mins"`
144
145 Name string `json:"name"`
146 ClusterType KubernetesClusterType `json:"cluster_type"`
147 Profile string `json:"profile"`
148 KubernetesVersion string `json:"kubernetes_version"`
149 DeletionProtection bool `json:"deletion_protection"`
150 EnableRRSA bool `json:"enable_rrsa"`
151
152 NodeCidrMask string `json:"node_cidr_mask"`
153 UserCa string `json:"user_ca"`
154
155 OsType string `json:"os_type"`
156 Platform string `json:"platform"`
157
158 UserData string `json:"user_data"`
159
160 NodePortRange string `json:"node_port_range"`
161 NodeNameMode string `json:"node_name_mode"`
162
163 //ImageId
164 ImageId string `json:"image_id"`
165
166 PodVswitchIds []string `json:"pod_vswitch_ids"` // eni多网卡模式下,需要传额外的vswitchid给addon
167
168 LoginPassword string `json:"login_password"` //和KeyPair 二选一
169 KeyPair string `json:"key_pair"` ////LoginPassword 二选一
170
171 RegionId common.Region `json:"region_id"`
172 VpcId string `json:"vpcid"`
173 ContainerCidr string `json:"container_cidr"`
174 ServiceCidr string `json:"service_cidr"`
175
176 CloudMonitorFlags bool `json:"cloud_monitor_flags"`
177
178 SecurityGroupId string `json:"security_group_id"`
179 IsEnterpriseSecurityGroup bool `json:"is_enterprise_security_group"`
180 EndpointPublicAccess bool `json:"endpoint_public_access"`
181 LoadBalancerSpec string `json:"load_balancer_spec"` //api server slb实例规格
182 ProxyMode ProxyMode `json:"proxy_mode"`
183 SnatEntry bool `json:"snat_entry"`
184 ResourceGroupId string `json:"resource_group_id"`
185
186 Addons []Addon `json:"addons"`
187 Tags []Tag `json:"tags"`
188
189 Taints []Taint `json:"taints"`
190
191 ApiAudiences string `json:"api_audiences,omitempty"`
192 ServiceAccountIssuer string `json:"service_account_issuer,omitempty"`
193 CustomSAN string `json:"custom_san,omitempty"`
194 ClusterSpec string `json:"cluster_spec"`
195 Timezone string `json:"timezone"`
196 ClusterDomain string `json:"cluster_domain"`
197 RdsInstances []string `json:"rds_instances"`
198 EncryptionProviderKey string `json:"encryption_provider_key"`
199 MaintenanceWindow MaintenanceWindow `json:"maintenance_window"`
200
201 //controlplane log parms
202 ControlplaneLogProject string `json:"controlplane_log_project"`
203 ControlplaneLogTTL string `json:"controlplane_log_ttl"`
204 ControlplaneComponents []string `json:"controlplane_log_components"`
205
206 // Operating system hardening
207 SocEnabled bool `json:"soc_enabled"`
208 CisEnabled bool `json:"cis_enabled"`
209 }
210
211 //addon
212 type Addon struct {
213 Name string `json:"name"`
214 Version string `json:"version"`
215 Config string `json:"config"`
216 Disabled bool `json:"disabled"` // 是否禁止默认安装
217 }
218
219 //taint
220 type Taint struct {
221 Key string `json:"key"`
222 Value string `json:"value"`
223 Effect Effect `json:"effect"`
224 }
225
226 type Label struct {
227 Key string `json:"key"`
228 Value string `json:"value"`
229 }
230
231 type MasterArgs struct {
232 MasterCount int `json:"master_count"`
233 MasterVSwitchIds []string `json:"master_vswitch_ids"`
234 MasterInstanceTypes []string `json:"master_instance_types"`
235
236 MasterInstanceChargeType string `json:"master_instance_charge_type"`
237 MasterPeriod int `json:"master_period"`
238 MasterPeriodUnit string `json:"master_period_unit"`
239
240 MasterAutoRenew bool `json:"master_auto_renew"`
241 MasterAutoRenewPeriod int `json:"master_auto_renew_period"`
242
243 MasterSystemDiskCategory ecs.DiskCategory `json:"master_system_disk_category"`
244 MasterSystemDiskSize int64 `json:"master_system_disk_size"`
245 MasterSystemDiskPerformanceLevel string `json:"master_system_disk_performance_level"`
246
247 MasterDataDisks []DataDisk `json:"master_data_disks"` //支持多个数据盘
248
249 //support hpc/scc
250 MasterHpcClusterId string `json:"master_hpc_cluster_id"`
251 MasterDeploymentSetId string `json:"master_deploymentset_id"`
252
253 //master node deletion protection
254 MasterDeletionProtection *bool `json:"master_deletion_protection"`
255
256 // disk snapshot policy
257 MasterSnapshotPolicyId string `json:"master_system_disk_snapshot_policy_id"`
258 }
259
260 type WorkerArgs struct {
261 WorkerVSwitchIds []string `json:"worker_vswitch_ids"`
262 WorkerInstanceTypes []string `json:"worker_instance_types"`
263
264 NumOfNodes int64 `json:"num_of_nodes"`
265
266 WorkerInstanceChargeType string `json:"worker_instance_charge_type"`
267 WorkerPeriod int `json:"worker_period"`
268 WorkerPeriodUnit string `json:"worker_period_unit"`
269
270 WorkerAutoRenew bool `json:"worker_auto_renew"`
271 WorkerAutoRenewPeriod int `json:"worker_auto_renew_period"`
272
273 WorkerSystemDiskCategory ecs.DiskCategory `json:"worker_system_disk_category"`
274 WorkerSystemDiskSize int64 `json:"worker_system_disk_size"`
275 WorkerSystemDiskPerformanceLevel string `json:"worker_system_disk_performance_level"`
276
277 WorkerDataDisk bool `json:"worker_data_disk"`
278 WorkerDataDisks []DataDisk `json:"worker_data_disks"` //支持多个数据盘
279
280 WorkerHpcClusterId string `json:"worker_hpc_cluster_id"`
281 WorkerDeploymentSetId string `json:"worker_deploymentset_id"`
282
283 //worker node deletion protection
284 WorkerDeletionProtection *bool `json:"worker_deletion_protection"`
285
286 //Runtime only for worker nodes
287 Runtime Runtime `json:"runtime"`
288
289 // disk snapshot policy
290 WorkerSnapshotPolicyId string `json:"worker_system_disk_snapshot_policy_id"`
291 }
292
293 type ScaleOutKubernetesClusterRequest struct {
294 LoginPassword string `json:"login_password"` //和KeyPair 二选一
295 KeyPair string `json:"key_pair"` ////LoginPassword 二选一
296
297 WorkerVSwitchIds []string `json:"worker_vswitch_ids"`
298 WorkerInstanceTypes []string `json:"worker_instance_types"`
299
300 WorkerInstanceChargeType string `json:"worker_instance_charge_type"`
301 WorkerPeriod int `json:"worker_period"`
302 WorkerPeriodUnit string `json:"worker_period_unit"`
303
304 WorkerAutoRenew bool `json:"worker_auto_renew"`
305 WorkerAutoRenewPeriod int `json:"worker_auto_renew_period"`
306
307 WorkerSystemDiskCategory ecs.DiskCategory `json:"worker_system_disk_category"`
308 WorkerSystemDiskSize int64 `json:"worker_system_disk_size"`
309 WorkerSnapshotPolicyId string `json:"worker_system_disk_snapshot_policy_id"`
310 WorkerSystemDiskPerformanceLevel string `json:"worker_system_disk_performance_level"`
311
312 WorkerDataDisk bool `json:"worker_data_disk"`
313 WorkerDataDisks []DataDisk `json:"worker_data_disks"` //支持多个数据盘
314
315 Tags []Tag `json:"tags"`
316 Taints []Taint `json:"taints"`
317 ImageId string `json:"image_id"`
318
319 UserData string `json:"user_data"`
320
321 Count int64 `json:"count"`
322 CpuPolicy string `json:"cpu_policy"`
323 Runtime Runtime `json:"runtime"`
324 CloudMonitorFlags bool `json:"cloud_monitor_flags"`
325 RdsInstances []string ` json:"rds_instances"`
326 }
327
328 //datadiks
329 type DataDisk struct {
330 Category string `json:"category"`
331 KMSKeyId string `json:"kms_key_id"`
332 Encrypted string `json:"encrypted"` // true|false
333 Device string `json:"device"` // could be /dev/xvd[a-z]. If not specification, will use default value.
334 Size string `json:"size"`
335 DiskName string `json:"name"`
336 AutoSnapshotPolicyId string `json:"auto_snapshot_policy_id"`
337 PerformanceLevel string `json:"performance_Level"`
338 }
339
340 type NodePoolDataDisk struct {
341 Category string `json:"category"`
342 KMSKeyId string `json:"kms_key_id"`
343 Encrypted string `json:"encrypted"` // true|false
344 Device string `json:"device"` // could be /dev/xvd[a-z]. If not specification, will use default value.
345 Size int `json:"size"`
346 DiskName string `json:"name"`
347 AutoSnapshotPolicyId string `json:"auto_snapshot_policy_id"`
348 PerformanceLevel string `json:"performance_Level"`
349 }
350
351 //runtime
352 type Runtime struct {
353 Name string `json:"name"`
354 Version string `json:"version"`
355 RuntimeClass []string `json:"runtimeClass,omitempty"`
356 Exist bool `json:"exist"`
357 AvailableNetworkComponents []string `json:"availableNetworkComponents,omitempty"`
358 }
359
360 //DelicatedKubernetes
361 type DelicatedKubernetesClusterCreationRequest struct {
362 ClusterArgs
363 MasterArgs
364 WorkerArgs
365 }
366
367 //ManagedKubernetes
368 type ManagedKubernetesClusterCreationRequest struct {
369 ClusterArgs
370 WorkerArgs
371 }
372
373 //Validate
374
375 //Create DelicatedKubernetes Cluster
376 func (client *Client) CreateDelicatedKubernetesCluster(request *DelicatedKubernetesClusterCreationRequest) (*ClusterCommonResponse, error) {
377 response := &ClusterCommonResponse{}
378 path := "/clusters"
379 if request.ResourceGroupId != "" {
380 // 创建集群到指定资源组
381 path = fmt.Sprintf("/resource_groups/%s/clusters", request.ResourceGroupId)
382 }
383 err := client.Invoke(request.RegionId, http.MethodPost, path, nil, request, response)
384 if err != nil {
385 return nil, err
386 }
387
388 return response, nil
389 }
390
391 //Create ManagedKubernetes Cluster
392 func (client *Client) CreateManagedKubernetesCluster(request *ManagedKubernetesClusterCreationRequest) (*ClusterCommonResponse, error) {
393 response := &ClusterCommonResponse{}
394 path := "/clusters"
395 if request.ResourceGroupId != "" {
396 // 创建集群到指定资源组
397 path = fmt.Sprintf("/resource_groups/%s/clusters", request.ResourceGroupId)
398 }
399 err := client.Invoke(request.RegionId, http.MethodPost, path, nil, request, response)
400 if err != nil {
401 return nil, err
402 }
403
404 return response, nil
405 }
406
407 //ScaleKubernetesCluster
408 func (client *Client) ScaleOutKubernetesCluster(clusterId string, request *ScaleOutKubernetesClusterRequest) (*ClusterCommonResponse, error) {
409 response := &ClusterCommonResponse{}
410 err := client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s", clusterId), nil, request, response)
411 if err != nil {
412 return nil, err
413 }
414
415 return response, nil
416 }
417
418 //DeleteClusterNodes
419 type DeleteKubernetesClusterNodesRequest struct {
420 ReleaseNode bool `json:"release_node"` //if set to true, the ecs instance will be released
421 Nodes []string `json:"nodes"` //the format is regionId.instanceId|Ip ,for example cn-hangzhou.192.168.1.2 or cn-hangzhou.i-abc
422 DrainNode bool `json:"drain_node"` //same as Nodes
423 }
424
425 //DeleteClusterNodes
426 func (client *Client) DeleteKubernetesClusterNodes(clusterId string, request *DeleteKubernetesClusterNodesRequest) (*common.Response, error) {
427 response := &common.Response{}
428 err := client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/nodes/remove", clusterId), nil, request, response)
429 if err != nil {
430 return nil, err
431 }
432
433 return response, nil
434 }
435
436 //Cluster definition
437 type KubernetesClusterDetail struct {
438 RegionId common.Region `json:"region_id"`
439
440 Name string `json:"name"`
441 ClusterId string `json:"cluster_id"`
442 Size int64 `json:"size"`
443 ClusterType KubernetesClusterType `json:"cluster_type"`
444 Profile string `json:"profile"`
445
446 VpcId string `json:"vpc_id"`
447 VSwitchIds string `json:"vswitch_id"`
448 SecurityGroupId string `json:"security_group_id"`
449 IngressLoadbalancerId string `json:"external_loadbalancer_id"`
450 ResourceGroupId string `json:"resource_group_id"`
451 NetworkMode string `json:"network_mode"`
452 ContainerCIDR string `json:"subnet_cidr"`
453
454 Tags []Tag `json:"tags"`
455 State string `json:"state"`
456
457 InitVersion string `json:"init_version"`
458 CurrentVersion string `json:"current_version"`
459 PrivateZone bool `json:"private_zone"`
460 DeletionProtection bool `json:"deletion_protection"`
461 EnableRRSA bool `json:"enable_rrsa"`
462 MetaData string `json:"meta_data"`
463
464 Created time.Time `json:"created"`
465 Updated time.Time `json:"updated"`
466
467 WorkerRamRoleName string `json:"worker_ram_role_name"`
468 ClusterSpec string `json:"cluster_spec"`
469 OSType string `json:"os_type"`
470 MasterURL string `json:"master_url"`
471 MaintenanceWindow MaintenanceWindow `json:"maintenance_window"`
472 Parameters map[string]interface{} `json:"parameters"`
473 }
474
475 //GetMetaData
476 func (c *KubernetesClusterDetail) GetMetaData() map[string]interface{} {
477 m := make(map[string]interface{})
478 _ = json.Unmarshal([]byte(c.MetaData), &m)
479 return m
480 }
481
482 //查询集群详情
483 func (client *Client) DescribeKubernetesClusterDetail(clusterId string) (*KubernetesClusterDetail, error) {
484 cluster := &KubernetesClusterDetail{}
485 err := client.Invoke("", http.MethodGet, "/clusters/"+clusterId, nil, nil, cluster)
486 if err != nil {
487 return nil, err
488 }
489 return cluster, nil
490 }
491
492 //DeleteKubernetesCluster
493 func (client *Client) DeleteKubernetesCluster(clusterId string) error {
494 return client.Invoke("", http.MethodDelete, "/clusters/"+clusterId, nil, nil, nil)
495 }
0 package cs
1
2 import (
3 "fmt"
4 "github.com/denverdino/aliyungo/common"
5 "github.com/denverdino/aliyungo/ecs"
6 "net/http"
7 "net/url"
8 "time"
9 )
10
11 type SpotPrice struct {
12 InstanceType string `json:"instance_type"`
13 PriceLimit string `json:"price_limit"`
14 }
15
16 type NodePoolInfo struct {
17 NodePoolId string `json:"nodepool_id"`
18 RegionId common.Region `json:"region_id"`
19 Name *string `json:"name"`
20 Created time.Time `json:"created"`
21 Updated time.Time `json:"updated"`
22 IsDefault *bool `json:"is_default"`
23 NodePoolType string `json:"type"`
24 ResourceGroupId *string `json:"resource_group_id"`
25 }
26
27 type ScalingGroup struct {
28 VpcId string `json:"vpc_id"`
29 VswitchIds []string `json:"vswitch_ids"`
30 InstanceTypes []string `json:"instance_types"`
31 LoginPassword *string `json:"login_password"`
32 KeyPair *string `json:"key_pair"`
33 SecurityGroupId string `json:"security_group_id"`
34 SecurityGroupIds []string `json:"security_group_ids"`
35 SystemDiskCategory ecs.DiskCategory `json:"system_disk_category"`
36 SystemDiskSize *int64 `json:"system_disk_size"`
37 SystemDiskPerformanceLevel *string `json:"system_disk_performance_level"`
38 SystemDiskEncryptAlgorithm *string `json:"system_disk_encrypt_algorithm"`
39 SystemDiskEncrypted *bool `json:"system_disk_encrypted"`
40 SystemDiskKMSKeyId *string `json:"system_disk_kms_key_id"`
41 DataDisks []NodePoolDataDisk `json:"data_disks"` //支持多个数据盘
42 Tags []Tag `json:"tags"`
43 ImageId *string `json:"image_id"`
44 Platform *string `json:"platform"`
45 OSType *string `json:"os_type"`
46 ImageType *string `json:"image_type"`
47 InstanceChargeType *string `json:"instance_charge_type"`
48 Period *int `json:"period"`
49 PeriodUnit *string `json:"period_unit"`
50 AutoRenew *bool `json:"auto_renew"`
51 AutoRenewPeriod *int `json:"auto_renew_period"`
52 // spot实例
53 SpotStrategy *string `json:"spot_strategy"`
54 SpotPriceLimit []SpotPrice `json:"spot_price_limit"`
55
56 RdsInstances []string `json:"rds_instances"`
57 ScalingPolicy *string `json:"scaling_policy"`
58 ScalingGroupId *string `json:"scaling_group_id"`
59
60 WorkerSnapshotPolicyId *string `json:"worker_system_disk_snapshot_policy_id"`
61 // 公网ip
62 InternetChargeType *string `json:"internet_charge_type"`
63 InternetMaxBandwidthOut *int `json:"internet_max_bandwidth_out"`
64 // Operating system hardening
65 SocEnabled *bool `json:"soc_enabled"`
66 CisEnabled *bool `json:"cis_enabled"`
67 // ipv6
68 SupportIPv6 *bool `json:"support_ipv6"`
69 // deploymentset
70 DeploymentSetId *string `json:"deploymentset_id"`
71 DesiredSize *int64 `json:"desired_size,omitempty"`
72 }
73
74 type AutoScaling struct {
75 Enable *bool `json:"enable"`
76 MaxInstances *int64 `json:"max_instances"`
77 MinInstances *int64 `json:"min_instances"`
78 Type *string `json:"type"`
79 // eip
80 IsBindEip *bool `json:"is_bond_eip"`
81 // value: PayByBandwidth / PayByTraffic
82 EipInternetChargeType *string `json:"eip_internet_charge_type"`
83 // default 5
84 EipBandWidth *int64 `json:"eip_bandwidth"`
85 }
86
87 type KubernetesConfig struct {
88 NodeNameMode string `json:"node_name_mode"`
89 Taints []Taint `json:"taints"`
90 Labels []Label `json:"labels"`
91 CpuPolicy string `json:"cpu_policy"`
92 UserData *string `json:"user_data"`
93
94 Runtime string `json:"runtime,omitempty"`
95 RuntimeVersion string `json:"runtime_version"`
96 CmsEnabled *bool `json:"cms_enabled"`
97 OverwriteHostname *bool `json:"overwrite_hostname"`
98 Unschedulable *bool `json:"unschedulable"`
99 }
100
101 // 加密计算节点池
102 type TEEConfig struct {
103 TEEType string `json:"tee_type"`
104 TEEEnable bool `json:"tee_enable"`
105 }
106
107 // 托管节点池配置
108 type Management struct {
109 Enable *bool `json:"enable"`
110 AutoRepair *bool `json:"auto_repair"`
111 UpgradeConf UpgradeConf `json:"upgrade_config"`
112 }
113
114 type UpgradeConf struct {
115 AutoUpgrade *bool `json:"auto_upgrade"`
116 Surge *int64 `json:"surge"`
117 SurgePercentage *int64 `json:"surge_percentage,omitempty"`
118 MaxUnavailable *int64 `json:"max_unavailable"`
119 KeepSurgeOnFailed *bool `json:"keep_surge_on_failed"`
120 }
121
122 type NodeConfig struct {
123 KubeletConfiguration *KubeletConfiguration `json:"kubelet_configuration,omitempty"`
124 RolloutPolicy *RolloutPolicy `json:"rollout_policy,omitempty"`
125 }
126
127 type KubeletConfiguration struct {
128 CpuManagerPolicy *string `json:"cpuManagerPolicy,omitempty"`
129 EventBurst *int64 `json:"eventBurst,omitempty"`
130 EventRecordQPS *int64 `json:"eventRecordQPS,omitempty"`
131 EvictionHard map[string]interface{} `json:"evictionHard,omitempty"`
132 EvictionSoft map[string]interface{} `json:"evictionSoft,omitempty"`
133 EvictionSoftGracePeriod map[string]interface{} `json:"evictionSoftGracePeriod,omitempty"`
134 KubeAPIBurst *int64 `json:"kubeAPIBurst,omitempty"`
135 KubeAPIQPS *int64 `json:"kubeAPIQPS,omitempty"`
136 KubeReserved map[string]interface{} `json:"kubeReserved,omitempty"`
137 RegistryBurst *int64 `json:"registryBurst,omitempty"`
138 RegistryPullQPS *int64 `json:"registryPullQPS,omitempty"`
139 SerializeImagePulls *bool `json:"serializeImagePulls,omitempty"`
140 SystemReserved map[string]interface{} `json:"systemReserved,omitempty"`
141 }
142
143 type RolloutPolicy struct {
144 MaxUnavailable *int64 `json:"max_unavailable,omitempty"`
145 }
146
147 type CreateNodePoolRequest struct {
148 RegionId common.Region `json:"region_id"`
149 Count int64 `json:"count"`
150 NodePoolInfo `json:"nodepool_info"`
151 ScalingGroup `json:"scaling_group"`
152 KubernetesConfig `json:"kubernetes_config"`
153 AutoScaling `json:"auto_scaling"`
154 TEEConfig `json:"tee_config"`
155 Management `json:"management"`
156 NodeConfig *NodeConfig `json:"node_config,omitempty"`
157 }
158
159 type BasicNodePool struct {
160 NodePoolInfo `json:"nodepool_info"`
161 NodePoolStatus `json:"status"`
162 }
163
164 type NodePoolStatus struct {
165 TotalNodes int `json:"total_nodes"`
166 OfflineNodes int `json:"offline_nodes"`
167 ServingNodes int `json:"serving_nodes"`
168 //DesiredNodes int `json:"desired_nodes"`
169 RemovingNodes int `json:"removing_nodes"`
170 FailedNodes int `json:"failed_nodes"`
171 InitialNodes int `json:"initial_nodes"`
172 HealthyNodes int `json:"healthy_nodes"`
173 State string `json:"state"`
174 }
175
176 type NodePoolDetail struct {
177 BasicNodePool
178 KubernetesConfig `json:"kubernetes_config"`
179 ScalingGroup `json:"scaling_group"`
180 AutoScaling `json:"auto_scaling"`
181 TEEConfig `json:"tee_config"`
182 Management `json:"management"`
183 }
184
185 type CreateNodePoolResponse struct {
186 Response
187 NodePoolID string `json:"nodepool_id"`
188 Message string `json:"Message"`
189 TaskID string `json:"task_id"`
190 }
191
192 type UpdateNodePoolRequest struct {
193 RegionId common.Region `json:"region_id"`
194 Count int64 `json:"count"`
195 NodePoolInfo `json:"nodepool_info"`
196 ScalingGroup `json:"scaling_group"`
197 KubernetesConfig `json:"kubernetes_config"`
198 AutoScaling `json:"auto_scaling"`
199 Management `json:"management"`
200 NodeConfig *NodeConfig `json:"node_config,omitempty"`
201 }
202
203 type NodePoolsDetail struct {
204 Response
205 NodePools []NodePoolDetail `json:"nodepools"`
206 }
207
208 func (client *Client) CreateNodePool(request *CreateNodePoolRequest, clusterId string) (*CreateNodePoolResponse, error) {
209 response := &CreateNodePoolResponse{}
210 err := client.Invoke(request.RegionId, http.MethodPost, fmt.Sprintf("/clusters/%s/nodepools", clusterId), nil, request, response)
211 if err != nil {
212 return nil, err
213 }
214
215 return response, nil
216 }
217
218 func (client *Client) DescribeNodePoolDetail(clusterId, nodePoolId string) (*NodePoolDetail, error) {
219 nodePool := &NodePoolDetail{}
220 err := client.Invoke("", http.MethodGet, fmt.Sprintf("/clusters/%s/nodepools/%s", clusterId, nodePoolId), nil, nil, nodePool)
221 if err != nil {
222 return nil, err
223 }
224 return nodePool, nil
225 }
226
227 func (client *Client) DescribeClusterNodePools(clusterId string) (*[]NodePoolDetail, error) {
228 nodePools := &NodePoolsDetail{}
229 err := client.Invoke("", http.MethodGet, fmt.Sprintf("/clusters/%s/nodepools", clusterId), nil, nil, nodePools)
230 if err != nil {
231 return nil, err
232 }
233 return &nodePools.NodePools, nil
234 }
235
236 func (client *Client) UpdateNodePool(clusterId string, nodePoolId string, request *UpdateNodePoolRequest) (*Response, error) {
237 response := &Response{}
238 err := client.Invoke(request.RegionId, http.MethodPut, fmt.Sprintf("/clusters/%s/nodepools/%s", clusterId, nodePoolId), nil, request, response)
239 if err != nil {
240 return nil, err
241 }
242
243 return response, nil
244 }
245
246 //Deprecated
247 func (client *Client) DeleteNodePool(clusterId, nodePoolId string) error {
248 return client.Invoke("", http.MethodDelete, fmt.Sprintf("/clusters/%s/nodepools/%s", clusterId, nodePoolId), nil, nil, nil)
249 }
250
251 func (client *Client) ForceDeleteNodePool(clusterId, nodePoolId string) error {
252 query := url.Values{}
253 query.Add("force", "true")
254 return client.Invoke("", http.MethodDelete, fmt.Sprintf("/clusters/%s/nodepools/%s", clusterId, nodePoolId), query, nil, nil)
255 }
0 package cs
1
2 import (
3 "os"
4 "strings"
5 "testing"
6 )
7
8 var (
9 VpcId = os.Getenv("VpcId")
10 VswitchIds = os.Getenv("VswitchIds")
11 LoginPassword = os.Getenv("LoginPassword")
12 NodePoolId = os.Getenv("NodePoolId")
13
14 nodepoolName = "test-npl"
15 systemDiskSize = int64(120)
16 )
17
18 func Test_CreateNodePool(t *testing.T) {
19 client := NewTestClientForDebug()
20
21 args := &CreateNodePoolRequest{
22 Count: 1,
23 RegionId: TestRegionID,
24 NodePoolInfo: NodePoolInfo{
25 Name: &nodepoolName,
26 NodePoolType: "ess",
27 },
28 ScalingGroup: ScalingGroup{
29 VpcId: VpcId,
30 VswitchIds: strings.Split(VswitchIds, ","),
31 InstanceTypes: []string{"ecs.n6.large"},
32 LoginPassword: &LoginPassword,
33 SystemDiskCategory: "cloud_efficiency",
34 SystemDiskSize: &systemDiskSize,
35 DataDisks: []NodePoolDataDisk{{Size: 100, Category: "cloud_ssd"}},
36 },
37 KubernetesConfig: KubernetesConfig{
38 NodeNameMode: "customized,aliyun.com,5,test",
39 },
40 }
41
42 resp, err := client.CreateNodePool(args, TestClusterId)
43 if err != nil {
44 t.Errorf("Error %++v", err)
45 } else {
46 t.Logf("response: %++v", resp)
47 }
48 }
49
50 func Test_DescribeNodePoolDetail(t *testing.T) {
51 client := NewTestClientForDebug()
52
53 resp, err := client.DescribeNodePoolDetail(TestClusterId, NodePoolId)
54 if err != nil {
55 t.Errorf("Error %++v", err)
56 } else {
57 t.Logf("response: %++v", resp)
58 }
59 }
60
61 func Test_UpdateNodePool(t *testing.T) {
62 client := NewTestClientForDebug()
63
64 args := &UpdateNodePoolRequest{
65 Count: 2,
66 RegionId: TestRegionID,
67 ScalingGroup: ScalingGroup{
68 InstanceTypes: []string{"ecs.n4.large"},
69 },
70 }
71
72 resp, err := client.UpdateNodePool(TestClusterId, NodePoolId, args)
73 if err != nil {
74 t.Errorf("Error %++v", err)
75 } else {
76 t.Logf("response: %++v", resp)
77 }
78 }
79
80 func Test_DeleteNodePool(t *testing.T) {
81 client := NewTestClientForDebug()
82
83 err := client.DeleteNodePool(TestClusterId, NodePoolId)
84 if err != nil {
85 t.Errorf("Error %++v", err)
86 } else {
87 t.Logf("success")
88 }
89 }
90
91 func Test_DescribeClusterNodePools(t *testing.T) {
92 client := NewTestClientForDebug()
93
94 resp, err := client.DescribeClusterNodePools(TestClusterId)
95 if err != nil {
96 t.Errorf("Error %++v", err)
97 } else {
98 t.Logf("response: %++v", resp)
99 }
100 }
6666 client.userAgent = userAgent
6767 }
6868
69 // SetTransport sets transport to the http client
70 func (client *ProjectClient) SetTransport(transport http.RoundTripper) {
71 if client.httpClient == nil {
72 client.httpClient = &http.Client{}
73 }
74 client.httpClient.Transport = transport
75 }
76
6977 func (client *ProjectClient) ClusterId() string {
7078 return client.clusterId
7179 }
133141
134142 if client.debug {
135143 var prettyJSON bytes.Buffer
136 err = json.Indent(&prettyJSON, body, "", " ")
137 log.Println(string(prettyJSON.Bytes()))
144 _ = json.Indent(&prettyJSON, body, "", " ")
145 log.Println(prettyJSON.String())
138146 }
139147
140148 if statusCode >= 400 && statusCode <= 599 {
141149 errorResponse := common.ErrorResponse{}
142 err = json.Unmarshal(body, &errorResponse)
150 _ = json.Unmarshal(body, &errorResponse)
143151 ecsError := &common.Error{
144152 ErrorResponse: errorResponse,
145153 StatusCode: statusCode,
0 package cs
1
2 import (
3 "fmt"
4 "net/http"
5 "net/url"
6 "strconv"
7 "time"
8
9 "github.com/denverdino/aliyungo/common"
10 )
11
12 type ServerlessCreationArgs struct {
13 ClusterType KubernetesClusterType `json:"cluster_type"`
14 Profile KubernetesClusterProfile `json:"profile"`
15 Name string `json:"name"`
16 RegionId string `json:"region_id"`
17 VpcId string `json:"vpcid"`
18 VSwitchId string `json:"vswitch_id"`
19 VswitchIds []string `json:"vswitch_ids"`
20 EndpointPublicAccess bool `json:"public_slb"`
21 PrivateZone bool `json:"private_zone"`
22 NatGateway bool `json:"nat_gateway"`
23 KubernetesVersion string `json:"kubernetes_version"`
24 DeletionProtection bool `json:"deletion_protection"`
25 EnableRRSA bool `json:"enable_rrsa"`
26 SecurityGroupId string `json:"security_group_id"`
27 Tags []Tag `json:"tags"`
28 Addons []Addon `json:"addons"`
29 ResourceGroupId string `json:"resource_group_id"`
30 ClusterSpec string `json:"cluster_spec"`
31 LoadBalancerSpec string `json:"load_balancer_spec"` //api server slb实例规格
32 ServiceCIDR string `json:"service_cidr"`
33 TimeZone string `json:"timezone"`
34 ServiceDiscoveryTypes []string `json:"service_discovery_types"`
35 ZoneID string `json:"zone_id"`
36 LoggingType string `json:"logging_type"`
37 SLSProjectName string `json:"sls_project_name"`
38 SnatEntry bool `json:"snat_entry"`
39 }
40
41 type ServerlessClusterResponse struct {
42 ClusterId string `json:"cluster_id"`
43 Name string `json:"name"`
44 ClusterType KubernetesClusterType `json:"cluster_type"`
45 RegionId string `json:"region_id"`
46 State ClusterState `json:"state"`
47 VpcId string `json:"vpc_id"`
48 VSwitchId string `json:"vswitch_id"`
49 SecurityGroupId string `json:"security_group_id"`
50 Tags []Tag `json:"tags"`
51 Created time.Time `json:"created"`
52 Updated time.Time `json:"updated"`
53 InitVersion string `json:"init_version"`
54 CurrentVersion string `json:"current_version"`
55 PrivateZone bool `json:"private_zone"`
56 DeletionProtection bool `json:"deletion_protection"`
57 EnableRRSA bool `json:"enable_rrsa"`
58 ResourceGroupId string `json:"resource_group_id"`
59 ClusterSpec string `json:"cluster_spec"`
60 Profile string `json:"profile"`
61 MetaData string `json:"meta_data"`
62 }
63
64 type Tag struct {
65 Key string `json:"key"`
66 Value string `json:"value"`
67 }
68
69 func (this *ServerlessCreationArgs) Validate() error {
70 if this.Name == "" || this.RegionId == "" || this.VpcId == "" {
71 return common.GetCustomError("InvalidParameters", "The name,region_id,vpc_id not allowed empty")
72 }
73 return nil
74 }
75
76 //create Serverless cluster
77 func (client *Client) CreateServerlessKubernetesCluster(args *ServerlessCreationArgs) (*ClusterCommonResponse, error) {
78 if args == nil {
79 return nil, common.GetCustomError("InvalidArgs", "The args is nil ")
80 }
81
82 if err := args.Validate(); err != nil {
83 return nil, err
84 }
85
86 cluster := &ClusterCommonResponse{}
87 path := "/clusters"
88 if args.ResourceGroupId != "" {
89 // 创建集群到指定资源组
90 path = fmt.Sprintf("/resource_groups/%s/clusters", args.ResourceGroupId)
91 }
92 err := client.Invoke(common.Region(args.RegionId), http.MethodPost, path, nil, args, &cluster)
93 if err != nil {
94 return nil, err
95 }
96 return cluster, nil
97 }
98
99 //describe Serverless cluster
100 func (client *Client) DescribeServerlessKubernetesCluster(clusterId string) (*ServerlessClusterResponse, error) {
101 cluster := &ServerlessClusterResponse{}
102 err := client.Invoke("", http.MethodGet, "/clusters/"+clusterId, nil, nil, cluster)
103 if err != nil {
104 return nil, err
105 }
106 return cluster, nil
107 }
108
109 //describe Serverless clsuters
110 func (client *Client) DescribeServerlessKubernetesClusters() ([]*ServerlessClusterResponse, error) {
111 allClusters := make([]*ServerlessClusterResponse, 0)
112 askClusters := make([]*ServerlessClusterResponse, 0)
113
114 err := client.Invoke("", http.MethodGet, "/clusters", nil, nil, &allClusters)
115 if err != nil {
116 return askClusters, err
117 }
118
119 for _, cluster := range allClusters {
120 // Ask 1.0/2.0
121 if cluster.ClusterType == ClusterTypeServerlessKubernetes {
122 askClusters = append(askClusters, cluster)
123 }
124 // Ask 3.0
125 if cluster.ClusterType == ClusterTypeManagedKubernetes && cluster.Profile == ProfileServerlessKubernetes {
126 askClusters = append(askClusters, cluster)
127 }
128 }
129
130 return askClusters, nil
131 }
132
133 //new api for get cluster kube user config
134 func (client *Client) DescribeClusterUserConfig(clusterId string, privateIpAddress bool) (*ClusterConfig, error) {
135 config := &ClusterConfig{}
136 query := url.Values{}
137 query.Add("PrivateIpAddress", strconv.FormatBool(privateIpAddress))
138
139 err := client.Invoke("", http.MethodGet, "/k8s/"+clusterId+"/user_config", query, nil, &config)
140 if err != nil {
141 return nil, err
142 }
143 return config, nil
144 }
0 package cs
1
2 import (
3 "fmt"
4 "testing"
5 "time"
6 )
7
8 func Test_CreateServerlessKubernetesCluster(t *testing.T) {
9 client := NewTestClientForDebug()
10
11 tags := make([]Tag, 0)
12 tags = append(tags, Tag{
13 Key: "key-a",
14 Value: "key-a",
15 })
16
17 tags = append(tags, Tag{
18 Key: "key-b",
19 Value: "key-b",
20 })
21
22 tags = append(tags, Tag{
23 Key: "key-c",
24 Value: "key-c",
25 })
26
27 args := &ServerlessCreationArgs{
28 ClusterType: ClusterTypeManagedKubernetes,
29 Profile: ProfileServerlessKubernetes,
30 Name: fmt.Sprintf("Serverless-cluster-%d", time.Now().Unix()),
31 RegionId: string(TestRegionID),
32 VpcId: TestVpcId,
33 VswitchIds: []string{TestVSwitchId},
34 ServiceCIDR: TestServiceCIDR,
35 LoggingType: TestLoggingType,
36 PrivateZone: true,
37 EndpointPublicAccess: true,
38 NatGateway: true,
39 DeletionProtection: true,
40 Tags: tags,
41 }
42
43 response, err := client.CreateServerlessKubernetesCluster(args)
44 if err != nil {
45 t.Errorf("Error %++v", err)
46 } else {
47 t.Logf("Response = %++v", response)
48 }
49 }
50
51 func Test_DescribeCluster(t *testing.T) {
52 client := NewTestClientForDebug()
53
54 cluster, err := client.DescribeServerlessKubernetesCluster(TestClusterId)
55 if err != nil {
56 t.Errorf("Error = %++v", err)
57 } else {
58 t.Logf("Cluster = %#v", cluster)
59 t.Logf("%v ", cluster.Created)
60 }
61 }
62
63 func Test_DescribeClusterUserConfig(t *testing.T) {
64 client := NewTestClientForDebug()
65
66 config, err := client.DescribeClusterUserConfig(TestClusterId, TestPrivateIpAddress)
67 if err != nil {
68 t.Errorf("Error = %++v", err)
69 } else {
70 t.Logf("Config = %#v", config)
71 }
72 }
73
74 func Test_DeleteServerlessCluster(t *testing.T) {
75 client := NewTestClientForDebug()
76
77 err := client.DeleteCluster(TestClusterId)
78 if err != nil {
79 t.Errorf("Error = %++v", err)
80 } else {
81 t.Logf("OK")
82 }
83 }
84
85 func Test_DescribeServerlessKubernetesClusters(t *testing.T) {
86 client := NewTestClientForDebug()
87 clusters, err := client.DescribeServerlessKubernetesClusters()
88 if err != nil {
89 t.Errorf("Error = %++v", err)
90 } else {
91 for _, cluster := range clusters {
92 t.Logf("Cluster = %#v", cluster)
93 }
94 }
95 }
0 package cs
1
2 import (
3 "fmt"
4 "github.com/denverdino/aliyungo/common"
5 "net/http"
6 )
7
8 type ClusterTokenReqeust struct {
9 //token 过期时间,如果不填写,则默认24小时过期
10 Expired int64 `json:"expired"`
11 IsPermanently bool `json:"is_permanently"`
12 }
13
14 type ClusterTokenResponse struct {
15 Created int64 ` json:"created"`
16 Updated int64 `json:"updated"`
17 Expired int64 ` json:"expired"`
18
19 ClusterID string ` json:"cluster_id"`
20
21 Token string ` json:"token"`
22 IsActive int ` json:"is_active"`
23 }
24
25 func (client *Client) CreateClusterToken(clusterId string, request *ClusterTokenReqeust) (*ClusterTokenResponse, error) {
26 response := &ClusterTokenResponse{}
27 err := client.Invoke("", http.MethodPost, "/clusters/"+clusterId+"/token", nil, request, response)
28 return response, err
29 }
30
31 func (client *Client) RevokeToken(token string) error {
32 return client.Invoke("", http.MethodDelete, "/token/"+token+"/revoke", nil, nil, nil)
33 }
34
35 func (client *Client) DescribeClusterTokens(clusterId string) ([]*ClusterTokenResponse, error) {
36 response := make([]*ClusterTokenResponse, 0)
37 err := client.Invoke("", http.MethodGet, "/clusters/"+clusterId+"/tokens", nil, nil, &response)
38 return response, err
39 }
40
41 func (client *Client) DescribeClusterToken(clusterId, token string) (*ClusterTokenResponse, error) {
42 if clusterId == "" || token == "" {
43 return nil, common.GetCustomError("InvalidParamter", "The clusterId or token is empty")
44 }
45 tokenInfo := &ClusterTokenResponse{}
46 err := client.Invoke("", http.MethodGet, fmt.Sprintf("/clusters/%s/tokens/%s", clusterId, token), nil, nil, tokenInfo)
47 return tokenInfo, err
48 }
0 package cs
1
2 import (
3 "testing"
4 "time"
5 )
6
7 func Test_CreateClusterToken(t *testing.T) {
8 client := NewTestClientForDebug()
9
10 req := &ClusterTokenReqeust{
11 Expired: time.Now().Unix() + 86400,
12 IsPermanently: false,
13 }
14
15 token, err := client.CreateClusterToken(TestClusterId, req)
16 if err != nil {
17 t.Fatalf("Error %++v", err)
18 } else {
19 t.Logf("Token = %++v", token)
20 }
21 }
22
23 func Test_RevokeClusterToken(t *testing.T) {
24 client := NewTestClientForDebug()
25 req := &ClusterTokenReqeust{
26 Expired: time.Now().Unix() + 86400,
27 IsPermanently: false,
28 }
29
30 token, err := client.CreateClusterToken(TestClusterId, req)
31 if err != nil {
32 t.Fatalf("Error = %++v", err)
33 } else {
34 err = client.RevokeToken(token.Token)
35 if err != nil {
36 t.Fatalf("Error = %++v", err)
37 } else {
38 tokens, err := client.DescribeClusterTokens(TestClusterId)
39 if err != nil {
40 t.Fatalf("Error %++v", err)
41 } else {
42 for _, token := range tokens {
43 t.Logf("Token = %++v", token)
44 }
45 }
46 }
47 }
48 }
49
50 func Test_DescribeClusterTokens(t *testing.T) {
51 client := NewTestClientForDebug()
52
53 tokens, err := client.DescribeClusterTokens(TestClusterId)
54 if err != nil {
55 t.Fatalf("Error %++v", err)
56 } else {
57 for _, token := range tokens {
58 t.Logf("Token = %++v", token)
59 }
60 }
61 }
62
63 func Test_DescribeClusterToken(t *testing.T) {
64 client := NewTestClientForDebug()
65
66 token, err := client.DescribeClusterToken(TestClusterId, TestToken)
67 if err != nil {
68 t.Fatalf("Error %++v", err)
69 } else {
70 t.Logf("Token = %++v", token)
71 }
72 }
6363 return NewECSClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
6464 }
6565
66 //only for Hangzhou Regional Domain
67 func NewECSClientWithSecurityToken4RegionalDomain(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
68 endpoint := os.Getenv("ECS_ENDPOINT")
69 if endpoint != "" {
70 return NewECSClientWithSecurityToken(accessKeyId, accessKeySecret, securityToken, regionID)
71 }
72
73 return NewECSClientWithEndpointAndSecurityToken4RegionalDomain(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
74 }
75
6676 func NewECSClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string, regionID common.Region) *Client {
6777 return NewECSClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, "", regionID)
6878 }
7787 WithServiceCode(ECSServiceCode).
7888 WithRegionID(regionID).
7989 InitClient()
90 return client
91 }
92
93 func NewECSClientWithEndpointAndSecurityToken4RegionalDomain(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
94 client := &Client{}
95 client.WithEndpoint(endpoint).
96 WithVersion(ECSAPIVersion).
97 WithAccessKeyId(accessKeyId).
98 WithAccessKeySecret(accessKeySecret).
99 WithSecurityToken(securityToken).
100 WithServiceCode(ECSServiceCode).
101 WithRegionID(regionID).
102 InitClient4RegionalDomain()
80103 return client
81104 }
82105
96119 return NewVPCClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
97120 }
98121
122 //Only for Hangzhou
123 func NewVPCClientWithSecurityToken4RegionalDomain(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
124 endpoint := os.Getenv("VPC_ENDPOINT")
125 if endpoint != "" {
126 return NewVPCClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
127 }
128
129 return NewVPCClientWithEndpointAndSecurityToken4RegionalDomain(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
130 }
131
99132 func NewVPCClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string, regionID common.Region) *Client {
100133 return NewVPCClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, "", regionID)
101134 }
113146 return client
114147 }
115148
149 //Only for Hangzhou
150 func NewVPCClientWithEndpointAndSecurityToken4RegionalDomain(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
151 client := &Client{}
152 client.WithEndpoint(endpoint).
153 WithVersion(VPCAPIVersion).
154 WithAccessKeyId(accessKeyId).
155 WithAccessKeySecret(accessKeySecret).
156 WithSecurityToken(securityToken).
157 WithServiceCode(VPCServiceCode).
158 WithRegionID(regionID).
159 InitClient4RegionalDomain()
160 return client
161 }
162
116163 // ---------------------------------------
117164 // NewVPCClientWithRegion creates a new instance of VPC client automatically get endpoint
118165 // ---------------------------------------
00 package ecs
11
22 import (
3 "github.com/denverdino/aliyungo/common"
4 "github.com/magiconair/properties/assert"
5 "os"
36 "testing"
47 )
58
7275 }
7376 }
7477 }
78
79 func Test_NewVPCClientWithSecurityToken4RegionalDomain(t *testing.T) {
80 client := NewVPCClientWithSecurityToken4RegionalDomain(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, common.Beijing)
81 assert.Equal(t, client.GetEndpoint(), "https://vpc-vpc.cn-beijing.aliyuncs.com")
82
83 os.Setenv("VPC_ENDPOINT", "vpc.aliyuncs.com")
84 client = NewVPCClientWithSecurityToken4RegionalDomain(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, common.Beijing)
85 assert.Equal(t, client.GetEndpoint(), "vpc.aliyuncs.com")
86 }
1313 TestSecurityToken = os.Getenv("SecurityToken")
1414 TestRegionID = common.Region(os.Getenv("RegionId"))
1515 TestVpcId = os.Getenv("VpcId")
16 TestVswitchID = os.Getenv("TestVswitchID")
1617
1718 TestInstanceId = os.Getenv("InstanceId")
18 TestSecurityGroupId = "MY_TEST_SECURITY_GROUP_ID"
19 TestImageId = "MY_IMAGE_ID"
19 TestSecurityGroupId = os.Getenv("TestSecurityGroupId")
20 TestResourceGroupId = os.Getenv("TestResourceGroupId")
21 TestImageId = os.Getenv("TestImageId")
2022 TestAccountId = "MY_TEST_ACCOUNT_ID" //Get from https://account.console.aliyun.com
21 TestInstanceType = "ecs.n4.large"
23 TestInstanceType = os.Getenv("InstanceType")
2224 TestVSwitchID = "MY_TEST_VSWITCHID"
2325
2426 TestIAmRich = false
5860
5961 func NetTestLocationClientForDebug() *Client {
6062 if testLocationClient == nil {
61 testLocationClient = NewECSClient(TestAccessKeyId, TestAccessKeySecret, TestRegionID)
63 testLocationClient = NewECSClientWithSecurityToken4RegionalDomain(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, TestRegionID)
6264 testLocationClient.SetDebug(true)
6365 }
6466
2525 DiskCategoryEphemeralSSD = DiskCategory("ephemeral_ssd")
2626 DiskCategoryCloudEfficiency = DiskCategory("cloud_efficiency")
2727 DiskCategoryCloudSSD = DiskCategory("cloud_ssd")
28 DiskCategoryCloudESSD = DiskCategory("cloud_essd")
29 )
30
31 // Performance Level of disks
32 type DiskPerformanceLevel string
33
34 const (
35 DiskPL0 = DiskCategory("PL0")
36 DiskPL1 = DiskCategory("PL1")
37 DiskPL2 = DiskCategory("PL2")
38 DiskPL3 = DiskCategory("PL3")
2839 )
2940
3041 // Status of disks
95106 AttachedTime util.ISO6801Time
96107 DetachedTime util.ISO6801Time
97108 DiskChargeType DiskChargeType
109 StorageSetId string
110 PerformanceLevel DiskPerformanceLevel
98111 }
99112
100113 type DescribeDisksResponse struct {
138151 Encrypted bool
139152 DiskCategory DiskCategory
140153 Size int
154 Tag map[string]string
141155 SnapshotId string
142156 ClientToken string
157 KMSKeyID string
158 StorageSetId string
159
160 PerformanceLevel DiskPerformanceLevel
143161 }
144162
145163 type CreateDisksResponse struct {
346364 if err != nil {
347365 return err
348366 }
349 if disks == nil || len(disks) == 0 {
367 if len(disks) == 0 {
350368 return common.GetClientErrorFromString("Not found")
351369 }
352370 if disks[0].Status == status {
44 "time"
55
66 "github.com/denverdino/aliyungo/common"
7 "github.com/denverdino/aliyungo/util"
78 )
89
910 type CreateNetworkInterfaceArgs struct {
10 RegionId common.Region
11 VSwitchId string
12 PrimaryIpAddress string // optional
13 SecurityGroupId string
14 NetworkInterfaceName string // optional
15 Description string // optional
16 ClientToken string // optional
11 RegionId common.Region
12 VSwitchId string
13 PrimaryIpAddress string // optional
14 SecurityGroupId string
15 NetworkInterfaceName string // optional
16 Description string // optional
17 ClientToken string // optional
18 Tag map[string]string // optional
19 ResourceGroupId string // optional
20 SecurityGroupIds []string `query:"list"` // optional
21 PrivateIpAddress []string `query:"list"` // optional
22 SecondaryPrivateIpAddressCount int
1723 }
1824
1925 type CreateNetworkInterfaceResponse struct {
3238 type DescribeNetworkInterfacesArgs struct {
3339 RegionId common.Region
3440 VSwitchId string
41 VpcID string
3542 PrimaryIpAddress string
43 PrivateIpAddress []string `query:"list"`
3644 SecurityGroupId string
3745 NetworkInterfaceName string
3846 Type string
4553 NetworkInterfaceId string
4654 NetworkInterfaceName string
4755 PrimaryIpAddress string
48 MacAddress string
49 Status string
50 PrivateIpAddress string
56 PrivateIpSets struct {
57 PrivateIpSet []PrivateIpType
58 }
59 MacAddress string
60 Status string
61 Type string
62 VpcId string
63 VSwitchId string
64 ZoneId string
65 AssociatedPublicIp AssociatedPublicIp
66 SecurityGroupIds struct {
67 SecurityGroupId []string
68 }
69 Description string
70 InstanceId string
71 CreationTime util.ISO6801Time
72 PrivateIpAddress string
73 }
74
75 type PrivateIpType struct {
76 PrivateIpAddress string
77 Primary bool
78 AssociatedPublicIp AssociatedPublicIp
79 }
80
81 type AssociatedPublicIp struct {
82 PublicIpAddress string
83 AllocationId string
5184 }
5285
5386 type DescribeNetworkInterfacesResponse struct {
74107 type ModifyNetworkInterfaceAttributeArgs struct {
75108 RegionId common.Region
76109 NetworkInterfaceId string
77 SecurityGroupId []string
110 SecurityGroupId []string `query:"list"`
78111 NetworkInterfaceName string
79112 Description string
80113 }
81114 type ModifyNetworkInterfaceAttributeResponse common.Response
115
116 type UnassignPrivateIpAddressesArgs struct {
117 RegionId common.Region
118 NetworkInterfaceId string
119 PrivateIpAddress []string `query:"list"`
120 }
121
122 type UnassignPrivateIpAddressesResponse common.Response
123
124 type AssignPrivateIpAddressesArgs struct {
125 RegionId common.Region
126 NetworkInterfaceId string
127 PrivateIpAddress []string `query:"list"` // optional
128 SecondaryPrivateIpAddressCount int // optional
129 }
130
131 type AssignPrivateIpAddressesResponse struct {
132 common.Response
133
134 AssignedPrivateIpAddressesSet struct {
135 NetworkInterfaceId string
136 PrivateIpSet struct {
137 PrivateIpAddress []string
138 }
139 }
140 }
82141
83142 func (client *Client) CreateNetworkInterface(args *CreateNetworkInterfaceArgs) (resp *CreateNetworkInterfaceResponse, err error) {
84143 resp = &CreateNetworkInterfaceResponse{}
116175 return resp, err
117176 }
118177
178 func (client *Client) UnassignPrivateIpAddresses(args *UnassignPrivateIpAddressesArgs) (resp *UnassignPrivateIpAddressesResponse, err error) {
179 resp = &UnassignPrivateIpAddressesResponse{}
180 err = client.Invoke("UnassignPrivateIpAddresses", args, resp)
181 return resp, err
182 }
183
184 func (client *Client) AssignPrivateIpAddresses(args *AssignPrivateIpAddressesArgs) (resp *AssignPrivateIpAddressesResponse, err error) {
185 resp = &AssignPrivateIpAddressesResponse{}
186 err = client.Invoke("AssignPrivateIpAddresses", args, resp)
187 return resp, err
188 }
189
119190 // Default timeout value for WaitForInstance method
120191 const NetworkInterfacesDefaultTimeout = 120
121192
0 package ecs
1
2 import (
3 "github.com/denverdino/aliyungo/common"
4 "testing"
5 "time"
6 )
7
8 func TestAssignPrivateIPAddresses(t *testing.T) {
9 req := AssignPrivateIpAddressesArgs{
10 RegionId: common.Beijing,
11 NetworkInterfaceId: "eni-testeni",
12 PrivateIpAddress: []string{"192.168.1.200", "192.168.1.201"},
13 }
14 client := NewTestClient()
15 assignPrivateIpAddressesResponse, err := client.AssignPrivateIpAddresses(&req)
16 if err != nil {
17 t.Errorf("Failed to AssignPrivateIpAddresses: %v", err)
18 }
19
20 if assignPrivateIpAddressesResponse.AssignedPrivateIpAddressesSet.NetworkInterfaceId != "eni-testeni" {
21 t.Errorf("assert network id mismatch.%s\n", assignPrivateIpAddressesResponse.AssignedPrivateIpAddressesSet.NetworkInterfaceId)
22 }
23
24 time.Sleep(5 * time.Second)
25
26 req = AssignPrivateIpAddressesArgs{
27 RegionId: common.Beijing,
28 NetworkInterfaceId: "eni-testeni",
29 SecondaryPrivateIpAddressCount: 1,
30 }
31
32 _, err = client.AssignPrivateIpAddresses(&req)
33 if err != nil {
34 t.Errorf("Failed to AssignPrivateIpAddresses: %v", err)
35 }
36 }
37
38 func TestDescribeENI(t *testing.T) {
39 req := DescribeNetworkInterfacesArgs{
40 RegionId: common.Beijing,
41 NetworkInterfaceId: []string{"eni-testeni"},
42 }
43 client := NewTestClient()
44 resp, err := client.DescribeNetworkInterfaces(&req)
45 if err != nil {
46 t.Errorf("Failed to DescribeNetworkInterfaces: %v", err)
47 }
48 if len(resp.NetworkInterfaceSets.NetworkInterfaceSet[0].PrivateIpSets.PrivateIpSet) != 4 {
49 t.Errorf("assert network private ip count be 4, %+v", resp.NetworkInterfaceSets.NetworkInterfaceSet[0].PrivateIpSets.PrivateIpSet)
50 }
51 t.Logf("%+v", resp.NetworkInterfaceSets.NetworkInterfaceSet[0])
52 }
53
54 func TestFindENIByPrivateIP(t *testing.T) {
55 req := DescribeNetworkInterfacesArgs{
56 RegionId: common.Shanghai,
57 VpcID: "vpc-xxx",
58 PrivateIpAddress: []string{"192.168.108.191"},
59 }
60 client := NewTestClient()
61 resp, err := client.DescribeNetworkInterfaces(&req)
62 if err != nil {
63 t.Errorf("Failed to DescribeNetworkInterfaces: %v", err)
64 }
65 t.Logf("%+v", resp.NetworkInterfaceSets.NetworkInterfaceSet)
66 }
67
68 func TestUnAssignPrivateIPAddresses(t *testing.T) {
69 req := UnassignPrivateIpAddressesArgs{
70 RegionId: common.Beijing,
71 NetworkInterfaceId: "eni-testeni",
72 PrivateIpAddress: []string{"192.168.1.200", "192.168.1.201"},
73 }
74 client := NewTestClient()
75 _, err := client.UnassignPrivateIpAddresses(&req)
76 if err != nil {
77 t.Errorf("Failed to UnAssignPrivateIpAddresses: %v", err)
78 }
79 }
80
81 func TestModifyNetworkInterfaceAttribute(t *testing.T) {
82 args := &ModifyNetworkInterfaceAttributeArgs{
83 RegionId: common.Shanghai,
84 NetworkInterfaceId: "eni-testeni",
85 SecurityGroupId: []string{"sg-xxx", "sg-yyy"},
86 }
87
88 client := NewTestClient()
89 _, err := client.ModifyNetworkInterfaceAttribute(args)
90 if err != nil {
91 t.Errorf("failed to ModifyNetworkInterfaceAttribute: %v", err)
92 }
93 }
94
95 func TestCreateNetworkInterface(t *testing.T) {
96 args := &CreateNetworkInterfaceArgs{
97 RegionId: common.Shanghai,
98 VSwitchId: "vsw-xxx",
99 SecurityGroupIds: []string{"sg-xxx", "sg-yyy"},
100 SecondaryPrivateIpAddressCount: 9,
101 }
102 client := NewTestClient()
103 resp, err := client.CreateNetworkInterface(args)
104 if err != nil {
105 t.Errorf("failed to CreateNetworkInterface: %v", err)
106 }
107 t.Logf("new eni info: %+v", resp)
108 }
312312 if err != nil {
313313 return err
314314 }
315 if images == nil || len(images) == 0 {
315 if len(images) == 0 {
316316 args.Status = ImageStatusAvailable
317317 images, _, er := client.DescribeImages(&args)
318318 if er == nil && len(images) == 1 {
33
44 type DescribeInstanceTypesArgs struct {
55 InstanceTypeFamily string
6 InstanceTypes []string `query:"list"`
67 }
78
89 //
910 // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancetypeitemtype
1011 type InstanceTypeItemType struct {
11 InstanceTypeId string
12 CpuCoreCount int
13 MemorySize float64
14 InstanceTypeFamily string
15 GPUAmount int
16 GPUSpec string
17 InitialCredit int
18 BaselineCredit int
19 EniQuantity int
20 LocalStorageCapacity int
21 LocalStorageAmount int
22 LocalStorageCategory string
12 InstanceTypeId string
13 CpuCoreCount int
14 MemorySize float64
15 InstanceTypeFamily string
16 GPUAmount int
17 GPUSpec string
18 InitialCredit int
19 BaselineCredit int
20 EniQuantity int
21 EniPrivateIpAddressQuantity int
22 LocalStorageCapacity int
23 LocalStorageAmount int
24 LocalStorageCategory string
2325 }
2426
2527 type DescribeInstanceTypesResponse struct {
44 )
55
66 func TestDescribeInstanceTypes(t *testing.T) {
7
87 client := NewTestClient()
98 instanceTypes, err := client.DescribeInstanceTypes()
109 if err != nil {
1312 for _, instanceType := range instanceTypes {
1413 t.Logf("InstanceType: %++v", instanceType)
1514 }
15
16 instanceTypes, err = client.DescribeInstanceTypesNew(&DescribeInstanceTypesArgs{
17 InstanceTypes: []string{"ecs.ec5.24xlarge", "ecs.ddh6s.custom.c4m48"},
18 })
19 if err != nil {
20 t.Fatalf("Failed to DescribeInstanceTypesNew: %v", err)
21 }
22 for _, instanceType := range instanceTypes {
23 t.Logf("InstanceType: %++v", instanceType)
24 }
1625 }
229229 //
230230 // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instanceattributestype
231231 type InstanceAttributesType struct {
232 AutoReleaseTime string
232233 InstanceId string
233234 InstanceName string
234235 Description string
235236 ImageId string
236237 RegionId common.Region
237238 ZoneId string
238 CPU int
239 Cpu int
240 CpuOptions CpuOptionsType
239241 Memory int
240242 ClusterId string
241243 InstanceType string
247249 SecurityGroupIds struct {
248250 SecurityGroupId []string
249251 }
250 PublicIpAddress IpAddressSetType
251 InnerIpAddress IpAddressSetType
252 InstanceNetworkType string //enum Classic | Vpc
253 InternetMaxBandwidthIn int
254 InternetMaxBandwidthOut int
255 InternetChargeType common.InternetChargeType
256 CreationTime util.ISO6801Time //time.Time
257 VpcAttributes VpcAttributesType
258 EipAddress EipAddressAssociateType
259 IoOptimized StringOrBool
260 InstanceChargeType common.InstanceChargeType
261 ExpiredTime util.ISO6801Time
262 Tags struct {
252 PublicIpAddress IpAddressSetType
253 InnerIpAddress IpAddressSetType
254 InstanceNetworkType string //enum Classic | Vpc
255 InternetMaxBandwidthIn int
256 InternetMaxBandwidthOut int
257 InternetChargeType common.InternetChargeType
258 CreationTime util.ISO6801Time //time.Time
259 CreditSpecification string
260 DedicatedHostAttribute DedicatedHostAttributeType
261 DedicatedInstanceAttribute DedicatedInstanceAttributeType
262 DeletionProtection bool
263 DeploymentSetGroupNo int
264 DeploymentSetId string
265 DeviceAvailable bool
266 EcsCapacityReservationAttr EcsCapacityReservationAttrType
267 VpcAttributes VpcAttributesType
268 EipAddress EipAddressAssociateType
269 IoOptimized StringOrBool
270 InstanceChargeType common.InstanceChargeType
271 ExpiredTime util.ISO6801Time
272 GPUAmount int
273 GPUSpec string
274 HibernationOptions HibernationOptionsType
275 HpcClusterId string
276 ISP string
277 LocalStorageAmount int
278 LocalStorageCapacity int
279 MetadataOptions MetadataOptionsType
280 NetworkInterfaces struct {
281 NetworkInterface []InstanceNetworkInterfaceType
282 }
283 OSName string
284 OSNameEn string
285 OSType string
286 RdmaIpAddress RdmaIpAddressType
287 Recyclable bool
288 ResourceGroupId string
289 SaleCycle string
290 SpotDuration int
291 StartTime string
292 StoppedMode string
293 Tags struct {
263294 Tag []TagItemType
264295 }
296 VlanId string
265297 SpotStrategy SpotStrategyType
266298 SpotPriceLimit float64
267299 KeyPairName string
300 }
301
302 type CpuOptionsType struct {
303 CoreCount int
304 Numa string
305 ThreadsPerCore int
306 }
307
308 type DedicatedHostAttributeType struct {
309 DedicatedHostClusterId string
310 DedicatedHostId string
311 DedicatedHostName string
312 }
313
314 type DedicatedInstanceAttributeType struct {
315 Affinity string
316 Tenancy string
317 }
318
319 type EcsCapacityReservationAttrType struct {
320 CapacityReservationId string
321 CapacityReservationPreference string
322 }
323
324 type HibernationOptionsType struct {
325 Configured bool
326 }
327
328 type MetadataOptionsType struct {
329 HttpEndpoint string
330 HttpPutResponseHopLimit int
331 HttpTokens string
332 }
333
334 type InstanceNetworkInterfaceType struct {
335 Ipv6Sets struct {
336 Ipv6Set []Ipv6SetType
337 }
338 MacAddress string
339 NetworkInterfaceId string
340 PrimaryIpAddress string
341 Type string
342 PrivateIpSets struct {
343 PrivateIpSet []PrivateIpSetType
344 }
345 }
346
347 type Ipv6SetType struct {
348 Ipv6Address string
349 }
350
351 type PrivateIpSetType struct {
352 Primary bool
353 PrivateIpAddress string
354 }
355
356 type RdmaIpAddressType struct {
357 RdmaIpAddress []string
268358 }
269359
270360 type DescribeInstanceAttributeResponse struct {
400490 PrivateIpAddresses string
401491 InnerIpAddresses string
402492 PublicIpAddresses string
493 EipAddresses string
494 InstanceChargeType common.InstanceChargeType
495 InternetChargeType common.InternetChargeType
496 ImageId string
497 LockReason string
403498 SecurityGroupId string
404 Tag map[string]string
405499 InstanceType string
406500 SpotStrategy SpotStrategyType
407501 common.Pagination
502 NextToken string
503 MaxResults int
504 Filter []Filter
505 IoOptimized *bool
506 InstanceTypeFamily string
507 KeyPairName string
508 ResourceGroupId string
509 HpcClusterId string
510 RdmaIpAddresses string
511 DryRun bool
512 HttpEndpoint string
513 HttpTokens string
514 Tag []TagType
408515 }
409516
410517 type DescribeInstancesResponse struct {
411518 common.Response
412519 common.PaginationResult
520 NextToken string
413521 Instances struct {
414522 Instance []InstanceAttributesType
415523 }
487595 Description string
488596 Device string
489597 DeleteWithInstance bool
598 PerformanceLevel string
599 KMSKeyId string
600 Encrypted bool
490601 }
491602
492603 type SystemDiskType struct {
493 Size int
494 Category DiskCategory //Enum cloud, ephemeral, ephemeral_ssd
495 DiskName string
496 Description string
604 Size int
605 Category DiskCategory //Enum cloud, ephemeral, ephemeral_ssd
606 DiskName string
607 Description string
608 PerformanceLevel DiskPerformanceLevel
609 AutoSnapshotPolicyId string
497610 }
498611
499612 type IoOptimized string
544657 RegionId common.Region
545658 ZoneId string
546659 ImageId string
660 ImageFamily string
547661 InstanceType string
548662 SecurityGroupId string
549663 InstanceName string
553667 InternetMaxBandwidthOut int
554668 HostName string
555669 Password string
670 PasswordInherit bool
671 DeploymentSetId string
672 ClusterId string
673 VlanId string
674 InnerIpAddress string
556675 IoOptimized IoOptimized
676 UseAdditionalService *bool
557677 SystemDisk SystemDiskType
558678 DataDisk []DataDiskType
559679 VSwitchId string
567687 AutoRenewPeriod int
568688 SpotStrategy SpotStrategyType
569689 SpotPriceLimit float64
690 SpotDuration *int
691 SpotInterruptionBehavior string
570692 KeyPairName string
571693 RamRoleName string
572694 SecurityEnhancementStrategy SecurityEnhancementStrategy
695 ResourceGroupId string
696 HpcClusterId string
697 DryRun bool
698 DedicatedHostId string
699 CreditSpecification string
700 DeletionProtection bool
701 Affinity string
702 Tenancy string
703 StorageSetId string
704 StorageSetPartitionNumber int
705 HttpEndpoint string
706 HttpTokens string
707 PrivatePoolOptions []PrivatePoolOptionsType
708 Tag []TagType
709 }
710
711 type PrivatePoolOptionsType struct {
712 MatchCriteria string
713 Id string
714 }
715
716 type TagType struct {
717 Key string
718 Value string
573719 }
574720
575721 type CreateInstanceResponse struct {
33 "encoding/json"
44 "fmt"
55 "testing"
6 "time"
67
78 "github.com/denverdino/aliyungo/common"
89 )
331332 RegionId: TestRegionID,
332333 Pagination: common.Pagination{
333334 PageNumber: 1,
334 PageSize: 100,
335 PageSize: 2,
335336 },
336337 //SecurityToken: TestSecurityToken,
337338 }
345346 }
346347 }
347348 }
349
350 func Test_CreateDescribeAndDeletiongInstances(t *testing.T) {
351 if TestAccessKeyId == "" || TestAccessKeySecret == "" || TestVpcId == "" || TestVswitchID == "" {
352 t.Skip("missing env")
353 return
354 }
355 client := NewTestClientForDebug()
356
357 //createInstance
358 createInstanceArgs := &CreateInstanceArgs{
359 RegionId: TestRegionID,
360 InstanceType: TestInstanceType,
361 VSwitchId: TestVswitchID,
362 ResourceGroupId: TestResourceGroupId,
363 SecurityGroupId: TestSecurityGroupId,
364 ImageId: TestImageId,
365 InstanceChargeType: common.PostPaid,
366 }
367
368 instanceId, err := client.CreateInstance(createInstanceArgs)
369 if err != nil {
370 t.Fatalf("CreateInstance error %v", err)
371 }
372
373 //wait for stoppend
374 err = client.WaitForInstance(instanceId, Stopped, 60)
375 if err != nil {
376 t.Fatalf("WaitForInstance Stopped error %v", err)
377 }
378
379 // start Instance
380 err = client.StartInstance(instanceId)
381 if err != nil {
382 t.Fatalf("StartInstance %s error %v", instanceId, err)
383 }
384
385 //wait for running
386 err = client.WaitForInstance(instanceId, Running, 0)
387 if err != nil {
388 t.Fatalf("WaitForInstance Running error %v", err)
389 }
390
391 time.Sleep(10 * time.Second)
392 t.Logf("After 30s ,describe instance %s", instanceId)
393
394 //describe Instances
395 instanceB, _ := json.Marshal([]string{instanceId})
396 describeInstancesArgs := &DescribeInstancesArgs{
397 RegionId: TestRegionID,
398 InstanceIds: string(instanceB),
399 }
400
401 instances, pageInfo, err := client.DescribeInstances(describeInstancesArgs)
402 if err != nil {
403 t.Fatalf("Error %v", err)
404 }
405
406 t.Logf("PageInfo = %#v", pageInfo)
407 for _, instance := range instances {
408 t.Logf("Instance = %#v", instance)
409 }
410
411 time.Sleep(30 * time.Second)
412 t.Logf("After 30s ,delete instance %s", instanceId)
413
414 //stop instance
415 err = client.StopInstance(instanceId, true)
416 if err != nil {
417 t.Fatalf("StopInstance %s error %v", instanceId, err)
418 }
419
420 //wait for stoppend
421 err = client.WaitForInstance(instanceId, Stopped, 60)
422 if err != nil {
423 t.Fatalf("WaitForInstance Stopped error %v", err)
424 }
425 t.Logf("Instance %s is stopped successfully.", instanceId)
426
427 // delete instance
428 err = client.DeleteInstance(instanceId)
429 if err != nil {
430 t.Fatalf("DeleteInstance %s error %v", instanceId, err)
431 }
432 t.Logf("Instance %s is deleted successfully.", instanceId)
433
434 }
11
22 import (
33 "github.com/denverdino/aliyungo/common"
4 )
5
6 type NatType string
7
8 const (
9 NgwNatTypeNormal = NatType("Normal")
10 NgwNatTypeEnhanced = NatType("Enhanced")
411 )
512
613 type BandwidthPackageType struct {
1219 type CreateNatGatewayArgs struct {
1320 RegionId common.Region
1421 VpcId string
22 VSwitchId string
1523 Spec string
1624 BandwidthPackage []BandwidthPackageType
1725 Name string
1826 Description string
27 NatType NatType
1928 ClientToken string
2029 }
2130
7483 Spec string
7584 Status string
7685 VpcId string
86 NatType NatType
7787 }
7888
7989 type DescribeNatGatewayResponse struct {
3737 }
3838 }
3939 }
40
41 func TestClient_CreateNatGateway(t *testing.T) {
42 client := NewVpcTestClientForDebug()
43 args := &CreateNatGatewayArgs{
44 RegionId: TestRegionID,
45 VpcId: TestVpcId,
46 VSwitchId: TestVswitchID,
47 NatType: NgwNatTypeEnhanced,
48 }
49
50 resp, err := client.CreateNatGateway(args)
51 if err != nil {
52 t.Fatalf("Error %++v", err)
53 } else {
54 t.Logf("ngw id :%s", resp.NatGatewayId)
55 }
56 }
8585 type EipInstanceType string
8686
8787 const (
88 EcsInstance = "EcsInstance"
89 SlbInstance = "SlbInstance"
90 Nat = "Nat"
91 HaVip = "HaVip"
88 EcsInstance = "EcsInstance"
89 SlbInstance = "SlbInstance"
90 Nat = "Nat"
91 HaVip = "HaVip"
92 NetworkInterface = "NetworkInterface"
93 )
94
95 type AssociateEipAddressMode string
96
97 const (
98 NAT = "NAT"
99 MULTI_BINDED = "MULTI_BINDED"
100 BINDED = "BINDED"
92101 )
93102
94103 type AssociateEipAddressArgs struct {
95 AllocationId string
96 InstanceId string
97 InstanceType EipInstanceType
104 AllocationId string
105 InstanceId string
106 InstanceRegionId common.Region
107 InstanceType EipInstanceType
108 PrivateIpAddress string
109 Mode AssociateEipAddressMode
98110 }
99111
100112 type AssociateEipAddressResponse struct {
101113 common.Response
102114 }
103115
104 // AssociateEipAddress associates EIP address to VM instance
105 //
106 // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&associateeipaddress
116 // AssociateEipAddress associates EIP address to instance
117 //
118 // You can read doc at https://help.aliyun.com/api/vpc/AssociateEipAddress.html
107119 func (client *Client) AssociateEipAddress(allocationId string, instanceId string) error {
108120 args := AssociateEipAddressArgs{
109121 AllocationId: allocationId,
131143 type AssociatedInstanceType string
132144
133145 const (
134 AssociatedInstanceTypeEcsInstance = AssociatedInstanceType("EcsInstance")
135 AssociatedInstanceTypeSlbInstance = AssociatedInstanceType("SlbInstance")
136 AssociatedInstanceTypeNat = AssociatedInstanceType("Nat")
137 AssociatedInstanceTypeHaVip = AssociatedInstanceType("HaVip")
146 AssociatedInstanceTypeEcsInstance = AssociatedInstanceType("EcsInstance")
147 AssociatedInstanceTypeSlbInstance = AssociatedInstanceType("SlbInstance")
148 AssociatedInstanceTypeNat = AssociatedInstanceType("Nat")
149 AssociatedInstanceTypeHaVip = AssociatedInstanceType("HaVip")
150 AssociatedInstanceTypeNetworkInterface = AssociatedInstanceType("NetworkInterface")
138151 )
139152
140153 type DescribeEipAddressesArgs struct {
142155 Status EipStatus //enum Associating | Unassociating | InUse | Available
143156 EipAddress string
144157 AllocationId string
145 AssociatedInstanceType AssociatedInstanceType //enum EcsInstance | SlbInstance | Nat | HaVip
158 AssociatedInstanceType AssociatedInstanceType //enum EcsInstance | SlbInstance | Nat | HaVip | NetworkInterface
146159 AssociatedInstanceId string //绑定的资源的Id。 这是一个过滤器性质的参数,若不指定,则表示不适用该条件对结果进行过滤。 如果要使用该过滤器,必须同时使用AssociatedInstanceType。若InstanceType为EcsInstance,则此处填写ECS实例Id。若InstanceType为SlbInstance,则此处填写VPC类型的私网SLB 的实例ID。若InstanceType为Nat,则此处填写NAT 的实例ID。。若InstanceType为HaVip,则此处填写HaVipId。
147160 common.Pagination
148161 }
157170 InstanceId string
158171 InstanceType string
159172 Bandwidth string // Why string
173 PrivateIpAddress string
160174 InternetChargeType common.InternetChargeType
161175 OperationLocks OperationLocksType
162176 AllocationTime util.ISO6801Time
217231 }
218232
219233 type UnallocateEipAddressArgs struct {
220 AllocationId string
221 InstanceId string
234 AllocationId string
235 InstanceId string
236 InstanceType EipInstanceType
237 PrivateIpAddress string
222238 }
223239
224240 type UnallocateEipAddressResponse struct {
235251 }
236252 response := UnallocateEipAddressResponse{}
237253 return client.Invoke("UnassociateEipAddress", &args, &response)
254 }
255
256 func (client *Client) NewUnassociateEipAddress(args *UnallocateEipAddressArgs) error {
257 response := UnallocateEipAddressResponse{}
258 return client.Invoke("UnassociateEipAddress", args, &response)
238259 }
239260
240261 type ReleaseEipAddressArgs struct {
8484
8585 }
8686
87 func TestClient_AssociateEipAddress_ENIIP(t *testing.T) {
88 client := NewVpcTestClientForDebug()
89 eipID := "eip-xxx"
90 eniID := "eni-yyy"
91 eniSecIP := "192.168.0.100"
92 region := common.Region("cn-hangzhou")
93
94 err := client.NewAssociateEipAddress(&AssociateEipAddressArgs{
95 AllocationId: eipID,
96 InstanceId: eniID,
97 InstanceType: NetworkInterface,
98 PrivateIpAddress: eniSecIP,
99 })
100 if err != nil {
101 t.Errorf("Failed to associate EIP address: %v", err)
102 }
103 err = client.WaitForEip(region, eipID, EipStatusInUse, DefaultTimeout)
104 if err != nil {
105 t.Errorf("Failed wait associate EIP address: %v", err)
106 }
107 err = client.NewUnassociateEipAddress(&UnallocateEipAddressArgs{
108 AllocationId: eipID,
109 InstanceId: eniID,
110 InstanceType: NetworkInterface,
111 PrivateIpAddress: eniSecIP,
112 })
113 if err != nil {
114 t.Errorf("Failed unassociate EIP address: %v", err)
115 }
116 }
117
87118 func TestClient_DescribeEipAddresses(t *testing.T) {
88119 client := NewVpcTestClientForDebug()
89120 args := &DescribeEipAddressesArgs{
0 package ecs
1
2 import "github.com/denverdino/aliyungo/common"
3
4 type DescribeRouteEntryListArgs struct {
5 RegionId string
6 RouteTableId string
7 DestinationCidrBlock string
8 IpVersion string
9 MaxResult int
10 NextHopId string
11 NextHopType string
12 NextToken string
13 RouteEntryId string
14 RouteEntryName string
15 RouteEntryType string
16 }
17
18 type DescribeRouteEntryListResponse struct {
19 common.Response
20 NextToken string
21 RouteEntrys struct {
22 RouteEntry []RouteEntry
23 }
24 }
25
26 type RouteEntry struct {
27 DestinationCidrBlock string
28 IpVersion string
29 RouteEntryId string
30 RouteEntryName string
31 RouteTableId string
32 Status string
33 Type string
34 NextHops struct {
35 NextHop []NextHop
36 }
37 }
38
39 type NextHop struct {
40 Enabled int
41 Weight int
42 NextHopId string
43 NextHopRegionId string
44 NextHopType string
45 NextHopRelatedInfo NextHopRelatedInfo
46 }
47
48 type NextHopRelatedInfo struct {
49 RegionId string
50 InstanceId string
51 InstanceType string
52 }
53
54 // DescribeRouteEntryList describes route entries
55 //
56 func (client *Client) DescribeRouteEntryList(args *DescribeRouteEntryListArgs) (*DescribeRouteEntryListResponse, error) {
57 response := &DescribeRouteEntryListResponse{}
58 err := client.Invoke("DescribeRouteEntryList", args, &response)
59 return response, err
60 }
0 package ecs
1
2 import (
3 "testing"
4 )
5
6 func TestClient_DescribeRouteEntry(t *testing.T) {
7 client := NewVpcTestClientForDebug()
8
9 nextHopId := "i-xxxx"
10 destinationCidrBlock := "172.xxx/x"
11 args := &DescribeRouteEntryListArgs{
12 RegionId: "cn-hangzhou",
13 RouteTableId: "vtb-xxxxx",
14 DestinationCidrBlock: destinationCidrBlock,
15 NextHopId: nextHopId,
16 RouteEntryType: "Custom",
17 }
18
19 response, err := client.DescribeRouteEntryList(args)
20
21 if err != nil {
22 t.Fatalf("Error %++v", err)
23 } else {
24 t.Logf("Result %++v", response)
25 }
26 }
9999 type NextHopType string
100100
101101 const (
102 NextHopIntance = NextHopType("Instance") //Default
103 NextHopTunnel = NextHopType("Tunnel")
104 NextHopTunnelRouterInterface = NextHopType("RouterInterface")
102 NextHopInstance = NextHopType("Instance") //Default
103 NextHopHaVip = NextHopType("HaVip")
104 NextHopRouterInterface = NextHopType("RouterInterface")
105 NextHopNetworkInterface = NextHopType("NetworkInterface")
106 NextHopVpnGateway = NextHopType("VpnGateway")
107 NextHopIPv6Gateway = NextHopType("IPv6Gateway")
108 NextHopTunnel = NextHopType("Tunnel")
105109 )
106110
107111 type CreateRouteEntryArgs struct {
1010 createArgs := CreateRouteEntryArgs{
1111 RouteTableId: routeTableId,
1212 DestinationCidrBlock: cidrBlock,
13 NextHopType: NextHopIntance,
13 NextHopType: NextHopInstance,
1414 NextHopId: instanceId,
1515 ClientToken: client.GenerateClientToken(),
1616 }
237237 for {
238238 interfaces, err := client.DescribeRouterInterfaces(&DescribeRouterInterfacesArgs{
239239 RegionId: regionId,
240 Filter: []Filter{Filter{Key: "RouterInterfaceId", Value: []string{interfaceId}}},
240 Filter: []Filter{{Key: "RouterInterfaceId", Value: []string{interfaceId}}},
241241 })
242242 if err != nil {
243243 return err
66
77 type NicType string
88 type Direction string
9 type SecurityGroupType string
910
1011 const (
1112 NicTypeInternet = NicType("internet")
1415 DirectionIngress = Direction("ingress")
1516 DirectionEgress = Direction("egress")
1617 DirectionAll = Direction("all")
18
19 SecurityGroupTypeNormal = SecurityGroupType("normal")
20 SecurityGroupTypeEnterprise = SecurityGroupType("enterprise")
1721 )
1822
1923 type IpProtocol string
9195 }
9296
9397 type DescribeSecurityGroupsArgs struct {
94 RegionId common.Region
95 VpcId string
98 RegionId common.Region
99 VpcId string
100 SecurityGroupIds []string
96101 common.Pagination
97102 }
98103
103108 SecurityGroupName string
104109 Description string
105110 VpcId string
111 SecurityGroupType SecurityGroupType // normal|enterprise
112 ServiceManaged bool
106113 CreationTime util.ISO6801Time
107114 }
108115
00 package ecs
11
22 import (
3 "os"
4 "strings"
35 "testing"
46
57 "github.com/denverdino/aliyungo/common"
3840 t.Logf("SecurityGroup Attribute: %++v", sga)
3941
4042 }
43 }
44 }
45
46 func TestSecurityGroups_BatchQuery(t *testing.T) {
47
48 client := NewTestClient()
49 arg := DescribeSecurityGroupsArgs{
50 RegionId: common.Region(os.Getenv("RegionId")),
51 SecurityGroupIds: strings.Split(os.Getenv("SecurityGroupIDs"), ","),
52 }
53
54 sgs, _, err := client.DescribeSecurityGroups(&arg)
55 if err != nil {
56 t.Errorf("Failed to DescribeSecurityGroups, error:%++v", err)
57 }
58 for _, sg := range sgs {
59 t.Logf("SecurityGroup: %++v", sg)
4160 }
4261 }
4362
125125 if err != nil {
126126 return err
127127 }
128 if snapshots == nil || len(snapshots) == 0 {
128 if len(snapshots) == 0 {
129129 return common.GetClientErrorFromString("Not found")
130130 }
131131 if snapshots[0].Progress == "100%" {
00 package ecs
11
2 import "github.com/denverdino/aliyungo/common"
2 import (
3 "time"
4
5 "github.com/denverdino/aliyungo/common"
6 )
7
8 type SnatEntryStatus string
9
10 const (
11 SnatEntryStatusPending = SnatEntryStatus("Pending")
12 SnatEntryStatusAvailable = SnatEntryStatus("Available")
13 )
314
415 type CreateSnatEntryArgs struct {
516 RegionId common.Region
617 SnatTableId string
718 SourceVSwitchId string
819 SnatIp string
20 SourceCIDR string
921 }
1022
1123 type CreateSnatEntryResponse struct {
2032 SnatTableId string
2133 SourceCIDR string
2234 SourceVSwitchId string
23 Status string
35 Status SnatEntryStatus
2436 }
2537
2638 type DescribeSnatTableEntriesArgs struct {
27 RegionId common.Region
28 SnatTableId string
39 RegionId common.Region
40 SnatTableId string
41 SnatEntryId string
42 SnatEntryName string
43 SnatIp string
44 SourceCIDR string
45 SourceVSwitchId string
2946 common.Pagination
3047 }
3148
3855 }
3956
4057 type ModifySnatEntryArgs struct {
41 RegionId common.Region
42 SnatTableId string
43 SnatEntryId string
44 SnatIp string
58 RegionId common.Region
59 SnatTableId string
60 SnatEntryId string
61 SnatIp string
62 SnatEntryName string
4563 }
4664
4765 type ModifySnatEntryResponse struct {
100118 err := client.Invoke("DeleteSnatEntry", args, &response)
101119 return err
102120 }
121
122 // WaitForSnatEntryAvailable waits for SnatEntry to available status
123 func (client *Client) WaitForSnatEntryAvailable(regionId common.Region, snatTableId, snatEntryId string, timeout int) error {
124 if timeout <= 0 {
125 timeout = DefaultTimeout
126 }
127
128 args := &DescribeSnatTableEntriesArgs{
129 RegionId: regionId,
130 SnatTableId: snatTableId,
131 SnatEntryId: snatEntryId,
132 }
133
134 for {
135 snatEntries, _, err := client.DescribeSnatTableEntries(args)
136 if err != nil {
137 return err
138 }
139
140 if len(snatEntries) == 0 {
141 return common.GetClientErrorFromString("Not found")
142 }
143 if snatEntries[0].Status == SnatEntryStatusAvailable {
144 break
145 }
146
147 timeout = timeout - DefaultWaitForInterval
148 if timeout <= 0 {
149 return common.GetClientErrorFromString("Timeout")
150 }
151 time.Sleep(DefaultWaitForInterval * time.Second)
152 }
153 return nil
154 }
1313 t.Fatalf("Failed to DescribeBandwidthPackages: %v", err)
1414 }
1515 }
16
17 func TestCreateSnatEntryWithSourceCIDR(t *testing.T) {
18 client := NewTestClient()
19 args := CreateSnatEntryArgs{
20 RegionId: "cn-beijing",
21 SnatTableId: "stb-xxx",
22 SnatIp: "47.XX.XX.98",
23 SourceCIDR: "192.168.1.1/32",
24 }
25
26 _, err := client.CreateSnatEntry(&args)
27 if err != nil {
28 t.Errorf("failed to CreateSnatEntry with SourceCIDR: %v", err)
29 }
30 }
7575 VSwitchIds struct {
7676 VSwitchId []string
7777 }
78 CidrBlock string
79 VRouterId string
80 Description string
81 IsDefault bool
82 CreationTime util.ISO6801Time
78 CidrBlock string
79 VRouterId string
80 Description string
81 IsDefault bool
82 CreationTime util.ISO6801Time
83 SecondaryCidrBlocks struct {
84 SecondaryCidrBlock []string
85 }
86 RouterTableIds struct {
87 RouterTableIds []string
88 }
8389 }
8490
8591 type DescribeVpcsResponse struct {
163163 t.Logf("Instance %s is created successfully.", instanceId)
164164 instance, err := client.DescribeInstanceAttribute(instanceId)
165165 t.Logf("Instance: %++v %v", instance, err)
166
166167 err = client.WaitForInstance(instanceId, Stopped, 0)
168 if err != nil {
169 t.Errorf("Failed to wait instance to stopped %s: %v", instanceId, err)
170 }
167171
168172 err = client.StartInstance(instanceId)
169173 if err != nil {
11
22 import (
33 "encoding/base64"
4
54 "github.com/denverdino/aliyungo/common"
65 "github.com/denverdino/aliyungo/ecs"
76 )
8988 CreationTime string
9089 InternetMaxBandwidthIn int
9190 InternetMaxBandwidthOut int
91 SystemDiskSize int
9292 SystemDiskCategory string
9393 DataDisks struct {
9494 DataDisk []DataDiskItemType
166166 }
167167 return &response, nil
168168 }
169
170 type ModifyScalingConfigurationRequest struct {
171 ScalingConfigurationId string
172 IoOptimized string
173 DataDisk []DataDisk
174 SpotStrategy string
175 SpotPriceLimit []SpotPriceLimit
176 ScalingConfigurationName string
177 InstanceName string
178 HostName string
179 ImageId string
180 ImageName string
181 InstanceTypes []string
182 Cpu int
183 Memory int
184 InternetChargeType string
185 InternetMaxBandwidthOut int
186 SystemDisk SystemDisk
187 LoadBalancerWeight string
188 UserData string
189 KeyPairName string
190 RamRoleName string
191 PasswordInherit string
192 Tags string
193 DeploymentSetId string
194 SecurityGroupId string
195 Override bool
196 ResourceGroupId string
197 SecurityGroupIds []string
198 HpcClusterId string
199
200 InstanceDescription string
201 Ipv6AddressCount int
202
203 CreditSpecification string
204 ImageFamily string
205 DedicatedHostId string
206 Affinity string
207 Tenancy string
208 }
209
210 type DataDisk struct {
211 Size int
212 SnapshotId string
213 Category string
214 Device string
215 DeleteWithInstance bool
216 Encrypted bool
217 KMSKeyId string
218 DiskName string
219 Description string
220 AutoSnapshotPolicyId string
221 }
222
223 type SpotPriceLimit struct {
224 InstanceType string
225 PriceLimit float32
226 }
227
228 type SystemDisk struct {
229 Category string
230 Size int
231 DiskName string
232 Description string
233 AutoSnapshotPolicyId string
234 }
235
236 type ModifyScalingConfigurationResponse struct {
237 common.Response
238 }
239
240 func (client *Client) ModifyScalingConfiguration(args *ModifyScalingConfigurationRequest) (resp *ModifyScalingConfigurationResponse, err error) {
241 response := ModifyScalingConfigurationResponse{}
242 err = client.InvokeByFlattenMethod("ModifyScalingConfiguration", args, &response)
243
244 if err != nil {
245 return nil, err
246 }
247 return &response, nil
248 }
1414 InService = LifecycleState("InService")
1515 Pending = LifecycleState("Pending")
1616 Removing = LifecycleState("Removing")
17 )
18
19 type MultiAZPolicy string
20
21 const (
22 MultiAZPolicyPriority = MultiAZPolicy("PRIORITY")
23 MultiAZPolicyCostOptimized = MultiAZPolicy("COST_OPTIMIZED")
24 MultiAZPolicyBalance = MultiAZPolicy("BALANCE")
1725 )
1826
1927 type CreateScalingGroupArgs struct {
2634 // NOTE: Set MinSize, MaxSize and DefaultCooldown type to int pointer to distinguish zero value from unset value.
2735 MinSize *int
2836 MaxSize *int
37 MultiAZPolicy MultiAZPolicy
2938 DefaultCooldown *int
3039 RemovalPolicy common.FlattenArray
3140 DBInstanceIds string
337346 }
338347 return nil
339348 }
349
350 type DescribeScalingActivitiesRequest struct {
351 ScalingActivityId []string
352 ScalingGroupId string
353 StatusCode string
354 RegionId common.Region
355 common.Pagination
356 }
357
358 type DescribeScalingActivitiesResponse struct {
359 common.PaginationResult
360 common.Response
361 ScalingActivities struct {
362 ScalingActivity []ScalingActivity
363 }
364 }
365
366 type ScalingActivity struct {
367 AttachedCapacity int
368 AutoCreatedCapacity int
369 Cause string
370 Description string
371 EndTime string
372 Progress int
373 ScalingActivityId string
374 ScalingGroupId string
375 ScalingInstanceNumber int
376 StartTime string
377 StatusCode string
378 StatusMessage string
379 TotalCapacity int
380 }
381
382 func (client *Client) DescribeScalingActivities(args *DescribeScalingActivitiesRequest) (resp *DescribeScalingActivitiesResponse, err error) {
383 response := DescribeScalingActivitiesResponse{}
384 err = client.InvokeByFlattenMethod("DescribeScalingActivities", args, &response)
385
386 if err != nil {
387 return nil, err
388 }
389 return &response, nil
390 }
00 package ess
11
22 import (
3 "fmt"
34 "testing"
45
56 "github.com/denverdino/aliyungo/common"
7475 }
7576 t.Logf("Instance %s is deleted successfully.", instanceId)
7677 }
78
79 func TestEssScalingActivity(t *testing.T) {
80
81 client := NewTestClient(common.Region(RegionId))
82 id := "asg-uf68jfxw7gqlao0wlc94"
83 result, err := client.DescribeScalingActivities(
84 &DescribeScalingActivitiesRequest{
85 ScalingGroupId: id,
86 RegionId: common.Shanghai,
87 },
88 )
89 if err != nil {
90 t.Errorf("get activity %s: %v", id, err)
91 }
92 fmt.Printf("%+v\n", result)
93 t.Logf("get activity succeed by id %s.", id)
94 }
0 module github.com/denverdino/aliyungo
1
2 go 1.15
3
4 require (
5 github.com/golang/protobuf v1.5.2 // indirect
6 github.com/magiconair/properties v1.8.6 // indirect
7 github.com/opentracing/opentracing-go v1.2.0 // indirect
8 github.com/pkg/errors v0.9.1 // indirect
9 github.com/stretchr/testify v1.7.1 // indirect
10 github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
11 github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
12 go.uber.org/atomic v1.9.0 // indirect
13 golang.org/x/text v0.3.7 // indirect
14 )
0 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
1 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
5 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
6 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
7 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
8 github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
9 github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
10 github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
11 github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
12 github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
13 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
14 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
15 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
16 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
17 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
18 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
19 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
20 github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
21 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
22 github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
23 github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
24 github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
25 github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
26 go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
27 go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
28 golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
29 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
30 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
31 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
32 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
33 google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
34 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
35 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
36 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
37 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
55 client := NewTestClientForDebug()
66
77 args := &DescribeRegionsArgs{
8 //RegionId: common.Beijing,
8 //RegionId: common.Beijing,
99 }
1010
1111 regions, err := client.DescribeRegions(args)
1313 "encoding/json"
1414 "reflect"
1515
16 "os"
17
1618 "github.com/denverdino/aliyungo/util"
17 "os"
1819 )
1920
2021 const (
4344 VSWITCH_CIDR_BLOCK = "vswitch-cidr-block"
4445 VSWITCH_ID = "vswitch-id"
4546 ZONE = "zone-id"
46 RAM_SECURITY = "Ram/security-credentials"
47 RAM_SECURITY = "ram/security-credentials"
4748 )
4849
4950 type IMetaDataRequest interface {
350351 func (vpc *MetaDataRequest) Decode(data string, api interface{}) error {
351352 if data == "" {
352353 url, _ := vpc.Url()
353 return errors.New(fmt.Sprintf("metadata: alivpc decode data must not be nil. url=[%s]\n", url))
354 return fmt.Errorf("metadata: alivpc decode data must not be nil. url=[%s]\n", url)
354355 }
355356 switch api.(type) {
356357 case *ResultList:
359360 case *RoleAuth:
360361 return json.Unmarshal([]byte(data), api)
361362 default:
362 return errors.New(fmt.Sprintf("metadata: unknow type to decode, type=%s\n", reflect.TypeOf(api)))
363 return fmt.Errorf("metadata: unknow type to decode, type=%s\n", reflect.TypeOf(api))
363364 }
364365 }
365366
2121 client.debug = debug
2222 }
2323
24 // SetTransport sets transport to the http client
25 func (client *Client) SetTransport(transport http.RoundTripper) {
26 if client.httpClient == nil {
27 client.httpClient = &http.Client{}
28 }
29 client.httpClient.Transport = transport
30 }
31
2432 func NewClient(accessKeyId, accessKeySecret, endpoint string) (client *Client) {
2533 client = &Client{
2634 AccessKeyId: accessKeyId,
4343 canonicalizedResource := req.path
4444 var paramNames []string
4545 if req.params != nil && len(req.params) > 0 {
46 for k, _ := range req.params {
46 for k := range req.params {
4747 paramNames = append(paramNames, k)
4848 }
4949 sort.Strings(paramNames)
6161 func canonicalizeHeader(headers map[string]string) string {
6262 var canonicalizedHeaders []string
6363
64 for k, _ := range headers {
64 for k := range headers {
6565 if lower := strings.ToLower(k); strings.HasPrefix(lower, HeaderMNSPrefix) {
6666 canonicalizedHeaders = append(canonicalizedHeaders, lower)
6767 }
3636 Internal bool
3737 Secure bool
3838 ConnectTimeout time.Duration
39 Transport http.RoundTripper
3940
4041 endpoint string
4142 debug bool
5657 // Options struct
5758 //
5859 type Options struct {
59 ServerSideEncryption bool
60 Meta map[string][]string
61 ContentEncoding string
62 CacheControl string
63 ContentMD5 string
64 ContentDisposition string
60 ServerSideEncryption bool
61 ServerSideEncryptionKeyID string
62
63 Meta map[string][]string
64 ContentEncoding string
65 CacheControl string
66 ContentMD5 string
67 ContentDisposition string
6568 //Range string
6669 //Expires int
6770 }
7174 CopySourceOptions string
7275 MetadataDirective string
7376 //ContentType string
77
78 ServerSideEncryption bool
79 ServerSideEncryptionKeyID string
7480 }
7581
7682 // CopyObjectResult is the output from a Copy request
490496
491497 // addHeaders adds o's specified fields to headers
492498 func (o Options) addHeaders(headers http.Header) {
493 if o.ServerSideEncryption {
499 if len(o.ServerSideEncryptionKeyID) != 0 {
500 headers.Set("x-oss-server-side-encryption", "KMS")
501 headers.Set("x-oss-server-side-encryption-key-id", o.ServerSideEncryptionKeyID)
502 } else if o.ServerSideEncryption {
494503 headers.Set("x-oss-server-side-encryption", "AES256")
495504 }
496505 if len(o.ContentEncoding) != 0 {
515524
516525 // addHeaders adds o's specified fields to headers
517526 func (o CopyOptions) addHeaders(headers http.Header) {
527 if len(o.ServerSideEncryptionKeyID) != 0 {
528 headers.Set("x-oss-server-side-encryption", "KMS")
529 headers.Set("x-oss-server-side-encryption-key-id", o.ServerSideEncryptionKeyID)
530 } else if o.ServerSideEncryption {
531 headers.Set("x-oss-server-side-encryption", "AES256")
532 }
533
518534 if len(o.MetadataDirective) != 0 {
519535 headers.Set("x-oss-metadata-directive", o.MetadataDirective)
520536 }
833849 // to retrieve the object at path. The signature is valid until expires.
834850 func (b *Bucket) SignedURLWithArgs(path string, expires time.Time, params url.Values, headers http.Header) string {
835851 return b.SignedURLWithMethod("GET", path, expires, params, headers)
852 }
853
854 func (b *Bucket) SignedURLWithMethodForAssumeRole(method, path string, expires time.Time, params url.Values, headers http.Header) string {
855 var uv = url.Values{}
856 if params != nil {
857 uv = params
858 }
859 if len(b.Client.SecurityToken) != 0 {
860 uv.Set("security-token", b.Client.SecurityToken)
861 }
862 return b.SignedURLWithMethod(method, path, expires, params, headers)
836863 }
837864
838865 // SignedURLWithMethod returns a signed URL that allows anyone holding the URL
10231050 func (client *Client) prepare(req *request) error {
10241051 // Copy so they can be mutated without affecting on retries.
10251052 headers := copyHeader(req.headers)
1026 if len(client.SecurityToken) != 0 {
1053 // security-token should be in either Params or Header, cannot be in both
1054 if len(req.params.Get("security-token")) == 0 && len(client.SecurityToken) != 0 {
10271055 headers.Set("x-oss-security-token", client.SecurityToken)
10281056 }
10291057
11611189 },
11621190 Timeout: req.timeout,
11631191 }
1192 if client.Transport != nil {
1193 c.Transport = client.Transport
1194 }
11641195
11651196 return client.doHttpRequest(c, hreq, resp)
11661197 }
55 "io/ioutil"
66 "math/rand"
77 "net/http"
8 "os"
8 "net/url"
99 "strconv"
1010 "sync"
11
1112 //"net/http"
1213 "testing"
1314 "time"
2223 )
2324
2425 func init() {
25 AccessKeyId := os.Getenv("AccessKeyId")
26 AccessKeySecret := os.Getenv("AccessKeySecret")
27 if len(AccessKeyId) != 0 && len(AccessKeySecret) != 0 {
28 client = oss.NewOSSClient(TestRegion, false, AccessKeyId, AccessKeySecret, false)
29 } else {
30 client = oss.NewOSSClient(TestRegion, false, TestAccessKeyId, TestAccessKeySecret, false)
31 }
32
33 assumeRoleClient = oss.NewOSSClientForAssumeRole(TestRegion, false, TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, false)
26 client = oss.NewOSSClient(TestRegion, false, TestAccessKeyID, TestAccessKeySecret, false)
27 assumeRoleClient = oss.NewOSSClientForAssumeRole(TestRegion, false, TestAccessKeyID, TestAccessKeySecret, TestSecurityToken, false)
3428 assumeRoleClient.SetDebug(true)
3529 }
3630
9791 }
9892 }
9993
100 func aTestGetNotFound(t *testing.T) {
94 func TestGetNotFound(t *testing.T) {
10195
10296 b := client.Bucket("non-existent-bucket")
10397 _, err := b.Get("non-existent")
123117 }
124118 }
125119
120 func TestPutObjectWithSSE(t *testing.T) {
121 const DISPOSITION = "attachment; filename=\"0x1a2b3c.jpg\""
122
123 b := client.Bucket(TestBucket)
124 err := b.Put("name-sse", []byte("content"), "content-type", oss.Private, oss.Options{
125 ContentDisposition: DISPOSITION,
126 ServerSideEncryptionKeyID: TestServerSideEncryptionKeyID,
127 })
128 if err != nil {
129 t.Errorf("Failed for Put: %v", err)
130 }
131 }
132
133 func TestPutCopyWithSSE(t *testing.T) {
134 b := client.Bucket(TestBucket)
135 t.Log("Source: ", b.Path("name-sse"))
136 res, err := b.PutCopy("newname-sse", oss.Private, oss.CopyOptions{
137 ServerSideEncryptionKeyID: TestServerSideEncryptionKeyID,
138 },
139 b.Path("name"))
140 if err == nil {
141 t.Logf("Copy result: %v", res)
142 } else {
143 t.Errorf("Failed for PutCopy: %v", err)
144 }
145 }
146
126147 func TestList(t *testing.T) {
127148
128149 b := client.Bucket(TestBucket)
129150
130151 data, err := b.List("n", "", "", 0)
131 if err != nil || len(data.Contents) != 2 {
152 if err != nil || len(data.Contents) != 4 {
132153 t.Errorf("Failed for List: %v", err)
133154 } else {
134155 t.Logf("Contents = %++v", data)
240261 resp.Body.Close()
241262 }
242263
264 func TestSignedURLWithArgsWithTrafficLimits(t *testing.T) {
265 b := client.Bucket(TestBucket)
266 expires := time.Now().Add(20 * time.Minute)
267 url := b.SignedURLWithArgs("largefile", expires, url.Values{
268 "x-oss-traffic-limit": []string{strconv.FormatInt(5*8<<20, 10)}},
269 nil)
270 resp, err := http.Get(url)
271 t.Logf("Large file response headers: %++v", resp.Header)
272
273 if err != nil {
274 t.Fatalf("Failed for GetResponseWithHeaders: %v", err)
275 }
276 data, err := ioutil.ReadAll(resp.Body)
277
278 if err != nil {
279 t.Errorf("Failed for Read file: %v", err)
280 }
281
282 if len(data) != int(_fileSize) {
283 t.Errorf("Incorrect length for Read with offset: %v", len(data))
284 }
285 resp.Body.Close()
286 }
287
243288 func TestCopyLargeFile(t *testing.T) {
244289 b := client.Bucket(TestBucket)
245290 err := b.CopyLargeFile("largefile", "largefile2", "application/octet-stream", oss.Private, oss.Options{})
271316 t.Fatalf("Failed for Get file: %v", err)
272317 }
273318
274 if bytes.Compare(bytes1, bytes2) != 0 {
319 if !bytes.Equal(bytes1, bytes2) {
275320 t.Fatal("The result should be equal")
276321 }
277322 }
307352 t.Fatalf("Failed for Get file: %v", err)
308353 }
309354
310 if bytes.Compare(bytes1, bytes2) != 0 {
355 if !bytes.Equal(bytes1, bytes2) {
311356 t.Fatal("The result should be equal")
312357 }
313358 }
370415 func TestDelMultiObjects(t *testing.T) {
371416
372417 b := client.Bucket(TestBucket)
373 objects := []oss.Object{oss.Object{Key: "newname"}}
418 objects := []oss.Object{
419 {Key: "newname"},
420 {Key: "name-sse"},
421 {Key: "newname-sse"},
422 }
374423 err := b.DelMulti(oss.Delete{
375424 Quiet: false,
376425 Objects: objects,
1515 //
1616
1717 var (
18 TestAccessKeyId = os.Getenv("AccessKeyId")
18 TestAccessKeyID = os.Getenv("AccessKeyId")
1919 TestAccessKeySecret = os.Getenv("AccessKeySecret")
2020 TestSecurityToken = os.Getenv("SecurityToken")
2121 TestRegion = oss.Region(os.Getenv("RegionId"))
22
23 TestServerSideEncryptionKeyID = os.Getenv("ServerSideEncryptionKeyId")
2224 )
2626 MEEast1 = Region("oss-me-east-1")
2727
2828 EUCentral1 = Region("oss-eu-central-1")
29 EUWest1 = Region("oss-eu-west-1")
2930
3031 DefaultRegion = Hangzhou
3132 )
1212
1313 var ossParamsToSign = map[string]bool{
1414 "acl": true,
15 "append": true,
16 "bucketInfo": true,
17 "cname": true,
18 "comp": true,
19 "cors": true,
1520 "delete": true,
21 "endTime": true,
22 "img": true,
23 "lifecycle": true,
24 "live": true,
1625 "location": true,
1726 "logging": true,
18 "notification": true,
27 "objectMeta": true,
1928 "partNumber": true,
20 "policy": true,
21 "requestPayment": true,
22 "torrent": true,
23 "uploadId": true,
24 "uploads": true,
25 "versionId": true,
26 "versioning": true,
27 "versions": true,
28 "response-content-type": true,
29 "response-content-language": true,
30 "response-expires": true,
29 "position": true,
30 "qos": true,
31 "referer": true,
32 "replication": true,
33 "replicationLocation": true,
34 "replicationProgress": true,
3135 "response-cache-control": true,
3236 "response-content-disposition": true,
3337 "response-content-encoding": true,
34 "bucketInfo": true,
38 "response-content-language": true,
39 "response-content-type": true,
40 "response-expires": true,
41 "security-token": true,
42 "startTime": true,
43 "status": true,
44 "style": true,
45 "styleName": true,
46 "symlink": true,
47 "tagging": true,
48 "uploadId": true,
49 "uploads": true,
50 "vod": true,
51 "website": true,
52 "x-oss-process": true,
53 "x-oss-traffic-limit": true,
3554 }
3655
3756 func (client *Client) signRequest(request *request) {
6180 }
6281
6382 if len(params) > 0 {
64 resource = resource + "?" + util.Encode(params)
83 resource = resource + "?" + util.EncodeWithoutEscape(params)
6584 }
6685
6786 canonicalizedResource := resource
7392 //log.Println("stringToSign: ", stringToSign)
7493 signature := util.CreateSignature(stringToSign, client.AccessKeySecret)
7594
76 if query.Get("OSSAccessKeyId") != "" {
95 if urlSignature {
7796 query.Set("Signature", signature)
7897 } else {
7998 headers.Set("Authorization", "OSS "+client.AccessKeyId+":"+signature)
5959 return NewPVTZClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
6060 }
6161
62 //Onlyfor hangzhou
63 func NewPVTZClientWithSecurityToken4RegionalDomain(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
64 endpoint := os.Getenv("PVTZ_ENDPOINT")
65 if endpoint == "" {
66 endpoint = PVTZDefaultEndpoint
67 }
68
69 return NewPVTZClientWithEndpointAndSecurityToken4RegionalDomain(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
70 }
71
6272 func NewPVTZClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string, regionID common.Region) *Client {
6373 return NewPVTZClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, "", regionID)
6474 }
7585 InitClient()
7686 return client
7787 }
88
89 //only for hangzhou
90 func NewPVTZClientWithEndpointAndSecurityToken4RegionalDomain(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
91 client := &Client{}
92 client.WithEndpoint(endpoint).
93 WithVersion(PVTZAPIVersion).
94 WithAccessKeyId(accessKeyId).
95 WithAccessKeySecret(accessKeySecret).
96 WithSecurityToken(securityToken).
97 WithServiceCode(PVTZServiceCode).
98 WithRegionID(regionID).
99 InitClient4RegionalDomain()
100 return client
101 }
4242 err = client.BindZoneVpc(&BindZoneVpcArgs{
4343 ZoneId: zoneId,
4444 Vpcs: []VPCType{
45 VPCType{
45 {
4646 RegionId: common.Beijing,
4747 VpcId: TestVPCId,
4848 },
114114 }
115115
116116 func TestDescribeChangeLogs(t *testing.T) {
117 client := NewTestClient()
117 client := NewTestLocationClientForDebug()
118118
119119 changeLogs, err := client.DescribeChangeLogs(&DescribeChangeLogsArgs{})
120120
00 package pvtz
11
22 import (
3 "github.com/denverdino/aliyungo/common"
34 "os"
45 )
56
910 TestAccessKeyId = os.Getenv("AccessKeyId")
1011 TestAccessKeySecret = os.Getenv("AccessKeySecret")
1112 TestVPCId = os.Getenv("VPCId")
13 TestSecurityToken = os.Getenv("SecurityToken")
14 TestRegionID = common.Region(os.Getenv("RegionId"))
1215 )
1316
1417 var testClient *Client
2932 }
3033 return testDebugClient
3134 }
35
36 var testDebugLocationClient *Client
37
38 func NewTestLocationClientForDebug() *Client {
39 if testDebugLocationClient == nil {
40 testDebugLocationClient = NewPVTZClientWithSecurityToken4RegionalDomain(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, TestRegionID)
41 testDebugLocationClient.SetDebug(true)
42 }
43 return testDebugLocationClient
44 }
151151 // UpdateZoneRecord update zone record
152152 //
153153 // You can read doc at https://help.aliyun.com/document_detail/66250.html
154 func (client *Client) UpdateZoneRecord(args *AddZoneRecordArgs) (err error) {
154 func (client *Client) UpdateZoneRecord(args *UpdateZoneRecordArgs) (err error) {
155155 response := &UpdateZoneRecordResponse{}
156156
157157 err = client.Invoke("UpdateZoneRecord", args, &response)
8080 ClearAccountAlias() (RamCommonResponse, error)
8181 SetPasswordPolicy(passwordPolicy PasswordPolicyRequest) (PasswordPolicyResponse, error)
8282 GetPasswordPolicy() (PasswordPolicyResponse, error)
83
84 // Common Client Methods
85 SetUserAgent(userAgent string)
8386 }
2323
2424 type PolicyResponse struct {
2525 RamCommonResponse
26 Policy Policy
26 Policy Policy
27 DefaultPolicyVersion PolicyVersion
2728 }
2829
2930 type PolicyQueryRequest struct {
1111 policy_name string
1212 policy_document = PolicyDocument{
1313 Statement: []PolicyItem{
14 PolicyItem{
14 {
1515 Action: "*",
1616 Effect: "Allow",
1717 Resource: "*",
202202 t.Logf("pass ListPoliciesForGroup %++v", resp)
203203 }
204204
205 func TEstListEntitiesForPolicy(t *testing.T) {
205 func TestListEntitiesForPolicy(t *testing.T) {
206206 client := NewTestClient()
207207 policyReq := PolicyRequest{
208208 PolicyType: "Custom",
1919
2020 policyDocument = AssumeRolePolicyDocument{
2121 Statement: []AssumeRolePolicyItem{
22 AssumeRolePolicyItem{Action: "sts:AssumeRole", Effect: "Allow", Principal: princpal},
22 {Action: "sts:AssumeRole", Effect: "Allow", Principal: princpal},
2323 },
2424 Version: "1"}
2525
2626 newPolicyDocument = AssumeRolePolicyDocument{
2727 Statement: []AssumeRolePolicyItem{
28 AssumeRolePolicyItem{Action: "sts:AssumeRole", Effect: "Deny", Principal: princpal},
28 {Action: "sts:AssumeRole", Effect: "Deny", Principal: princpal},
2929 },
3030 Version: "1"}
3131
204204 }
205205
206206 // CreateOrder create db instance order
207 // you can read doc at http://docs.alibaba-inc.com/pages/viewpage.action?pageId=259349053
208207 func (client *Client) CreateOrder(args *CreateOrderArgs) (resp CreateOrderResponse, err error) {
209208 response := CreateOrderResponse{}
210209 err = client.Invoke("CreateOrder", args, &response)
253253 args := AllocateInstancePublicConnectionArgs{
254254 DBInstanceId: DBInstanceId,
255255 ConnectionStringPrefix: DBInstanceId + "o",
256 Port: "3306",
256 Port: "3306",
257257 }
258258
259259 _, err := client.AllocateInstancePublicConnection(&args)
8585 client.SecurityToken = securityToken
8686 }
8787
88 // SetTransport sets transport to the http client
89 func (client *Client) SetTransport(transport http.RoundTripper) {
90 if client.httpClient == nil {
91 client.httpClient = &http.Client{}
92 }
93 client.httpClient.Transport = transport
94 }
95
8896 type Request struct {
8997 Method string
9098 URL string
143151 httpReq.Header.Set("Date", util.GetGMTime())
144152 httpReq.Header.Set("Accept", "application/json")
145153 //httpReq.Header.Set("x-acs-version", client.Version)
154 httpReq.Header["x-acs-version"] = []string{client.Version}
146155
147156 httpReq.Header["x-acs-signature-version"] = []string{"1.0"}
148157 httpReq.Header["x-acs-signature-nonce"] = []string{util.CreateRandomString()}
179188
180189 if client.debug {
181190 var prettyJSON bytes.Buffer
182 err = json.Indent(&prettyJSON, body, "", " ")
183 log.Println(string(prettyJSON.Bytes()))
191 _ = json.Indent(&prettyJSON, body, "", " ")
192 log.Println(prettyJSON.String())
184193 }
185194
186195 if statusCode >= 400 && statusCode <= 599 {
187196 errorResponse := common.ErrorResponse{}
188 err = json.Unmarshal(body, &errorResponse)
197 _ = json.Unmarshal(body, &errorResponse)
189198 cErr := &common.Error{
190199 ErrorResponse: errorResponse,
191200 StatusCode: statusCode,
1313 TestSecurityToken = os.Getenv("SecurityToken")
1414 TestRegionID = common.Region(os.Getenv("RegionId"))
1515
16 clientForTestCase = NewTestClient()
17 debugClientForTestCase = NewTestClientForDebug()
16 debugClientForTestCase = NewTestClientForDebug()
17 debugRpcClientForTestCase = NewTestRpcClientForDebug()
1818 )
1919
2020 var testClient *Client
2828 }
2929
3030 var testDebugClient *Client
31 var testDebugRpcClient *RpcClient
3132
3233 func NewTestClientForDebug() *Client {
3334 if testDebugClient == nil {
3738 testDebugClient.SetSecurityToken(TestSecurityToken)
3839 return testDebugClient
3940 }
41
42 func NewTestRpcClientForDebug() *RpcClient {
43 if testDebugRpcClient == nil {
44 testDebugRpcClient = NewRpcClient(TestAccessKeyId, TestAccessKeySecret)
45 testDebugRpcClient.SetDebug(true)
46 }
47 testDebugRpcClient.SetSecurityToken(TestSecurityToken)
48 return testDebugRpcClient
49 }
1717 }
1818
1919 type Event struct {
20 Status string
2021 ResourceStatus string
2122 ResourceName string
2223 StatusReason string
3232 func (client *Client) DescribeResource(stackId, stackName, resourceName string) (*Resource, error) {
3333 response := &Resource{}
3434 err := client.Invoke("", http.MethodGet, fmt.Sprintf("/stacks/%s/%s/resources/%s", stackName, stackId, resourceName), nil, nil, &response)
35 if err != nil {
36 return nil, err
37 }
38
39 return response, nil
40 }
41
42 //https://help.aliyun.com/document_detail/28917.html?spm=5176.doc28916.6.589.BUPJqx
43 func (client *Client) DescribeResourceByRegion(regionId common.Region, stackId, stackName, resourceName string) (*Resource, error) {
44 response := &Resource{}
45 err := client.Invoke(regionId, http.MethodGet, fmt.Sprintf("/stacks/%s/%s/resources/%s", stackName, stackId, resourceName), nil, nil, &response)
3546 if err != nil {
3647 return nil, err
3748 }
0 package ros
1
2 import (
3 "github.com/denverdino/aliyungo/common"
4 "os"
5 )
6
7 const (
8 ROS_RPC_APIVersion = "2019-09-10"
9 ROSServiceCode = "ros"
10 )
11
12 type RpcClient struct {
13 common.Client
14 }
15
16 func NewRpcClient(accessKeyId, accessKeySecret string) *RpcClient {
17 endpoint := os.Getenv("ROS_ENDPOINT")
18 if endpoint == "" {
19 endpoint = ROSDefaultEndpoint
20 }
21 return NewRpcClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
22 }
23
24 func NewRpcClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string) *RpcClient {
25 client := &RpcClient{}
26 client.Init(endpoint, ROS_RPC_APIVersion, accessKeyId, accessKeySecret)
27 return client
28 }
29
30 func NewRosRpcClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *RpcClient {
31 endpoint := os.Getenv("ROS_ENDPOINT")
32 if endpoint == "" {
33 endpoint = ROSDefaultEndpoint
34 }
35
36 return NewRosRpcClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
37 }
38
39 func NewRosRpcClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *RpcClient {
40 client := &RpcClient{}
41 client.WithEndpoint(endpoint).
42 WithVersion(ROS_RPC_APIVersion).
43 WithAccessKeyId(accessKeyId).
44 WithAccessKeySecret(accessKeySecret).
45 WithSecurityToken(securityToken).
46 WithServiceCode(ROSServiceCode).
47 WithRegionID(regionID).
48 InitClient()
49 return client
50 }
2121 _, canonicalizedHeader := canonicalizeHeader(headers)
2222
2323 stringToSign := request.Method + "\n" + accept + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedHeader + canonicalizedResource
24
25 log.Println("stringToSign: ", stringToSign)
24 if client.debug {
25 log.Println("stringToSign: ", stringToSign)
26 }
2627 signature := util.CreateSignature(stringToSign, client.AccessKeySecret)
2728 headers.Set("Authorization", "acs "+client.AccessKeyId+":"+signature)
2829 }
88 "github.com/denverdino/aliyungo/util"
99 )
1010
11 type DeletionProtection string
12
13 const (
14 DeletionProtectionEnabled = DeletionProtection("Enabled")
15 DeletionProtectionDisabled = DeletionProtection("Disabled")
16 )
17
1118 //https://help.aliyun.com/document_detail/28910.html?spm=5176.doc50083.6.580.b5wkQr
1219 type CreateStackRequest struct {
13 Name string
14 Template string
15 Parameters interface{}
16 DisableRollback bool
17 TimeoutMins int
20 Name string
21 Template string
22 Parameters interface{}
23 DisableRollback bool
24 DeletionProtection DeletionProtection
25 TimeoutMins int
1826 }
1927
2028 type CreateStackResponse struct {
3543 //https://help.aliyun.com/document_detail/28911.html?spm=5176.doc28910.6.581.etoi2Z
3644 type DeleteStackRequest struct {
3745 RegionId common.Region
46 }
47
48 type DeleteStackRpcRequest struct {
49 RegionId common.Region
50 StackId string
51 RetainResources common.FlattenArray
52 RetainAllResources bool
53 }
54
55 type SetDeletionProtectionRequest struct {
56 RegionId common.Region
57 StackId string
58 DeletionProtection DeletionProtection
3859 }
3960
4061 type DeleteStackResponse struct {
202223
203224 //https://help.aliyun.com/document_detail/49066.html?spm=5176.doc28910.6.586.MJjWQh
204225 type UpdateStackRequest struct {
205 Template string
206 Parameters interface{}
207 DisableRollback bool
208 TimeoutMins int
226 Template string
227 Parameters interface{}
228 DisableRollback bool
229 TimeoutMins int
230 StackPolicy interface{}
231 UpdateAllowPolicy interface{}
232 Existing bool
209233 }
210234
211235 type UpdateStackResponse struct {
223247
224248 return stack, nil
225249 }
250
251 // rpc api: https://help.aliyun.com/document_detail/132113.html?spm=a2c4g.11174283.6.880.1b1d143eCzdE0b
252 func (client *RpcClient) DeleteStack(args *DeleteStackRpcRequest) (*DeleteStackResponse, error) {
253 response := &DeleteStackResponse{}
254 err := client.InvokeByFlattenMethod("DeleteStack", args, response)
255 if err != nil {
256 return nil, err
257 }
258 return response, nil
259 }
260
261 // rpc api: https://help.aliyun.com/document_detail/161560.html?spm=a2c4g.11186623.6.991.18f62842yOfz9G
262 func (client *RpcClient) SetDeletionProtection(args *SetDeletionProtectionRequest) (*common.Response, error) {
263 response := &common.Response{}
264 err := client.Invoke("SetDeletionProtection", args, response)
265 if err != nil {
266 return nil, err
267 }
268 return response, nil
269 }
00 package ros
11
22 import (
3 "strings"
34 "testing"
45
56 "fmt"
9091 }
9192 }
9293
94 func TestClient_CreateStack_DeletionProtection(t *testing.T) {
95 args := &CreateStackRequest{
96 Name: fmt.Sprintf("my-k8s-test-stack-%d", time.Now().Unix()),
97 Template: myTestTemplate,
98 Parameters: map[string]interface{}{},
99 DisableRollback: false,
100 DeletionProtection: DeletionProtectionEnabled,
101 TimeoutMins: 30,
102 }
103
104 response, err := debugClientForTestCase.CreateStack(TestRegionID, args)
105 if err != nil {
106 t.Fatalf("Failed to CreateStack %++v", err)
107 } else {
108 t.Logf("Success %++v", response)
109 }
110 }
111
93112 func TestClient_DeleteStack(t *testing.T) {
94113 stackName := os.Getenv("StackName")
95114 stackId := os.Getenv("StackId")
158177 t.Logf("Success %++v", response)
159178 }
160179 }
180
181 func TestClient_DeleteStackWithParams(t *testing.T) {
182 stackId := os.Getenv("StackId")
183 resourceIds := os.Getenv("RetainResources")
184
185 args := &DeleteStackRpcRequest{
186 RegionId: TestRegionID,
187 StackId: stackId,
188 RetainResources: strings.Split(resourceIds, ","),
189 }
190
191 response, err := debugRpcClientForTestCase.DeleteStack(args)
192 if err != nil {
193 t.Fatalf("Failed to DeleteStack %++v", err)
194 } else {
195 t.Logf("Success %++v", response)
196 }
197 }
198
199 func TestClient_DeleteStack_DisabledProtection(t *testing.T) {
200 stackId := os.Getenv("StackId")
201
202 args := &SetDeletionProtectionRequest{
203 RegionId: TestRegionID,
204 StackId: stackId,
205 DeletionProtection: DeletionProtectionDisabled,
206 }
207
208 response, err := debugRpcClientForTestCase.SetDeletionProtection(args)
209 if err != nil {
210 t.Fatalf("Failed to SetDeletionProtection %++v", err)
211 } else {
212 t.Logf("Success %++v", response)
213 }
214
215 deleteArgs := &DeleteStackRpcRequest{
216 RegionId: TestRegionID,
217 StackId: stackId,
218 }
219
220 resp, err := debugRpcClientForTestCase.DeleteStack(deleteArgs)
221 if err != nil {
222 t.Fatalf("Failed to DeleteStack %++v", err)
223 } else {
224 t.Logf("Success %++v", resp)
225 }
226 }
0 package standard
1
2 import (
3 "github.com/denverdino/aliyungo/common"
4
5 "os"
6 )
7
8 type Client struct {
9 common.Client
10 }
11
12 const (
13 // ROSDefaultEndpoint is the default API endpoint of ESS services
14 ROSDefaultEndpoint = "https://ros.aliyuncs.com"
15 ROSAPIVersion = "2019-09-10"
16 ROSServiceCode = "ros"
17 )
18
19 // NewClient creates a new instance of RDS client
20 func NewClient(accessKeyId, accessKeySecret string) *Client {
21 endpoint := os.Getenv("ROS_ENDPOINT")
22 if endpoint == "" {
23 endpoint = ROSDefaultEndpoint
24 }
25 return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
26 }
27
28 func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client {
29 client := &Client{}
30 client.Init(endpoint, ROSAPIVersion, accessKeyId, accessKeySecret)
31 return client
32 }
33
34 func NewROSClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client {
35 endpoint := os.Getenv("ROS_ENDPOINT")
36 if endpoint == "" {
37 endpoint = ROSDefaultEndpoint
38 }
39
40 return NewClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID)
41 }
42
43 func NewClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client {
44 client := &Client{}
45 client.NewInit(endpoint, ROSAPIVersion, accessKeyId, accessKeySecret, ROSServiceCode, regionID)
46 return client
47 }
0 package standard
1
2 import (
3 "fmt"
4 "github.com/denverdino/aliyungo/common"
5 "testing"
6 )
7
8 const (
9 TestAccessKeyId = ""
10 TestAccessKeySecret = ""
11 Region = common.Shanghai
12 StackID = "c7f1fed9-0104-4596-aae6-aa5215f5a793"
13 )
14
15 func NewTestClient() *Client {
16 return NewROSClient(TestAccessKeyId, TestAccessKeySecret, Region)
17 }
18
19 func TestGetStack(t *testing.T) {
20
21 client := NewTestClient()
22 req := GetStackRequest{
23 RegionId: Region,
24 StackId: StackID,
25 }
26 res, err := client.GetStack(&req)
27 if err != nil {
28 t.Fail()
29 }
30 fmt.Printf("Response: %+v\n", res)
31 }
32
33 func TestListStack(t *testing.T) {
34 client := NewTestClient()
35 req := &ListStacksRequest{}
36 res, err := client.ListStacks(req)
37 if err != nil {
38 t.Fail()
39 }
40 fmt.Printf("ListResponse: %+v\n", res)
41 }
42
43 func TestListStackEvent(t *testing.T) {
44 client := NewTestClient()
45 req := &ListStackEventsRequest{
46 StackId: StackID,
47 }
48 res, err := client.ListStackEvents(req)
49 if err != nil {
50 t.Fail()
51 }
52 fmt.Printf("ListEventResponse: %+v\n", res)
53 }
54
55 func TestCreateStack(t *testing.T) {
56 client := NewTestClient()
57 req := &CreateStackRequest{
58 StackName: "TDDDDDDD",
59 TemplateBody: tpl,
60 DisableRollback: true,
61 TimeoutInMinutes: 60,
62 Parameters: []Parameter{
63 {ParameterKey: "SystemDisk", ParameterValue: ""},
64 },
65 }
66 res, err := client.CreateStack(req)
67 if err != nil {
68 t.Logf("create stack: %s", err.Error())
69 t.Fail()
70 }
71 fmt.Printf("ListEventResponse: %+v\n", res)
72 }
73
74 var tpl = `
75
76 `
0 package standard
1
2 import (
3 "github.com/denverdino/aliyungo/common"
4 )
5
6 type DeletionProtection string
7
8 const (
9 DeletionProtectionEnabled = DeletionProtection("Enabled")
10 DeletionProtectionDisabled = DeletionProtection("Disabled")
11 )
12
13 //https://help.aliyun.com/document_detail/28910.html?spm=5176.doc50083.6.580.b5wkQr
14 type CreateStackRequest struct {
15 RegionId common.Region
16 StackName string
17 DisableRollback bool
18 TemplateBody string
19 TemplateURL string
20 Parameters []Parameter
21 StackPolicyURL string
22 TimeoutInMinutes int
23 StackPolicyBody string
24 ClientToken string
25 NotificationURLs []string
26 DeletionProtection DeletionProtection
27 RamRoleName string
28 }
29
30 type CreateStackResponse struct {
31 StackId string
32 common.Response
33 }
34
35 type ListStackEventsRequest struct {
36 common.Pagination
37 RegionId common.Region
38 StackId string
39 Status []string
40 ResourceType []string
41 LogicalResourceId []string
42 }
43
44 type ListStackEventsResponse struct {
45 common.Response
46 common.PaginationResult
47 RegionId common.Region
48 Events []Event
49 }
50
51 type Event struct {
52 StackId string
53 Status string
54 StackName string
55 StatusReason string
56 EventId string
57 LogicalResourceId string
58 ResourceType string
59 PhysicalResourceId string
60 CreateTime string
61 }
62
63 func (client *Client) ListStackEvents(args *ListStackEventsRequest) (*ListStackEventsResponse, error) {
64 response := &ListStackEventsResponse{}
65 err := client.Invoke("ListStackEvents", args, response)
66 if err != nil {
67 return nil, err
68 }
69
70 return response, nil
71 }
72
73 func (client *Client) CreateStack(args *CreateStackRequest) (*CreateStackResponse, error) {
74 stack := &CreateStackResponse{}
75 err := client.Invoke("CreateStack", args, stack)
76 if err != nil {
77 return nil, err
78 }
79
80 return stack, nil
81 }
82
83 //https://help.aliyun.com/document_detail/28911.html?spm=5176.doc28910.6.581.etoi2Z
84 type DeleteStackRequest struct {
85 RegionId common.Region
86 StackId string
87 RetainAllResources bool
88 RetainResources []string
89 RamRoleName string
90 }
91
92 type DeleteStackResponse struct {
93 common.Response
94 }
95
96 func (client *Client) DeleteStack(req *DeleteStackRequest) (*DeleteStackResponse, error) {
97 response := &DeleteStackResponse{}
98 err := client.Invoke("DeleteStack", req, response)
99 if err != nil {
100 return nil, err
101 }
102
103 return response, nil
104 }
105
106 type GetStackRequest struct {
107 RegionId common.Region
108 StackId string
109 ClientToken string
110 }
111
112 type GetStackResponse struct {
113 CreateTime string
114 Description string
115 DisableRollback bool
116 NotificationURLs []string
117 Outputs []Output
118 ParentStackId string
119 RegionId common.Region
120 Status string
121 StackId string
122 StackName string
123 Parameters []Parameter
124 UpdateTime string
125 StatusReason string
126 TemplateDescription string
127 TimeoutInMinutes int
128
129 RequestId string
130 DeletionProtection DeletionProtection
131 DriftDetectionTime string
132 RamRoleName string
133 RootStackId string
134 StackDriftStatus string
135 StackType string
136 }
137
138 type Parameter struct {
139 ParameterKey string
140 ParameterValue string
141 }
142
143 type Output struct {
144 Description string
145 OutputKey string
146 OutputValue interface{}
147 }
148
149 func (client *Client) GetStack(req *GetStackRequest) (*GetStackResponse, error) {
150 response := &GetStackResponse{}
151 err := client.Invoke("GetStack", req, response)
152 if err != nil {
153 return nil, err
154 }
155
156 return response, nil
157 }
158
159 type ListStacksRequest struct {
160 RegionId common.Region
161 StackId string
162 Status []string
163 ParentStackId string
164 StackName []string
165 ShowNestedStack bool
166 Tag []Tag
167 common.Pagination
168 }
169
170 type ListStacksResponse struct {
171 common.PaginationResult
172 common.Response
173 Stacks []Stack
174 }
175
176 type Stack struct {
177 CreateTime string
178
179 DisableRollback bool
180 DriftDetectionTime string
181 ParentStackId string
182 RegionId common.Region
183 StackDriftStatus string
184 StackId string
185 StackName string
186 Status string
187 StatusReason string
188
189 TimeoutInMinutes int
190 UpdateTime string
191 }
192
193 type Tag struct {
194 Key string
195 Value string
196 }
197
198 func (client *Client) ListStacks(req *ListStacksRequest) (*ListStacksResponse, error) {
199 response := &ListStacksResponse{}
200 err := client.Invoke("ListStacks", req, response)
201 if err != nil {
202 return nil, err
203 }
204
205 return response, nil
206 }
207
208 type UpdateStackRequest struct {
209 Parameters []Parameter
210 RegionId string
211 StackId string
212 ClientToken string
213 StackPolicyDuringUpdateBody string
214 TimeoutInMinutes int
215 TemplateBody string
216 StackPolicyURL string
217 StackPolicyDuringUpdateURL string
218 StackPolicyBody string
219 UsePreviousParameters bool
220 DisableRollback bool
221 TemplateURL string
222 RamRoleName string
223 ReplacementOption string
224 }
225
226 type UpdateStackResponse struct {
227 StackId string
228 common.Response
229 }
230
231 func (client *Client) UpdateStack(req *UpdateStackRequest) (*UpdateStackResponse, error) {
232 response := &UpdateStackResponse{}
233 err := client.Invoke("UpdateStack", req, response)
234 if err != nil {
235 return nil, err
236 }
237
238 return response, nil
239 }
240
241 type GetStackResourceRequest struct {
242 StackId string
243 LogicalResourceId string
244 ClientToken string
245 ShowResourceAttributes bool
246 RegionId common.Region
247 }
248
249 type GetStackResourceResponse struct {
250 Status string
251 Description string
252 LogicalResourceId string
253 StackId string
254
255 StackName string
256 StatusReason string
257 PhysicalResourceId string
258 ResourceType string
259 CreateTime string
260 Metadata map[string]string
261 UpdateTime string
262 ResourceAttributes []ResourceAttribute
263 RequestId string
264 DriftDetectionTime string
265 ResourceDriftStatus string
266 }
267 type ResourceAttribute struct {
268 ResourceAttributeValue string
269 ResourceAttributeKey string
270 }
271
272 func (client *Client) GetStackResource(req *GetStackResourceRequest) (*GetStackResourceResponse, error) {
273 response := &GetStackResourceResponse{}
274 err := client.Invoke("GetStackResource", req, response)
275 if err != nil {
276 return nil, err
277 }
278
279 return response, nil
280 }
281
282 type ListStackResourcesRequest struct {
283 RegionId common.Region
284 StackId string
285 }
286
287 type ListStackResourcesResponse struct {
288 common.Response
289 Resources []Resource
290 }
291
292 type Resource struct {
293 CreateTime string
294 DriftDetectionTime string
295 LogicalResourceId string
296 PhysicalResourceId string
297
298 ResourceDriftStatus string
299 ResourceType string
300 StackId string
301 StackName string
302 Status string
303 StatusReason string
304 UpdateTime string
305 }
306
307 func (client *Client) ListStackResources(req *ListStackResourcesRequest) (*ListStackResourcesResponse, error) {
308 response := &ListStackResourcesResponse{}
309 err := client.Invoke("ListStackResources", req, response)
310 if err != nil {
311 return nil, err
312 }
313
314 return response, nil
315 }
5656 return NewSLBClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
5757 }
5858
59 //Only for hangzhou
60 func NewSLBClientWithSecurityToken4RegionalDomain(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
61 endpoint := os.Getenv("SLB_ENDPOINT")
62 if endpoint != "" {
63 return NewSLBClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
64 }
65
66 return NewSLBClientWithEndpointAndSecurityToken4RegionalDomain(endpoint, accessKeyId, accessKeySecret, securityToken, regionID)
67 }
68
5969 func NewSLBClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
6070 client := &Client{}
6171 client.WithEndpoint(endpoint).
6878 InitClient()
6979 return client
7080 }
81
82 //only for hangzhou
83 func NewSLBClientWithEndpointAndSecurityToken4RegionalDomain(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client {
84 client := &Client{}
85 client.WithEndpoint(endpoint).
86 WithVersion(SLBAPIVersion).
87 WithAccessKeyId(accessKeyId).
88 WithAccessKeySecret(accessKeySecret).
89 WithSecurityToken(securityToken).
90 WithServiceCode(SLBServiceCode).
91 WithRegionID(regionID).
92 InitClient4RegionalDomain()
93 return client
94 }
1515 TestVServerGroupID = "MY_VSERVER_GROUPID"
1616 TestListenerPort = 9000
1717 TestInstanceId = "MY_INSTANCE_ID"
18 TestENIId = "MY_ENI_ID"
1819 TestRegionID = common.Region(os.Getenv("RegionId"))
1920 TestIAmRich = false
2021 TestQuick = false
4344
4445 func NewTestNewSLBClientForDebug() *Client {
4546 if testDebugNewSLBClient == nil {
46 testDebugNewSLBClient = NewSLBClientWithSecurityToken(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, TestRegionID)
47 testDebugNewSLBClient = NewSLBClientWithSecurityToken4RegionalDomain(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, TestRegionID)
4748 testDebugNewSLBClient.SetDebug(true)
4849 }
4950 return testDebugNewSLBClient
9898 UnhealthyThreshold int
9999 HealthCheckTimeout int
100100 HealthCheckInterval int
101 ForwardPort int
102 ListenerForward FlagType
101103 HealthCheckHttpCode HealthCheckHttpCodeType
102104 VServerGroup FlagType
103105 VServerGroupId string
105107 XForwardedFor_SLBID FlagType
106108 XForwardedFor_SLBIP FlagType
107109 XForwardedFor_proto FlagType
110 Description string
111 AclId string
112 AclStatus string
113 AclType string
108114 }
109115 type CreateLoadBalancerHTTPListenerArgs HTTPListenerType
110116
146152 BackendServerPort int
147153 Bandwidth int
148154 Scheduler SchedulerType
149 PersistenceTimeout int
155 PersistenceTimeout *int
150156 HealthCheck FlagType
151157 HealthCheckType HealthCheckType
152158 HealthCheckDomain string
159165 HealthCheckHttpCode HealthCheckHttpCodeType
160166 VServerGroup FlagType
161167 VServerGroupId string
168 Description string
169 AclId string
170 AclStatus string
171 AclType string
162172 }
163173
164174 type CreateLoadBalancerTCPListenerArgs TCPListenerType
178188 BackendServerPort int
179189 Bandwidth int
180190 Scheduler SchedulerType
181 PersistenceTimeout int
191 PersistenceTimeout *int
182192 HealthCheck FlagType
183193 HealthCheckConnectPort int
184194 HealthyThreshold int
187197 HealthCheckInterval int
188198 VServerGroup FlagType
189199 VServerGroupId string
200 Description string
201
202 AclId string
203 AclStatus string
204 AclType string
190205 }
191206 type CreateLoadBalancerUDPListenerArgs UDPListenerType
192207
00 package slb
11
2 import "testing"
2 import (
3 "bytes"
4 "encoding/json"
5 "fmt"
6 "testing"
7 )
38
49 func testListeners(t *testing.T, client *Client, loadBalancerId string) {
510
4045 }
4146 t.Logf("Listener: %++v", *response)
4247 }
48
49 func TestDescribeListener(t *testing.T) {
50
51 response, err := client.DescribeLoadBalancerTCPListenerAttribute(loadBalancerId, 22)
52 if err != nil {
53 t.Error(err)
54 } else {
55 fmt.Println(PrettyJson(response))
56 }
57 }
58
59 func TestDescribeSLB(t *testing.T) {
60
61 response, err := client.DescribeLoadBalancerAttribute(loadBalancerId)
62 if err != nil {
63 t.Error(err)
64 } else {
65 fmt.Println(PrettyJson(response))
66 }
67 }
68
69 func PrettyJson(obj interface{}) string {
70 pretty := bytes.Buffer{}
71 data, err := json.Marshal(obj)
72 if err != nil {
73 return err.Error()
74 }
75 err = json.Indent(&pretty, data, "", " ")
76
77 if err != nil {
78 return err.Error()
79 }
80
81 return pretty.String()
82 }
1919 const (
2020 PayByBandwidth = InternetChargeType("paybybandwidth")
2121 PayByTraffic = InternetChargeType("paybytraffic")
22 )
23
24 type AddressIPVersionType string
25
26 const (
27 IPv4 = AddressIPVersionType("ipv4")
28 IPv6 = AddressIPVersionType("ipv6")
2229 )
2330
2431 type LoadBalancerSpecType string
3239 S3Large = "slb.s3.large"
3340 )
3441
42 type ModificationProtectionType string
43
44 const (
45 NonProtection = ModificationProtectionType("NonProtection")
46 ConsoleProtection = ModificationProtectionType("ConsoleProtection")
47 )
48
3549 type CreateLoadBalancerArgs struct {
36 RegionId common.Region
37 LoadBalancerName string
38 AddressType AddressType
39 VSwitchId string
40 InternetChargeType InternetChargeType
41 Bandwidth int
42 ClientToken string
43 MasterZoneId string
44 SlaveZoneId string
45 LoadBalancerSpec LoadBalancerSpecType
50 RegionId common.Region
51 LoadBalancerName string
52 AddressType AddressType
53 VSwitchId string
54 InternetChargeType InternetChargeType
55 Bandwidth int
56 ClientToken string
57 MasterZoneId string
58 SlaveZoneId string
59 LoadBalancerSpec LoadBalancerSpecType
60 AddressIPVersion AddressIPVersionType
61 DeleteProtection FlagType
62 ModificationProtectionStatus ModificationProtectionType
63 ModificationProtectionReason string
64 ResourceGroupId string
4665 }
4766
4867 type CreateLoadBalancerResponse struct {
5372 VpcId string
5473 VSwitchId string
5574 LoadBalancerName string
75 MasterZoneId string
76 SlaveZoneId string
77 AddressIPVersion AddressIPVersionType
5678 }
5779
5880 // CreateLoadBalancer create loadbalancer
192214 type ListenerPortAndProtocolType struct {
193215 ListenerPort int
194216 ListenerProtocol string
217 Description string
195218 }
196219
197220 type BackendServerType struct {
200223 Type string
201224 }
202225
226 type ServiceManagedModeType string
227
228 const (
229 Managed = ServiceManagedModeType("Managed")
230 Unmanaged = ServiceManagedModeType("Unmanaged")
231 DependencyManaged = ServiceManagedModeType("DependencyManaged")
232 )
233
203234 type LoadBalancerType struct {
204 LoadBalancerId string
205 LoadBalancerName string
206 LoadBalancerStatus string
207 Address string
208 RegionId common.Region
209 RegionIdAlias string
210 AddressType AddressType
211 VSwitchId string
212 VpcId string
213 NetworkType string
214 Bandwidth int
215 InternetChargeType InternetChargeType
216 CreateTime string //Why not ISO 6801
217 CreateTimeStamp util.ISO6801Time
218 ListenerPorts struct {
235 LoadBalancerId string
236 ResourceGroupId string
237 LoadBalancerName string
238 LoadBalancerStatus string
239 Address string
240 RegionId common.Region
241 RegionIdAlias string
242 AddressType AddressType
243 VSwitchId string
244 VpcId string
245 NetworkType string
246 Bandwidth int
247 InternetChargeType InternetChargeType
248 CreateTime string //Why not ISO 6801
249 CreateTimeStamp util.ISO6801Time
250 DeleteProtection FlagType
251 ModificationProtectionStatus ModificationProtectionType
252 ModificationProtectionReason string
253 ListenerPorts struct {
219254 ListenerPort []int
220255 }
221256 ListenerPortsAndProtocol struct {
224259 BackendServers struct {
225260 BackendServer []BackendServerType
226261 }
227 LoadBalancerSpec LoadBalancerSpecType
262 LoadBalancerSpec LoadBalancerSpecType
263 MasterZoneId string
264 SlaveZoneId string
265 AddressIPVersion AddressIPVersionType
266 ServiceManagedMode ServiceManagedModeType
228267 }
229268
230269 type DescribeLoadBalancersResponse struct {
320359 }
321360 return nil
322361 }
362
363 type SetLoadBalancerDeleteProtectionArgs struct {
364 LoadBalancerId string
365 DeleteProtection FlagType
366 RegionId common.Region
367 }
368
369 type SetLoadBalancerDeleteProtectionResponse struct {
370 common.Response
371 }
372
373 // SetLoadBalancerDeleteProtection loadbalancer delete protection
374 //
375 // You can read doc at https://help.aliyun.com/document_detail/122674.html?spm=a2c4g.11186623.6.720.694f4265hwOdXQ
376 func (client *Client) SetLoadBalancerDeleteProtection(args *SetLoadBalancerDeleteProtectionArgs) (err error) {
377 response := &SetLoadBalancerDeleteProtectionResponse{}
378 err = client.Invoke("SetLoadBalancerDeleteProtection", args, response)
379 return err
380 }
381
382 type SetLoadBalancerModificationProtectionArgs struct {
383 RegionId common.Region
384 LoadBalancerId string
385 ModificationProtectionStatus ModificationProtectionType
386 ModificationProtectionReason string
387 }
388
389 type SetLoadBalancerModificationProtectionResponse struct {
390 common.Response
391 }
392
393 func (client *Client) SetLoadBalancerModificationProtection(args *SetLoadBalancerModificationProtectionArgs) (err error) {
394 response := &SetLoadBalancerModificationProtectionResponse{}
395 err = client.Invoke("SetLoadBalancerModificationProtection", args, response)
396 return err
397 }
398
399 type ManagedResourceType string
400
401 const (
402 ManagedLoadBalancer = ManagedResourceType("LoadBalancer")
403 ManagedTls = ManagedResourceType("Tls")
404 ManagedVServerGroup = ManagedResourceType("VServerGroup")
405 ManagedMasterSlaveServerGroup = ManagedResourceType("MasterSlaveServerGroup")
406 ManagedAcl = ManagedResourceType("Acl")
407 ManagedListener = ManagedResourceType("Listener")
408 ManagedRule = ManagedResourceType("Rule")
409 ManagedAppRule = ManagedResourceType("AppRule")
410 ManagedDomainExtension = ManagedResourceType("DomainExtension")
411 )
412
413 type ManagedResourceModel struct {
414 ResourceId string
415 Port int
416 Protocol string
417 }
418
419 type ServiceManagedControlArgs struct {
420 RegionId common.Region
421 ServiceManagedMode ServiceManagedModeType
422 ResourceUid string
423 ResourceBid string
424 ResourceType ManagedResourceType
425 Resources []ManagedResourceModel
426 }
427
428 type ServiceManagedControlResponse struct {
429 common.Response
430 }
431
432 //api: https://yuque.antfin-inc.com/docs/share/63b5a2d3-6fb3-4bd7-a50e-c4b385b866fd?#
433 func (client *Client) ServiceManagedControl(args *ServiceManagedControlArgs) (err error) {
434 response := &ServiceManagedControlResponse{}
435 err = client.Invoke("ServiceManagedControl", args, response)
436 return err
437 }
55 "github.com/denverdino/aliyungo/common"
66 )
77
8 func TestLoadBlancer(t *testing.T) {
8 func TestLoadBalancer(t *testing.T) {
99
1010 client := NewTestClientForDebug()
1111
1212 creationArgs := CreateLoadBalancerArgs{
1313 RegionId: common.Beijing,
1414 LoadBalancerName: "test-slb",
15 LoadBalancerSpec: S2Medium, // eni not support slb.s0.share slb(default slb.s0.share)
1516 AddressType: InternetAddressType,
1617 ClientToken: client.GenerateClientToken(),
1718 }
2930
3031 describeLoadBalancersArgs := DescribeLoadBalancersArgs{
3132 RegionId: common.Beijing,
33 }
34
35 loadBalancers, err := client.DescribeLoadBalancers(&describeLoadBalancersArgs)
36
37 if err != nil {
38 t.Fatalf("Failed to DescribeLoadBalancers: %v", err)
39 }
40 t.Logf("DescribeLoadBalancers result: %++v", loadBalancers)
41
42 err = client.SetLoadBalancerStatus(lbId, InactiveStatus)
43 if err != nil {
44 t.Fatalf("Failed to SetLoadBalancerStatus: %v", err)
45 }
46 err = client.SetLoadBalancerName(lbId, "test-slb2")
47 if err != nil {
48 t.Fatalf("Failed to SetLoadBalancerName: %v", err)
49 }
50 loadBalancer, err := client.DescribeLoadBalancerAttribute(lbId)
51
52 if err != nil {
53 t.Fatalf("Failed to DescribeLoadBalancerAttribute: %v", err)
54 }
55 t.Logf("DescribeLoadBalancerAttribute result: %++v", loadBalancer)
56
57 err = client.DeleteLoadBalancer(lbId)
58 if err != nil {
59 t.Errorf("Failed to DeleteLoadBalancer: %v", err)
60 }
61
62 t.Logf("DeleteLoadBalancer successfully: %s", lbId)
63
64 }
65
66 func TestLoadBalancerIPv6(t *testing.T) {
67
68 client := NewTestClientForDebug()
69
70 creationArgs := CreateLoadBalancerArgs{
71 RegionId: common.Hangzhou,
72 LoadBalancerName: "test-slb-ipv6",
73 AddressType: InternetAddressType,
74 MasterZoneId: "cn-hangzhou-e",
75 SlaveZoneId: "cn-hangzhou-f",
76 ClientToken: client.GenerateClientToken(),
77 AddressIPVersion: IPv6,
78 }
79
80 response, err := client.CreateLoadBalancer(&creationArgs)
81 if err != nil {
82 t.Fatalf("Failed to CreateLoadBalancer: %v", err)
83 }
84
85 t.Logf("CreateLoadBalancer result: %v", *response)
86 lbId := response.LoadBalancerId
87
88 describeLoadBalancersArgs := DescribeLoadBalancersArgs{
89 RegionId: common.Hangzhou,
3290 }
3391
3492 loadBalancers, err := client.DescribeLoadBalancers(&describeLoadBalancersArgs)
78136 t.Logf("Result = %++v", slbs)
79137 }
80138 }
139
140 func TestClient_SetLoadBalancerDeleteProtection(t *testing.T) {
141 client := NewTestNewSLBClientForDebug()
142
143 creationArgs := CreateLoadBalancerArgs{
144 RegionId: common.Beijing,
145 LoadBalancerName: "test-slb",
146 LoadBalancerSpec: S2Medium,
147 AddressType: InternetAddressType,
148 ClientToken: client.GenerateClientToken(),
149 }
150
151 response, err := client.CreateLoadBalancer(&creationArgs)
152 if err != nil {
153 t.Fatalf("Failed to CreateLoadBalancer: %v", err)
154 }
155
156 t.Logf("CreateLoadBalancer result: %v", *response)
157 lbId := response.LoadBalancerId
158
159 args := &SetLoadBalancerDeleteProtectionArgs{
160 LoadBalancerId: lbId,
161 DeleteProtection: OnFlag,
162 RegionId: common.Beijing,
163 }
164
165 err = client.SetLoadBalancerDeleteProtection(args)
166 if err != nil {
167 t.Fatalf("Failed %++v", err)
168 }
169 t.Logf("SetLoadBalancerDeleteProtection result: %v", *response)
170
171 err = client.DeleteLoadBalancer(lbId)
172 if err != nil {
173 t.Logf("DeleteLoadBalancer result: %++v", err)
174 } else {
175 t.Fatalf("Failed to set LoadBalancer delete protection.")
176 }
177 }
178
179 func TestClient_SetLoadBalancerModificationProtection(t *testing.T) {
180 client := NewTestNewSLBClientForDebug()
181
182 creationArgs := CreateLoadBalancerArgs{
183 RegionId: common.Beijing,
184 LoadBalancerName: "test-slb-modification-protection",
185 LoadBalancerSpec: S1Small,
186 AddressType: InternetAddressType,
187 ModificationProtectionStatus: ConsoleProtection,
188 ModificationProtectionReason: "kubernetes.do.not.delete",
189 ClientToken: client.GenerateClientToken(),
190 }
191 response, err := client.CreateLoadBalancer(&creationArgs)
192 if err != nil {
193 t.Fatalf("Failed to CreateLoadBalancer: %v", err)
194 }
195
196 t.Logf("CreateLoadBalancer result: %v", *response)
197 lbId := response.LoadBalancerId
198
199 lb, err := client.DescribeLoadBalancerAttribute(lbId)
200 if err != nil {
201 t.Fatalf("Failed to DescribeLoadBalancerAttribute: %v", err)
202 }
203
204 if lb.ModificationProtectionStatus != ConsoleProtection {
205 t.Fatalf("Failed to SetLoadBalancerModificationProtection, slb %s, expected %s got %s",
206 lbId, ConsoleProtection, lb.ModificationProtectionStatus)
207 }
208
209 args := SetLoadBalancerModificationProtectionArgs{
210 RegionId: common.Beijing,
211 LoadBalancerId: lbId,
212 ModificationProtectionStatus: NonProtection,
213 }
214
215 err = client.SetLoadBalancerModificationProtection(&args)
216 if err != nil {
217 t.Fatalf("Failed to SetLoadBalancerModificationProtection: %v", err)
218 }
219
220 lb, err = client.DescribeLoadBalancerAttribute(lbId)
221 if err != nil {
222 t.Fatalf("Failed to DescribeLoadBalancerAttribute: %v", err)
223 }
224
225 if lb.ModificationProtectionStatus != NonProtection {
226 t.Fatalf("Failed to SetLoadBalancerModificationProtection, slb %s, expected %s got %s",
227 lbId, ConsoleProtection, lb.ModificationProtectionStatus)
228 }
229
230 // Delete Slb
231 err = client.DeleteLoadBalancer(lbId)
232 if err != nil {
233 t.Fatalf("Failed to DeleteLoadBalancer: %v", err)
234 }
235
236 }
237
238 func TestClient_ServiceManagedControl(t *testing.T) {
239 client := NewTestNewSLBClientForDebug()
240
241 creationArgs := CreateLoadBalancerArgs{
242 RegionId: common.Beijing,
243 LoadBalancerName: "test-slb-modification-protection",
244 LoadBalancerSpec: S1Small,
245 AddressType: InternetAddressType,
246 ModificationProtectionStatus: ConsoleProtection,
247 ModificationProtectionReason: "kubernetes.do.not.delete",
248 ClientToken: client.GenerateClientToken(),
249 }
250 response, err := client.CreateLoadBalancer(&creationArgs)
251 if err != nil {
252 t.Fatalf("Failed to CreateLoadBalancer: %v", err)
253 }
254
255 t.Logf("CreateLoadBalancer result: %v", *response)
256 lbId := response.LoadBalancerId
257
258 lb, err := client.DescribeLoadBalancerAttribute(lbId)
259 if err != nil {
260 t.Fatalf("Failed to DescribeLoadBalancerAttribute: %v", err)
261 }
262
263 resource := make([]ManagedResourceModel, 0)
264 resource = append(resource, ManagedResourceModel{ResourceId: lb.LoadBalancerId})
265 args := ServiceManagedControlArgs{
266 RegionId: common.Beijing,
267 ServiceManagedMode: Managed,
268 ResourceType: ManagedLoadBalancer,
269 Resources: resource,
270 }
271
272 err = client.ServiceManagedControl(&args)
273 if err != nil {
274 t.Fatalf("Failed to modify resource managed status: %v", err)
275 }
276
277 lb, err = client.DescribeLoadBalancerAttribute(lbId)
278 if err != nil {
279 t.Fatalf("Failed to DescribeLoadBalancerAttribute: %v", err)
280 }
281
282 if lb.ServiceManagedMode != Managed {
283 t.Fatalf("Failed to modify resource managed status, slb %s, expected %s got %s",
284 lbId, Managed, lb.ServiceManagedMode)
285 }
286
287 // Delete Slb
288 err = client.DeleteLoadBalancer(lbId)
289 if err != nil {
290 t.Fatalf("Failed to DeleteLoadBalancer: %v", err)
291 }
292
293 }
1010 client := NewTestClientForDebug()
1111
1212 rulesArr := []Rule{
13 Rule{RuleName: "rule-001", Domain: "datapaking.com", Url: "/rule0001", VServerGroupId: TestVServerGroupID},
14 Rule{RuleName: "rule-002", Domain: "datapaking.com", Url: "/rule0002", VServerGroupId: TestVServerGroupID},
13 {RuleName: "rule-001", Domain: "datapaking.com", Url: "/rule0001", VServerGroupId: TestVServerGroupID},
14 {RuleName: "rule-002", Domain: "datapaking.com", Url: "/rule0002", VServerGroupId: TestVServerGroupID},
1515 }
1616 ruleStr, _ := json.Marshal(rulesArr)
1717
11
22 import (
33 "encoding/json"
4
54 "github.com/denverdino/aliyungo/common"
65 )
76
6261
6362 type RemoveBackendServersArgs struct {
6463 LoadBalancerId string
65 BackendServers []string
64 BackendServers string
6665 }
6766
6867 type RemoveBackendServersResponse struct {
7675 // RemoveBackendServers Remove backend servers
7776 //
7877 // You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-backendserver&RemoveBackendServers
79 func (client *Client) RemoveBackendServers(loadBalancerId string, backendServers []string) (result []BackendServerType, err error) {
78 func (client *Client) RemoveBackendServers(loadBalancerId string, backendServers []BackendServerType) (result []BackendServerType, err error) {
79 bytes, _ := json.Marshal(backendServers)
80
8081 args := &RemoveBackendServersArgs{
8182 LoadBalancerId: loadBalancerId,
82 BackendServers: backendServers,
83 BackendServers: string(bytes),
8384 }
8485 response := &RemoveBackendServersResponse{}
86
8587 err = client.Invoke("RemoveBackendServers", args, response)
8688 if err != nil {
8789 return nil, err
44 func testBackendServers(t *testing.T, client *Client, loadBalancerId string) {
55
66 backendServers := []BackendServerType{
7 BackendServerType{
7 {
88 ServerId: TestInstanceId,
99 Weight: 100,
10 Type: "ecs",
1011 },
12 //BackendServerType{
13 // ServerId: TestENIId,
14 // Weight: 100,
15 // Type: "eni",
16 //},
1117 }
1218
1319 servers, err := client.AddBackendServers(loadBalancerId, backendServers)
2834
2935 t.Logf("Backend servers: %++v", servers)
3036
31 servers, err = client.RemoveBackendServers(loadBalancerId, []string{TestInstanceId})
37 servers, err = client.RemoveBackendServers(loadBalancerId, backendServers)
3238 if err != nil {
3339 t.Errorf("Failed to RemoveBackendServers: %v", err)
3440 }
1010 client := NewTestClientForDebug()
1111
1212 tagItemArr := []TagItem{
13 TagItem{TagKey: "username", TagValue: "test"},
14 TagItem{TagKey: "birdthday", TagValue: "20170101"},
13 {TagKey: "username", TagValue: "test"},
14 {TagKey: "birdthday", TagValue: "20170101"},
1515 }
1616 tagItems, _ := json.Marshal(tagItemArr)
1717
3333 client := NewTestClientForDebug()
3434
3535 tagItemArr := []TagItem{
36 TagItem{TagKey: "username", TagValue: "test"},
37 TagItem{TagKey: "birdthday", TagValue: "20170101"},
36 {TagKey: "username", TagValue: "test"},
37 {TagKey: "birdthday", TagValue: "20170101"},
3838 }
3939 tagItems, _ := json.Marshal(tagItemArr)
4040
44 )
55
66 type VBackendServerType struct {
7 ServerId string
8 Weight int
9 Port int
10 Type string
7 ServerId string
8 Weight int
9 Port int
10 Type string
11 ServerIp string
12 Description string
1113 }
1214
1315 type VServerGroup struct {
16 RegionId common.Region
1417 VServerGroupName string
1518 VServerGroupId string
1619 }
5053 }
5154
5255 type DescribeVServerGroupsArgs struct {
53 LoadBalancerId string
54 RegionId common.Region
56 LoadBalancerId string
57 RegionId common.Region
58 IncludeRule bool
59 IncludeListener bool
5560 }
5661
5762 type DescribeVServerGroupAttributeArgs struct {
8287 VServerGroups struct {
8388 VServerGroup []VServerGroup
8489 }
90 AssociatedObjects struct {
91 Listeners string
92 Rules string
93 }
8594 }
86 type DescribeVServerGroupAttributeResponse CreateVServerGroupResponse
95 type DescribeVServerGroupAttributeResponse struct {
96 common.Response
97 VServerGroupId string
98 VServerGroupName string
99 LoadBalancerId string
100 BackendServers VBackendServers
101 }
87102
88103 func (client *Client) CreateVServerGroup(args *CreateVServerGroupArgs) (response *CreateVServerGroupResponse, err error) {
89104 response = &CreateVServerGroupResponse{}
22 import (
33 "encoding/json"
44 "testing"
5
6 "fmt"
57
68 "github.com/denverdino/aliyungo/common"
79 )
5658
5759 func TestDescribeVServerGroups(t *testing.T) {
5860 arg := &DescribeVServerGroupsArgs{
59 LoadBalancerId: loadBalancerId,
60 RegionId: region,
61 LoadBalancerId: loadBalancerId,
62 RegionId: region,
63 IncludeListener: true,
64 IncludeRule: true,
6165 }
6266 response, err := client.DescribeVServerGroups(arg)
6367 if err != nil {
6468 t.Error(err)
6569 } else {
66 t.Log(response)
67 for _, vserverGroup := range response.VServerGroups.VServerGroup {
68 deleteVServerGroupIdList = append(deleteVServerGroupIdList, vserverGroup.VServerGroupId)
69 }
70 fmt.Println(PrettyJson(response))
7071 }
7172 }
7273
0 package slb
1
2 import (
3 "github.com/denverdino/aliyungo/common"
4 )
5
6 type DescribeZonesArgs struct {
7 RegionId common.Region
8 }
9
10 //
11 // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&zonetype
12 type ZoneType struct {
13 ZoneId string
14 LocalName string
15 SlaveZones struct {
16 SlaveZone []ZoneType
17 }
18 }
19
20 type DescribeZonesResponse struct {
21 common.Response
22 Zones struct {
23 Zone []ZoneType
24 }
25 }
26
27 // DescribeZones describes zones
28 func (client *Client) DescribeZones(regionId common.Region) (zones []ZoneType, err error) {
29 response, err := client.DescribeZonesWithRaw(regionId)
30 if err == nil {
31 return response.Zones.Zone, nil
32 }
33
34 return []ZoneType{}, err
35 }
36
37 func (client *Client) DescribeZonesWithRaw(regionId common.Region) (response *DescribeZonesResponse, err error) {
38 args := DescribeZonesArgs{
39 RegionId: regionId,
40 }
41 response = &DescribeZonesResponse{}
42
43 err = client.Invoke("DescribeZones", &args, response)
44
45 if err == nil {
46 return response, nil
47 }
48
49 return nil, err
50 }
0 package slb
1
2 import (
3 "github.com/denverdino/aliyungo/common"
4 "testing"
5 )
6
7 func TestDescribeZones(t *testing.T) {
8
9 client := NewTestNewSLBClientForDebug()
10
11 zones, err := client.DescribeZones(common.Hangzhou)
12
13 if err == nil {
14 t.Logf("regions: %v", zones)
15 } else {
16 t.Errorf("Failed to DescribeZones: %v", err)
17 }
18
19 }
2525
2626 func (client *Client) SetDebug(debug bool) {
2727 client.debug = debug
28 }
29
30 // SetTransport sets transport to the http client
31 func (client *Client) SetTransport(transport http.RoundTripper) {
32 if client.httpClient == nil {
33 client.httpClient = &http.Client{}
34 }
35 client.httpClient.Transport = transport
2836 }
2937
3038 type Project struct {
00 package sls
11
2 import "encoding/json"
2 import (
3 "encoding/json"
4 )
35
46 type IndexLineConfig struct {
57 TokenList []string `json:"token,omitempty"`
68 CaseSensitive bool `json:"caseSensitive"`
79 IncludeKeys []string `json:"include_keys,omitempty"`
8 Exclude_keys []string `json:"exclude_keys,omitempty"`
10 ExcludeKeys []string `json:"exclude_keys,omitempty"`
911 }
1012
1113 type IndexKeyConfig struct {
14 Type string `json:"type,omitempty"`
15 Alias string `json:"alias,omitempty"`
16 Chn bool `json:"chn"`
1217 TokenList []string `json:"token,omitempty"`
13 CaseSensitive bool `json:"caseSensitive,omitempty"`
18 CaseSensitive bool `json:"caseSensitive"`
19 DocValue bool `json:"doc_value"`
1420 }
1521
1622 type IndexConfig struct {
1723 TTL int `json:"ttl,omitempty"`
18 LineConfig IndexLineConfig `json:"line,omitempty"`
24 LineConfig *IndexLineConfig `json:"line,omitempty"`
1925 KeyConfigList map[string]IndexKeyConfig `json:"keys,omitempty"`
2026 }
2127
99 p := DefaultProject(t)
1010 config := &IndexConfig{
1111 TTL: 7,
12 LineConfig: IndexLineConfig{
12 LineConfig: &IndexLineConfig{
1313 TokenList: []string{",", "\t", "\n", " ", ";"},
1414 CaseSensitive: false,
1515 },
11
22 import (
33 "encoding/json"
4 "errors"
54 "fmt"
65 "strconv"
76 )
153152 return v, nil
154153 }
155154
156 return nil, errors.New(fmt.Sprintf("%v is not a string array", configs["config"]))
155 return nil, fmt.Errorf("%v is not a string array", configs["config"])
157156 }
77 "io/ioutil"
88 "log"
99 "net/http"
10 "net/http/httputil"
1011 "net/url"
1112 "strconv"
1213 "time"
9091 if err != nil {
9192 return nil, err
9293 }
94 if client.debug {
95 reqDump, _ := httputil.DumpRequest(hreq, true)
96 log.Printf("---------------REQUEST---------------\n%s\n\n", string(reqDump))
97 }
9398 t0 := time.Now()
9499 resp, err := client.httpClient.Do(hreq)
95100 t1 := time.Now()
96101 if err != nil {
97102 return nil, err
98103 }
99
100104 if client.debug {
105 resDump, _ := httputil.DumpResponse(resp, true)
106 log.Printf("---------------RESPONSE---------------\n%s\n\n", string(resDump))
101107 log.Printf("Invoke %s %s %d (%v)", req.method, req.url(), resp.StatusCode, t1.Sub(t0))
102108 }
103109
5050 canonicalizedResource := req.path
5151 var paramNames []string
5252 if req.params != nil && len(req.params) > 0 {
53 for k, _ := range req.params {
53 for k := range req.params {
5454 paramNames = append(paramNames, k)
5555 }
5656 sort.Strings(paramNames)
6868 func canonicalizeHeader(headers map[string]string) string {
6969 var canonicalizedHeaders []string
7070
71 for k, _ := range headers {
71 for k := range headers {
7272 if lower := strings.ToLower(k); strings.HasPrefix(lower, HeaderSLSPrefix1) || strings.HasPrefix(lower, HeaderSLSPrefix2) {
7373 canonicalizedHeaders = append(canonicalizedHeaders, lower)
7474 }
2525
2626 princpalPolicyDocument = ram.AssumeRolePolicyDocument{
2727 Statement: []ram.AssumeRolePolicyItem{
28 ram.AssumeRolePolicyItem{Action: "sts:AssumeRole", Effect: "Allow", Principal: princpal},
28 {Action: "sts:AssumeRole", Effect: "Allow", Principal: princpal},
2929 },
3030 Version: "1"}
3131
3838
3939 var policyDocument = ram.PolicyDocument{
4040 Statement: []ram.PolicyItem{
41 ram.PolicyItem{
41 {
4242 Action: "oss:GetObject",
4343 Effect: "Allow",
4444 Resource: "acs:oss:*:*:*/anyprefix",
6565 func createPolicyDocument() *ram.PolicyDocument {
6666 return &ram.PolicyDocument{
6767 Statement: []ram.PolicyItem{
68 ram.PolicyItem{
68 {
6969 Action: "oss:GetObject",
7070 Effect: "Allow",
7171 Resource: "acs:oss:*:*:*/*",
1313 got := make([]time.Duration, 0, len(want)) // avoid allocation when testing timing
1414 t0 := time.Now()
1515 for a := testAttempt.Start(); a.Next(); {
16 got = append(got, time.Now().Sub(t0))
16 got = append(got, time.Since(t0))
1717 }
18 got = append(got, time.Now().Sub(t0))
18 got = append(got, time.Since(t0))
1919 if len(got) != len(want) {
2020 t.Fatalf("Failed!")
2121 }
4646 // add to support url.Values
4747 mapValues, ok := i.(url.Values)
4848 if ok {
49 for k, _ := range mapValues {
49 for k := range mapValues {
5050 values.Set(k, mapValues.Get(k))
5151 }
5252 return
190190 // add to support url.Values
191191 mapValues, ok := i.(url.Values)
192192 if ok {
193 for k, _ := range mapValues {
193 for k := range mapValues {
194194 values.Set(k, mapValues.Get(k))
195195 }
196196 return
6464 StringArray: []string{"abc", "xyz"},
6565 StringArray2: []string{"abc", "xyz"},
6666 StructArray: []SubStruct{
67 SubStruct{A: "a", B: 1},
68 SubStruct{A: "x", B: 2},
67 {A: "a", B: 1},
68 {A: "x", B: 2},
6969 },
7070 SubStruct: SubStruct{A: "M", B: 0},
7171 test: TestString("test"),
33 "bytes"
44 srand "crypto/rand"
55 "encoding/binary"
6 "encoding/json"
7 "fmt"
68 "math/rand"
79 "net/http"
810 "net/url"
5759 if v != "" {
5860 buf.WriteString("=")
5961 buf.WriteString(url.QueryEscape(v))
62 }
63 }
64 }
65 return buf.String()
66 }
67
68 // Like Encode, but key and value are not escaped
69 func EncodeWithoutEscape(v url.Values) string {
70 if v == nil {
71 return ""
72 }
73 var buf bytes.Buffer
74 keys := make([]string, 0, len(v))
75 for k := range v {
76 keys = append(keys, k)
77 }
78 sort.Strings(keys)
79 for _, k := range keys {
80 vs := v[k]
81 prefix := k
82 for _, v := range vs {
83 if buf.Len() > 0 {
84 buf.WriteByte('&')
85 }
86 buf.WriteString(prefix)
87 if v != "" {
88 buf.WriteString("=")
89 buf.WriteString(v)
6090 }
6191 }
6292 }
144174 return string(s)
145175
146176 }
177
178 func PrettyJson(object interface{}) string {
179 b, err := json.MarshalIndent(object, "", " ")
180 if err != nil {
181 fmt.Printf("ERROR: PrettyJson, %v\n %s\n", err, b)
182 }
183 return string(b)
184 }