├── .circleci └── config.yml ├── .github └── workflows │ └── go.yml ├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── acm ├── acm.go ├── acm_test.go ├── coding.go └── coding_test.go ├── cdn ├── auth │ ├── random_uuid.go │ ├── random_uuid_test.go │ ├── sign_url.go │ └── sign_url_test.go ├── client.go ├── client_test.go ├── config.go ├── config_test.go ├── domain.go ├── domain_test.go ├── refresh.go ├── service.go └── types.go ├── cen ├── client.go ├── route.go └── route_test.go ├── cms ├── alarm.go ├── alarm_test.go ├── alerts.go ├── apiproxy.go ├── bytesbuffer │ └── bytesbuffer.go ├── client.go ├── config_test.go ├── project.go └── util │ ├── dateutil.go │ ├── signature.go │ └── uri.go ├── common ├── client.go ├── client_test.go ├── endpoint.go ├── endpoint_test.go ├── endpoints.xml ├── logger.go ├── logger_test.go ├── regions.go ├── regions_test.go ├── request.go ├── types.go ├── utils │ └── utils.go └── version.go ├── cs ├── client.go ├── clusters.go ├── clusters_test.go ├── config_test.go ├── kubernetes_cluster_test.go ├── kubernets_cluster.go ├── node_pool.go ├── node_pool_test.go ├── projects.go ├── projects_client.go ├── registry.go ├── serverless.go ├── serverless_test.go ├── services.go ├── signature.go ├── token.go ├── token_test.go └── volumes.go ├── dm ├── README.md ├── client.go ├── mail.go └── mail_test.go ├── dns ├── AddDomain.go ├── AddDomainGroup.go ├── AddDomainGroup_test.go ├── AddDomainRecord.go ├── AddDomainRecord_test.go ├── AddDomain_test.go ├── ChangeDomainGroup.go ├── ChangeDomainGroup_test.go ├── DeleteDomain.go ├── DeleteDomainGroup.go ├── DeleteDomainGroup_test.go ├── DeleteDomainRecord.go ├── DeleteDomainRecord_test.go ├── DeleteDomain_test.go ├── DeleteSubDomainRecords.go ├── DeleteSubDomainRecords_test.go ├── DescribeDomainGroups.go ├── DescribeDomainGroups_test.go ├── DescribeDomainInfo.go ├── DescribeDomainInfo_test.go ├── DescribeDomainRecordInfo.go ├── DescribeDomainRecordInfoNew.go ├── DescribeDomainRecordInfoNew_test.go ├── DescribeDomainRecordInfo_test.go ├── DescribeDomainRecords.go ├── DescribeDomainRecordsNew.go ├── DescribeDomainRecordsNew_test.go ├── DescribeDomainRecords_test.go ├── DescribeDomains.go ├── DescribeDomains_test.go ├── DescribeSubDomainRecords.go ├── DescribeSubDomainRecords_test.go ├── GetMainDomainName.go ├── GetMainDomainName_test.go ├── UpdateDomainGroup.go ├── UpdateDomainGroup_test.go ├── UpdateDomainRecord.go ├── UpdateDomainRecord_test.go ├── client.go ├── config_test.go └── record.go ├── ecs ├── client.go ├── client_test.go ├── config_test.go ├── disks.go ├── disks_test.go ├── eni.go ├── eni_test.go ├── forward_entry.go ├── images.go ├── images_test.go ├── instance_types.go ├── instance_types_test.go ├── instances.go ├── instances_test.go ├── monitoring.go ├── monitoring_test.go ├── nat_gateway.go ├── nat_gateway_test.go ├── networks.go ├── networks_test.go ├── regions.go ├── route_entry.go ├── route_entry_test.go ├── route_tables.go ├── route_tables_test.go ├── router_interface.go ├── router_interface_test.go ├── security_groups.go ├── security_groups_test.go ├── snapshots.go ├── snapshots_test.go ├── snat_entry.go ├── snat_entry_test.go ├── ssh_key_pair.go ├── tags.go ├── tags_test.go ├── vpcs.go ├── vpcs_test.go ├── vrouters.go ├── vrouters_test.go ├── vswitches.go ├── vswitches_test.go └── zones.go ├── ess ├── client.go ├── config_test.go ├── configuration.go ├── configuration_test.go ├── group.go ├── group_test.go ├── rule.go ├── rule_test.go ├── schedule.go └── schedule_test.go ├── go.mod ├── go.sum ├── kms ├── client.go ├── config_test.go ├── decrypt.go ├── decrypt_test.go ├── encrypt.go ├── encrypt_test.go ├── keys.go ├── keys_test.go ├── regions.go └── regions_test.go ├── location ├── client.go ├── config_test.go ├── endpoints.go ├── endpoints_test.go ├── regions.go ├── regions_test.go ├── services.go └── services_test.go ├── metadata ├── client.go └── client_test.go ├── mns ├── client.go ├── client_test.go ├── queue.go ├── request.go ├── signature.go ├── types.go └── util.go ├── mq ├── client.go ├── client_test.go ├── types.go └── util.go ├── nas ├── CreateAccessRule.go ├── CreateFileSystem.go ├── CreateMountTarget.go ├── DescribeAccessRules.go ├── DescribeFileSystems.go ├── DescribeMountTargets.go └── client.go ├── opensearch ├── application.go ├── client.go ├── data.go └── search.go ├── oss ├── authenticate_callback.go ├── client.go ├── client_test.go ├── config_test.go ├── export.go ├── multi.go ├── multi_test.go ├── regions.go ├── regions_test.go └── signature.go ├── push ├── README.md ├── client.go └── push.go ├── pvtz ├── changeLogs.go ├── client.go ├── client_test.go ├── config_test.go ├── records.go ├── regions.go └── zones.go ├── ram ├── account.go ├── account_test.go ├── ak.go ├── ak_test.go ├── api.go ├── client.go ├── client_test.go ├── error.go ├── group.go ├── group_test.go ├── mfa.go ├── mfa_test.go ├── policy.go ├── policy_test.go ├── profile.go ├── profile_test.go ├── role.go ├── role_test.go ├── security.go ├── security_test.go └── types.go ├── rds ├── client.go ├── config_test.go ├── instances.go ├── instances_test.go └── monitoring.go ├── ros ├── client.go ├── config_test.go ├── other.go ├── other_test.go ├── resource.go ├── resource_test.go ├── rpc_client.go ├── signature.go ├── stack.go ├── stack_test.go ├── standard │ ├── client.go │ ├── client_test.go │ └── stack.go ├── template.go └── template_test.go ├── slb ├── certificates.go ├── client.go ├── config_test.go ├── listeners.go ├── listerners_test.go ├── loadbalancers.go ├── loadbalancers_test.go ├── regions.go ├── regions_test.go ├── rules.go ├── rules_test.go ├── servers.go ├── servers_test.go ├── tags.go ├── tags_test.go ├── vserver_group.go ├── vserver_group_test.go ├── zones.go └── zones_test.go ├── sls ├── client.go ├── client_test.go ├── index.go ├── index_test.go ├── logstore.go ├── logstore_test.go ├── logtail.go ├── logtail_test.go ├── machine_group.go ├── machine_group_test.go ├── request.go ├── signature.go └── sls.pb.go ├── sms ├── README.md ├── client.go ├── dysms.go ├── sms.go └── sms_test.go ├── sts ├── assume_role.go ├── assume_role_test.go ├── client.go ├── client_test.go ├── get_caller_identity.go └── get_caller_identity_test.go └── util ├── attempt.go ├── attempt_test.go ├── encoding.go ├── encoding_test.go ├── iso6801.go ├── iso6801_test.go ├── signature.go ├── signature_test.go ├── util.go └── util_test.go /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/golang:1.10 6 | working_directory: /go/src/github.com/denverdino/aliyungo 7 | steps: 8 | - checkout 9 | - run: go get -t -d -v ./... 10 | - run: go test -run=nope ./... 11 | - run: go vet ./... 12 | 13 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | on: [push] 3 | jobs: 4 | 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | steps: 9 | 10 | - name: Set up Go 1.13 11 | uses: actions/setup-go@v1 12 | with: 13 | go-version: 1.13 14 | id: go 15 | 16 | - name: Check out code into the Go module directory 17 | uses: actions/checkout@v1 18 | 19 | - name: Get dependencies 20 | run: | 21 | go get -v -t -d ./... 22 | if [ -f Gopkg.toml ]; then 23 | curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh 24 | dep ensure 25 | fi 26 | - name: Run golangci-lint with reviewdog 27 | uses: reviewdog/action-golangci-lint@v1.1.3 28 | with: 29 | github_token: ${{ secrets.github_token }} 30 | 31 | 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | arch: 3 | - AMD64 4 | - ppc64le 5 | go: 6 | - 1.10.8 7 | 8 | # let us have speedy Docker-based Travis workers 9 | sudo: false 10 | 11 | script: 12 | - go get ./... 13 | - go vet ./... 14 | - go build ./... 15 | - go test -run=nope ./... 16 | -------------------------------------------------------------------------------- /acm/acm_test.go: -------------------------------------------------------------------------------- 1 | package acm 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "testing" 8 | ) 9 | 10 | func getClient() *Client { 11 | client, err := NewClient(func(c *Client) { 12 | c.AccessKey = os.Getenv("AccessKeyId") 13 | c.SecretKey = os.Getenv("AccessKeySecret") 14 | c.EndPoint = "acm.aliyun.com" 15 | c.NameSpace = "test" 16 | }) 17 | 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | 22 | return client 23 | } 24 | 25 | func RunWithTest(t *testing.T, test func(client *Client, t *testing.T)) { 26 | client := getClient() 27 | defer client.Delete("test", "test") 28 | 29 | _, err := client.Publish("test", "test", "test测试") 30 | 31 | if err != nil { 32 | t.Fatalf("pulish error:%s", err) 33 | } 34 | 35 | test(client, t) 36 | } 37 | 38 | func TestNewClient(t *testing.T) { 39 | client := getClient() 40 | servers := client.GetServers() 41 | 42 | if len(servers) == 0 { 43 | t.Error("get server error") 44 | } 45 | } 46 | 47 | func TestClient_GetConfig(t *testing.T) { 48 | RunWithTest(t, func(client *Client, t *testing.T) { 49 | ret, err := client.GetConfig("test", "test") 50 | if err != nil { 51 | t.Error(err) 52 | } 53 | if ret != "test测试" { 54 | t.Error("wrong respond content") 55 | } 56 | fmt.Println(ret) 57 | }) 58 | } 59 | 60 | func TestClient_Subscribe(t *testing.T) { 61 | RunWithTest(t, func(client *Client, t *testing.T) { 62 | _, err := client.Subscribe("test", "test", "") 63 | if err != nil { 64 | t.Error(err) 65 | } 66 | }) 67 | } 68 | 69 | func TestClient_GetAllConfig(t *testing.T) { 70 | RunWithTest(t, func(client *Client, t *testing.T) { 71 | _, err := client.GetAllConfigs(1, 200) 72 | if err != nil { 73 | t.Error(err) 74 | } 75 | }) 76 | } 77 | -------------------------------------------------------------------------------- /acm/coding.go: -------------------------------------------------------------------------------- 1 | package acm 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "io/ioutil" 7 | 8 | "golang.org/x/text/encoding/simplifiedchinese" 9 | "golang.org/x/text/transform" 10 | ) 11 | 12 | func GbkToUtf8(s []byte) ([]byte, error) { 13 | reader := GbkToUtf8Reader(bytes.NewReader(s)) 14 | return ioutil.ReadAll(reader) 15 | } 16 | 17 | func Utf8ToGbk(s []byte) ([]byte, error) { 18 | reader := Utf8ToGbkReader(bytes.NewReader(s)) 19 | return ioutil.ReadAll(reader) 20 | } 21 | 22 | //return utf8 23 | func GbkToUtf8Reader(s io.Reader) io.Reader { 24 | return transform.NewReader(s, simplifiedchinese.GBK.NewDecoder()) 25 | } 26 | 27 | //return gbk 28 | func Utf8ToGbkReader(s io.Reader) io.Reader { 29 | return transform.NewReader(s, simplifiedchinese.GBK.NewEncoder()) 30 | } 31 | -------------------------------------------------------------------------------- /acm/coding_test.go: -------------------------------------------------------------------------------- 1 | package acm 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var s = "GBK与UTF-8 编码转换测试" 8 | 9 | func TestGbkToUtf8(t *testing.T) { 10 | gbk, err := Utf8ToGbk([]byte(s)) 11 | if err != nil { 12 | t.Error(err) 13 | } 14 | 15 | utf8, err := GbkToUtf8([]byte(gbk)) 16 | if err != nil { 17 | t.Error(err) 18 | } 19 | 20 | if string(utf8) != s { 21 | t.Error("Iconv Fail:", utf8, s) 22 | } 23 | } 24 | 25 | func TestUtf8ToGbk(t *testing.T) { 26 | _, err := Utf8ToGbk([]byte(s)) 27 | if err != nil { 28 | t.Error(err) 29 | } 30 | 31 | //fmt.Printf("%s", string(gbk)) 32 | } 33 | -------------------------------------------------------------------------------- /cdn/auth/random_uuid_test.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | const iterations = 1000 8 | 9 | func TestUUID4Generation(t *testing.T) { 10 | for i := 0; i < iterations; i++ { 11 | u := GenerateUUID() 12 | 13 | if u[6]&0xf0 != 0x40 { 14 | t.Fatalf("version byte not correctly set: %v, %08b %08b", u, u[6], u[6]&0xf0) 15 | } 16 | 17 | if u[8]&0xc0 != 0x80 { 18 | t.Fatalf("top order 8th byte not correctly set: %v, %b", u, u[8]) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /cdn/auth/sign_url_test.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "crypto/md5" 5 | "fmt" 6 | "net/url" 7 | "reflect" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | var ( 13 | testSignTime = time.Unix(1541064730, 0) 14 | testPrivKey = "12345678" 15 | ) 16 | 17 | func assertEqual(t *testing.T, name string, x, y interface{}) { 18 | if !reflect.DeepEqual(x, y) { 19 | t.Errorf("%s: Not equal! Expected='%v', Actual='%v'\n", name, x, y) 20 | t.FailNow() 21 | } 22 | } 23 | 24 | func TestAtypeAuth(t *testing.T) { 25 | r, _ := url.Parse("https://example.com/a?foo=bar") 26 | url := aTypeTest(r, testPrivKey, testSignTime) 27 | assertEqual(t, "testTypeA", "https://example.com/a?foo=bar&auth_key=1541064730-0-0-f9dd5ed1e274ab4b1d5f5745344bf28b", url) 28 | } 29 | 30 | func TestBtypeAuth(t *testing.T) { 31 | signer := NewURLSigner("b", testPrivKey) 32 | url, _ := signer.Sign("https://example.com/a?foo=bar", testSignTime) 33 | assertEqual(t, "testTypeB", "https://example.com/201811011732/3a19d83a89ccb00a73212420791b0123/a?foo=bar", url) 34 | } 35 | 36 | func TestCtypeAuth(t *testing.T) { 37 | signer := NewURLSigner("c", testPrivKey) 38 | url, _ := signer.Sign("https://example.com/a?foo=bar", testSignTime) 39 | assertEqual(t, "testTypeC", "https://example.com/7d6b308ce87beb16d9dba32d741220f6/5bdac81a/a?foo=bar", url) 40 | } 41 | 42 | func aTypeTest(r *url.URL, privateKey string, expires time.Time) string { 43 | //rand equals "0" in test case 44 | rand := "0" 45 | uid := "0" 46 | secret := fmt.Sprintf("%s-%d-%s-%s-%s", r.Path, expires.Unix(), rand, uid, privateKey) 47 | hashValue := md5.Sum([]byte(secret)) 48 | authKey := fmt.Sprintf("%d-%s-%s-%x", expires.Unix(), rand, uid, hashValue) 49 | if r.RawQuery == "" { 50 | return fmt.Sprintf("%s?auth_key=%s", r.String(), authKey) 51 | } 52 | return fmt.Sprintf("%s&auth_key=%s", r.String(), authKey) 53 | } 54 | -------------------------------------------------------------------------------- /cdn/client.go: -------------------------------------------------------------------------------- 1 | package cdn 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | const ( 10 | // CDNDefaultEndpoint is the default API endpoint of CDN services 11 | CDNDefaultEndpoint = "https://cdn.aliyuncs.com" 12 | CDNAPIVersion = "2014-11-11" 13 | ) 14 | 15 | type CdnClient struct { 16 | common.Client 17 | } 18 | 19 | func NewClient(accessKeyId string, accessKeySecret string) *CdnClient { 20 | endpoint := os.Getenv("CDN_ENDPOINT") 21 | if endpoint == "" { 22 | endpoint = CDNDefaultEndpoint 23 | } 24 | return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) 25 | } 26 | 27 | func NewClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string) *CdnClient { 28 | client := &CdnClient{} 29 | client.Init(endpoint, CDNAPIVersion, accessKeyId, accessKeySecret) 30 | return client 31 | } 32 | -------------------------------------------------------------------------------- /cdn/client_test.go: -------------------------------------------------------------------------------- 1 | package cdn 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | /* 8 | Set your AccessKeyId and AccessKeySecret in env 9 | simply use the command below 10 | AccessKeyId=YourAccessKeyId AccessKeySecret=YourAccessKeySecret go test 11 | */ 12 | var ( 13 | AccessKeyId = os.Getenv("AccessKeyId") 14 | AccessKeySecret = os.Getenv("AccessKeySecret") 15 | ) 16 | 17 | func NewTestClient() *CdnClient { 18 | client := NewClient(AccessKeyId, AccessKeySecret) 19 | return client 20 | } 21 | -------------------------------------------------------------------------------- /cdn/domain_test.go: -------------------------------------------------------------------------------- 1 | package cdn 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var ( 8 | domainName = "www.jb51.net" 9 | domain = AddDomainRequest{ 10 | DomainName: domainName, 11 | CdnType: "web", 12 | SourceType: "domain", 13 | Sources: "aliyun.com", 14 | } 15 | descDomainReq = DescribeDomainRequest{ 16 | DomainName: domainName, 17 | } 18 | modifyDomainReq = ModifyDomainRequest{ 19 | DomainName: domainName, 20 | SourceType: "domain", 21 | SourcePort: 443, 22 | Sources: "aliyun.com", 23 | } 24 | ) 25 | 26 | func TestAddCdnDomain(t *testing.T) { 27 | client := NewTestClient() 28 | resp, err := client.AddCdnDomain(domain) 29 | if err != nil { 30 | t.Errorf("Failed to AddCdnDomain %v", err) 31 | } 32 | t.Logf("pass AddCdnDomain %v", resp) 33 | } 34 | 35 | func TestDescribeCdnDomainDetail(t *testing.T) { 36 | client := NewTestClient() 37 | resp, err := client.DescribeCdnDomainDetail(descDomainReq) 38 | if err != nil { 39 | t.Errorf("Failed to DescribeCdnDomainDetail %v", err) 40 | } 41 | t.Logf("pass DescribeCdnDomainDetail %v", resp) 42 | } 43 | 44 | func TestModifyCdnDomain(t *testing.T) { 45 | client := NewTestClient() 46 | resp, err := client.ModifyCdnDomain(modifyDomainReq) 47 | if err != nil { 48 | t.Errorf("Failed to ModifyCdnDomain %v", err) 49 | } 50 | t.Logf("pass ModifyCdnDomain %v", resp) 51 | } 52 | 53 | func TestStopCdnDomain(t *testing.T) { 54 | client := NewTestClient() 55 | resp, err := client.StopCdnDomain(descDomainReq) 56 | if err != nil { 57 | t.Errorf("Failed to StopCdnDomain %v", err) 58 | } 59 | t.Logf("pass StopCdnDomain %v", resp) 60 | } 61 | 62 | func TestStartCdnDomain(t *testing.T) { 63 | client := NewTestClient() 64 | resp, err := client.StartCdnDomain(descDomainReq) 65 | if err != nil { 66 | t.Errorf("Failed to StartCdnDomain %v", err) 67 | } 68 | t.Logf("pass StartCdnDomain %v", resp) 69 | } 70 | 71 | func TestDeleteCdnDomain(t *testing.T) { 72 | client := NewTestClient() 73 | resp, err := client.DeleteCdnDomain(descDomainReq) 74 | if err != nil { 75 | t.Errorf("Failed to DeleteCdnDomain %v", err) 76 | } 77 | t.Logf("pass DeleteCdnDomain %v", resp) 78 | } 79 | -------------------------------------------------------------------------------- /cdn/refresh.go: -------------------------------------------------------------------------------- 1 | package cdn 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type RefreshRequest struct { 10 | ObjectPath string 11 | // optional 12 | ObjectType string 13 | } 14 | 15 | type RefreshResponse struct { 16 | CdnCommonResponse 17 | RefreshTaskId string 18 | } 19 | 20 | type PushResponse struct { 21 | CdnCommonResponse 22 | PushTaskId string 23 | } 24 | 25 | type DescribeRequest struct { 26 | // optional 27 | TaskId string 28 | ObjectPath string 29 | common.Pagination 30 | } 31 | 32 | type Task struct { 33 | TaskId string 34 | ObjectPath string 35 | Status string 36 | Process string 37 | CreationTime time.Time 38 | Description string 39 | } 40 | 41 | type DescribeResponse struct { 42 | CdnCommonResponse 43 | common.PaginationResult 44 | Tasks struct { 45 | CDNTask []Task 46 | } 47 | } 48 | 49 | type QuotaResponse struct { 50 | CdnCommonResponse 51 | UrlQuota string 52 | DirQuota string 53 | UrlRemain string 54 | DirRemain string 55 | } 56 | 57 | func (client *CdnClient) RefreshObjectCaches(req RefreshRequest) (RefreshResponse, error) { 58 | var resp RefreshResponse 59 | err := client.Invoke("RefreshObjectCaches", req, &resp) 60 | if err != nil { 61 | return RefreshResponse{}, err 62 | } 63 | return resp, nil 64 | } 65 | 66 | func (client *CdnClient) PushObjectCache(req RefreshRequest) (PushResponse, error) { 67 | var resp PushResponse 68 | err := client.Invoke("PushObjectCache", req, &resp) 69 | if err != nil { 70 | return PushResponse{}, err 71 | } 72 | return resp, nil 73 | } 74 | 75 | func (client *CdnClient) DescribeRefreshTasks(req DescribeRequest) (DescribeResponse, error) { 76 | var resp DescribeResponse 77 | err := client.Invoke("DescribeRefreshTasks", req, &resp) 78 | if err != nil { 79 | return DescribeResponse{}, err 80 | } 81 | return resp, nil 82 | } 83 | 84 | func (client *CdnClient) DescribeRefreshQuota() (QuotaResponse, error) { 85 | var resp QuotaResponse 86 | err := client.Invoke("DescribeRefreshQuota", struct{}{}, &resp) 87 | if err != nil { 88 | return QuotaResponse{}, err 89 | } 90 | return resp, nil 91 | } 92 | -------------------------------------------------------------------------------- /cdn/service.go: -------------------------------------------------------------------------------- 1 | package cdn 2 | 3 | import "time" 4 | 5 | type ServiceRequest struct { 6 | InternetChargeType string 7 | } 8 | 9 | type Service struct { 10 | InternetChargeType string 11 | OpeningTime string 12 | ChangingChargeType string 13 | ChangingAffectTime time.Time 14 | OperationLocks struct { 15 | LockReason []string 16 | } 17 | } 18 | 19 | type ServiceResponse struct { 20 | CdnCommonResponse 21 | Service 22 | } 23 | 24 | func (client *CdnClient) OpenCdnService(req ServiceRequest) (CdnCommonResponse, error) { 25 | var resp CdnCommonResponse 26 | err := client.Invoke("OpenCdnService", req, &resp) 27 | if err != nil { 28 | return CdnCommonResponse{}, err 29 | } 30 | return resp, nil 31 | } 32 | 33 | func (client *CdnClient) DescribeCdnService() (ServiceResponse, error) { 34 | var resp ServiceResponse 35 | err := client.Invoke("DescribeCdnService", struct{}{}, &resp) 36 | if err != nil { 37 | return ServiceResponse{}, err 38 | } 39 | return resp, nil 40 | } 41 | 42 | func (client *CdnClient) ModifyCdnService(req ServiceRequest) (CdnCommonResponse, error) { 43 | var resp CdnCommonResponse 44 | err := client.Invoke("ModifyCdnService", req, &resp) 45 | if err != nil { 46 | return CdnCommonResponse{}, err 47 | } 48 | return resp, nil 49 | } 50 | -------------------------------------------------------------------------------- /cdn/types.go: -------------------------------------------------------------------------------- 1 | package cdn 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | const ( 10 | Web = "web" 11 | Download = "download" 12 | Video = "video" 13 | LiveStream = "liveStream" 14 | Ipaddr = "ipaddr" 15 | Domain = "domain" 16 | OSS = "oss" 17 | Domestic = "domestic" 18 | Overseas = "overseas" 19 | Global = "global" 20 | ContentType = "Content-Type" 21 | CacheControl = "Cache-Control" 22 | ContentDisposition = "Content-Disposition" 23 | ContentLanguage = "Content-Language" 24 | Expires = "Expires" 25 | AccessControlAllowOrigin = "Access-Control-Allow-Origin" 26 | AccessControlAllowMethods = "Access-Control-Allow-Methods" 27 | AccessControlMaxAge = "Access-Control-Max-Age" 28 | ) 29 | 30 | var CdnTypes = []string{Web, Download, Video, LiveStream} 31 | var SourceTypes = []string{Ipaddr, Domain, OSS} 32 | var Scopes = []string{Domestic, Overseas, Global} 33 | var HeaderKeys = []string{ContentType, CacheControl, ContentDisposition, ContentLanguage, Expires, AccessControlAllowMethods, AccessControlAllowOrigin, AccessControlMaxAge} 34 | 35 | type CdnCommonResponse struct { 36 | common.Response 37 | } 38 | 39 | type Domains struct { 40 | DomainName string 41 | Cname string 42 | CdnType string 43 | DomainStatus string 44 | GmtCreated string 45 | GmtModified string 46 | Description string 47 | } 48 | 49 | type MonitorDataItem struct { 50 | TimeStamp string 51 | QueryPerSecond string 52 | BytesHitRate string 53 | BytesPerSecond string 54 | RequestHitRate string 55 | AverageObjectSize string 56 | } 57 | 58 | type TaskItem struct { 59 | TaskId string 60 | ObjectPath string 61 | Status string 62 | CreationTime time.Time 63 | } 64 | 65 | type LogDetail struct { 66 | LogName string 67 | LogPath string 68 | LogSize int32 69 | StartTime string 70 | EndTime string 71 | } 72 | -------------------------------------------------------------------------------- /cen/route_test.go: -------------------------------------------------------------------------------- 1 | package cen 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | var ( 10 | ak = "" 11 | sec = "" 12 | ) 13 | 14 | func TestDescribePublishedRoute(t *testing.T) { 15 | client := NewCENClient(ak, sec, "cn-shanghai") 16 | res, err := client.DescribePublishedRouteEntries( 17 | &DescribePublishedRouteEntriesArgs{ 18 | CenId: "cen-qhu4rn3cknrg5o4qhl", 19 | ChildInstanceType: "VPC", 20 | ChildInstanceRegionId: "cn-shanghai", 21 | ChildInstanceRouteTableId: "vtb-uf699blmsutb4wkbzqcmt", 22 | ChildInstanceId: "vpc-uf6ch2jfder4r0z51vtox", 23 | }, 24 | ) 25 | if err != nil { 26 | t.Errorf("describe: %s", err.Error()) 27 | t.FailNow() 28 | } 29 | fmt.Printf("Result: %+v", res) 30 | b, err := json.MarshalIndent(res, "", " ") 31 | fmt.Printf("%s", b) 32 | } 33 | 34 | func TestPublishedRoute(t *testing.T) { 35 | client := NewCENClient(ak, sec, "cn-shanghai") 36 | err := client.PublishRouteEntries( 37 | &PublishRouteEntriesArgs{ 38 | CenId: "cen-qhu4rn3cknrg5o4qhl", 39 | ChildInstanceType: "VPC", 40 | ChildInstanceRegionId: "cn-shanghai", 41 | ChildInstanceRouteTableId: "vtb-uf6nco4vj87ly556c589f", 42 | ChildInstanceId: "vpc-uf6ch2jfder4r0z51vtox", 43 | DestinationCidrBlock: "192.168.0.0/26", 44 | }, 45 | ) 46 | if err != nil { 47 | t.Errorf("publish: %s", err.Error()) 48 | t.FailNow() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /cms/config_test.go: -------------------------------------------------------------------------------- 1 | package cms 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | var ( 10 | TestAccessKeyId = os.Getenv("AccessKeyId") 11 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 12 | TestSecurityToken = os.Getenv("SecurityToken") 13 | TestRegionID = common.Region(os.Getenv("RegionId")) 14 | ) 15 | 16 | var testClient *CMSClient 17 | 18 | func NewTestClient() *CMSClient { 19 | if testClient == nil { 20 | testClient = NewCMSClient(TestAccessKeyId, TestAccessKeySecret) 21 | } 22 | return testClient 23 | } 24 | 25 | var testDebugClient *CMSClient 26 | 27 | func NewTestClientForDebug() *CMSClient { 28 | if testDebugClient == nil { 29 | testDebugClient = NewCMSClient(TestAccessKeyId, TestAccessKeySecret) 30 | testDebugClient.SetDebug(true) 31 | } 32 | return testDebugClient 33 | } 34 | -------------------------------------------------------------------------------- /cms/util/dateutil.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import "time" 4 | 5 | /** 6 | * 取得当前日期时间字符串,为RFC1123格式 7 | */ 8 | func GetRFCDate() string { 9 | now := time.Now() 10 | utcNow := now.UTC() 11 | 12 | return utcNow.Format("Mon, 02 Jan 2006 15:04:05 GMT") 13 | } 14 | -------------------------------------------------------------------------------- /cms/util/signature.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "crypto/hmac" 5 | "crypto/md5" 6 | "crypto/sha1" 7 | "encoding/base64" 8 | "fmt" 9 | "io" 10 | 11 | "github.com/denverdino/aliyungo/cms/bytesbuffer" 12 | ) 13 | 14 | /** 15 | 对字符串进行md5运算 16 | @param 17 | data: 签名的内容 18 | **/ 19 | func Md5Signature(data string) string { 20 | t := md5.New() 21 | io.WriteString(t, data) 22 | 23 | return fmt.Sprintf("%x", t.Sum(nil)) 24 | } 25 | 26 | /** 27 | ** 对字符串进行md5,并对md5的结果进行base64编码 28 | * @param 29 | * data: 签名的内容 30 | */ 31 | func Md5Base64_32(data string) string { 32 | md5String := Md5Signature(data) 33 | 34 | return base64.StdEncoding.EncodeToString([]byte(md5String)) 35 | } 36 | 37 | /** 38 | * 对字符串进行md5编码,并且每2位转换为字符,然后进行base64 39 | * @param 40 | * data:要编码的串 41 | **/ 42 | func Md5Base64_16(data string) string { 43 | md5String := Md5Signature(data) 44 | md5CharString, _ := bytesbuffer.Hex_to_str(md5String) 45 | 46 | return base64.StdEncoding.EncodeToString([]byte(md5CharString)) 47 | } 48 | 49 | /** 50 | hmac_sha1签名 51 | @param: 52 | secret string:签名的key 53 | message string:签名的内容 54 | **/ 55 | func HmacSha1(secret string, message string) string { 56 | key := []byte(secret) 57 | h := hmac.New(sha1.New, key) 58 | h.Write([]byte(message)) 59 | 60 | return base64.StdEncoding.EncodeToString(h.Sum(nil)) 61 | } 62 | -------------------------------------------------------------------------------- /cms/util/uri.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "net/url" 5 | "strings" 6 | ) 7 | 8 | /** 9 | * url编码特殊过滤,和标准的url编码有小差别 10 | */ 11 | func QueryEscape(str string) string { 12 | encodeString := url.QueryEscape(str) 13 | 14 | encodeString = strings.Replace(encodeString, "+", "%20", -1) 15 | encodeString = strings.Replace(encodeString, "*", "%2A", -1) 16 | 17 | return encodeString 18 | } 19 | 20 | /** 21 | * url解码特殊过滤,和标准的url编码有小差别 22 | */ 23 | func QueryUnEscape(str string) string { 24 | str = strings.Replace(str, "%20", "+", -1) 25 | str = strings.Replace(str, "%2A", "*", -1) 26 | 27 | encodeString, _ := url.QueryUnescape(str) 28 | 29 | return encodeString 30 | } 31 | -------------------------------------------------------------------------------- /common/endpoint_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLoadEndpointFromFile(t *testing.T) { 8 | 9 | } 10 | 11 | func TestClient_DescribeOpenAPIEndpoint(t *testing.T) { 12 | client := NewTestClientForDebug() 13 | services := []string{"ecs", "slb", "rds", "vpc"} 14 | regions := []Region{ 15 | APNorthEast1, 16 | APSouthEast2, 17 | APSouthEast3, 18 | MEEast1, 19 | EUCentral1, 20 | Zhangjiakou, 21 | Huhehaote, 22 | Hangzhou, 23 | Qingdao, 24 | Beijing, 25 | Shanghai, 26 | Shenzhen, 27 | } 28 | 29 | for _, region := range regions { 30 | for _, service := range services { 31 | endpoint := client.DescribeOpenAPIEndpoint(Region(region), service) 32 | t.Logf("Endpoint[%s][%s]=%s", string(region), service, endpoint) 33 | } 34 | } 35 | } 36 | 37 | func TestLocationClient_DescribeEndpoints(t *testing.T) { 38 | client := NewTestClientForDebug() 39 | args := &DescribeEndpointsArgs{ 40 | Id: "cn-zhangjiakou", 41 | ServiceCode: "slb", 42 | Type: "openAPI", 43 | } 44 | response, err := client.DescribeEndpoints(args) 45 | if err != nil { 46 | t.Fatalf("Error %++v", err) 47 | } else { 48 | t.Logf("Result = %++v", response) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /common/logger_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "bytes" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func Test_Client_Logger(t *testing.T) { 10 | client := NewTestClientForDebug() 11 | assert.NotNil(t, client) 12 | args := &DescribeEndpointsArgs{ 13 | Id: Hangzhou, 14 | ServiceCode: "ecs", 15 | Type: "openAPI", 16 | } 17 | // without logger 18 | resp, err := client.DescribeEndpoints(args) 19 | t.Log(resp) 20 | assert.Nil(t, err) 21 | 22 | // with logger 23 | wr := new(bytes.Buffer) 24 | assert.Nil(t, err) 25 | template := `{time} {channel}: {method} {host} {uri} HTTP/{version} {code} {cost} {hostname} {req_headers} {error} {res_body}` 26 | client.SetLogger("", "openapi", wr, template) 27 | resp, err = client.DescribeEndpoints(args) 28 | t.Log(wr.String()) 29 | t.Log(resp) 30 | assert.Nil(t, err) 31 | } 32 | -------------------------------------------------------------------------------- /common/regions.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | // Region represents ECS region 4 | type Region string 5 | 6 | // Constants of region definition 7 | const ( 8 | Hangzhou = Region("cn-hangzhou") 9 | Qingdao = Region("cn-qingdao") 10 | Beijing = Region("cn-beijing") 11 | Hongkong = Region("cn-hongkong") 12 | Shenzhen = Region("cn-shenzhen") 13 | Shanghai = Region("cn-shanghai") 14 | Zhangjiakou = Region("cn-zhangjiakou") 15 | Huhehaote = Region("cn-huhehaote") 16 | 17 | Chengdu = Region("cn-chengdu") 18 | 19 | APSouthEast1 = Region("ap-southeast-1") 20 | APNorthEast1 = Region("ap-northeast-1") 21 | APSouthEast2 = Region("ap-southeast-2") 22 | APSouthEast3 = Region("ap-southeast-3") 23 | APSouthEast5 = Region("ap-southeast-5") 24 | 25 | APSouth1 = Region("ap-south-1") 26 | 27 | USWest1 = Region("us-west-1") 28 | USEast1 = Region("us-east-1") 29 | 30 | MEEast1 = Region("me-east-1") 31 | 32 | EUCentral1 = Region("eu-central-1") 33 | EUWest1 = Region("eu-west-1") 34 | 35 | ShenZhenFinance = Region("cn-shenzhen-finance-1") 36 | ShanghaiFinance = Region("cn-shanghai-finance-1") 37 | HangZhouFinance = Region("cn-hangzhou-finance-1") 38 | 39 | CNNorth2Gov1 = Region("cn-north-2-gov-1") 40 | RUSWest1 = Region("rus-west-1") 41 | ) 42 | 43 | var ValidRegions = []Region{ 44 | Hangzhou, Qingdao, Beijing, Shenzhen, Hongkong, Shanghai, Zhangjiakou, Huhehaote, 45 | USWest1, USEast1, 46 | APNorthEast1, APSouthEast1, APSouthEast2, APSouthEast3, APSouthEast5, 47 | APSouth1, 48 | MEEast1, 49 | EUCentral1, EUWest1, 50 | ShenZhenFinance, ShanghaiFinance, HangZhouFinance, CNNorth2Gov1, 51 | } 52 | 53 | // IsValidRegion checks if r is an Ali supported region. 54 | func IsValidRegion(r string) bool { 55 | for _, v := range ValidRegions { 56 | if r == string(v) { 57 | return true 58 | } 59 | } 60 | return false 61 | } 62 | -------------------------------------------------------------------------------- /common/regions_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "testing" 4 | 5 | func TestIsValidRegion(t *testing.T) { 6 | var tests = []struct { 7 | region string 8 | 9 | exp bool 10 | }{ 11 | {"", false}, 12 | 13 | {"cn-hangzhou", true}, 14 | {"us-east-1", true}, 15 | 16 | {"hangzhou", false}, 17 | {"not-unknown", false}, 18 | } 19 | for _, v := range tests { 20 | got := IsValidRegion(v.region) 21 | if got != v.exp { 22 | t.Fail() 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "time" 4 | 5 | func GetTimeInFormatISO8601() (timeStr string) { 6 | gmt := time.FixedZone("GMT", 0) 7 | 8 | return time.Now().In(gmt).Format("2006-01-02T15:04:05Z") 9 | } 10 | -------------------------------------------------------------------------------- /common/version.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | const Version = "0.1" 4 | -------------------------------------------------------------------------------- /cs/config_test.go: -------------------------------------------------------------------------------- 1 | package cs 2 | 3 | import ( 4 | "os" 5 | "strconv" 6 | 7 | "github.com/denverdino/aliyungo/common" 8 | ) 9 | 10 | //Modify with your Access Key Id and Access Key Secret 11 | 12 | var ( 13 | TestAccessKeyId = os.Getenv("AccessKeyId") 14 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 15 | TestSecurityToken = os.Getenv("SecurityToken") 16 | TestRegionID = common.Region(os.Getenv("RegionId")) 17 | TestVpcId = os.Getenv("VpcId") 18 | TestVSwitchId = os.Getenv("VSwitchId") 19 | TestServiceCIDR = os.Getenv("ServiceCIDR") 20 | TestClusterId = os.Getenv("ClusterId") 21 | TestPrivateIpAddress, _ = strconv.ParseBool(os.Getenv("PrivateIpAddress")) 22 | TestToken = os.Getenv("Token") 23 | TestLoggingType = os.Getenv("LoggingType") 24 | ) 25 | 26 | var testClient *Client 27 | 28 | func NewTestClient() *Client { 29 | if testClient == nil { 30 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 31 | } 32 | return testClient 33 | } 34 | 35 | var testDebugClient *Client 36 | 37 | func NewTestClientForDebug() *Client { 38 | if testDebugClient == nil { 39 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 40 | testDebugClient.SetDebug(true) 41 | } 42 | return testDebugClient 43 | } 44 | 45 | var testDebugAussumeRoleClient *Client 46 | 47 | func NewTestDebugAussumeRoleClient() *Client { 48 | if testDebugAussumeRoleClient == nil { 49 | testDebugAussumeRoleClient = NewClientForAussumeRole(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken) 50 | testDebugAussumeRoleClient.SetDebug(true) 51 | } 52 | return testDebugAussumeRoleClient 53 | } 54 | -------------------------------------------------------------------------------- /cs/registry.go: -------------------------------------------------------------------------------- 1 | package cs 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | const ( 8 | CRDefaultEndpoint = "https://cr.cn-hangzhou.aliyuncs.com" 9 | CRAPIVersion = "2016-06-07" 10 | ) 11 | 12 | func NewCRClientWithSecurityToken(region, accessKeyId, accessKeySecret, securityToken string) *Client { 13 | return &Client{ 14 | AccessKeyId: accessKeyId, 15 | AccessKeySecret: accessKeySecret, 16 | SecurityToken: securityToken, 17 | endpoint: "https://cr." + region + ".aliyuncs.com", 18 | Version: CRAPIVersion, 19 | httpClient: &http.Client{}, 20 | } 21 | } 22 | 23 | type CRAuthorizationToken struct { 24 | Data struct { 25 | AuthorizationToken string `json:"authorizationToken"` 26 | TempUserName string `json:"tempUserName"` 27 | ExpireDate int64 `json:"expireDate"` 28 | } `json:"data"` 29 | RequestId string `json:"requestId"` 30 | } 31 | 32 | func (client *Client) GetCRAuthorizationToken() (crtoken CRAuthorizationToken, err error) { 33 | err = client.Invoke("", http.MethodGet, "/tokens", nil, nil, &crtoken) 34 | return 35 | } 36 | 37 | func (client *Client) GetCRRepoInfo(repoNamespace, repoName string) (str string, err error) { 38 | err = client.Invoke("", http.MethodGet, "/repos/"+repoNamespace+"/"+repoName, nil, nil, &str) 39 | return 40 | } 41 | -------------------------------------------------------------------------------- /cs/signature.go: -------------------------------------------------------------------------------- 1 | package cs 2 | 3 | import ( 4 | "net/http" 5 | "sort" 6 | "strings" 7 | 8 | "log" 9 | 10 | "github.com/denverdino/aliyungo/util" 11 | ) 12 | 13 | func (client *Client) signRequest(request *http.Request) { 14 | 15 | headers := request.Header 16 | contentMd5 := headers.Get("Content-Md5") 17 | contentType := headers.Get("Content-Type") 18 | accept := headers.Get("Accept") 19 | date := headers.Get("Date") 20 | 21 | canonicalizedResource := request.URL.RequestURI() 22 | 23 | _, canonicalizedHeader := canonicalizeHeader(headers) 24 | 25 | stringToSign := request.Method + "\n" + accept + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedHeader + canonicalizedResource 26 | 27 | if client.debug { 28 | log.Printf("stringToSign = %s: ", stringToSign) 29 | } 30 | 31 | signature := util.CreateSignature(stringToSign, client.AccessKeySecret) 32 | headers.Set("Authorization", "acs "+client.AccessKeyId+":"+signature) 33 | } 34 | 35 | const headerOSSPrefix = "x-acs-" 36 | 37 | //Have to break the abstraction to append keys with lower case. 38 | func canonicalizeHeader(headers http.Header) (newHeaders http.Header, result string) { 39 | var canonicalizedHeaders []string 40 | newHeaders = http.Header{} 41 | 42 | for k, v := range headers { 43 | if lower := strings.ToLower(k); strings.HasPrefix(lower, headerOSSPrefix) { 44 | newHeaders[lower] = v 45 | canonicalizedHeaders = append(canonicalizedHeaders, lower) 46 | } else { 47 | newHeaders[k] = v 48 | } 49 | } 50 | 51 | sort.Strings(canonicalizedHeaders) 52 | 53 | var canonicalizedHeader string 54 | 55 | for _, k := range canonicalizedHeaders { 56 | v := "" 57 | if len(headers[k]) > 0 { 58 | v = headers[k][0] 59 | } 60 | canonicalizedHeader += k + ":" + v + "\n" 61 | } 62 | 63 | return newHeaders, canonicalizedHeader 64 | } 65 | -------------------------------------------------------------------------------- /cs/token.go: -------------------------------------------------------------------------------- 1 | package cs 2 | 3 | import ( 4 | "fmt" 5 | "github.com/denverdino/aliyungo/common" 6 | "net/http" 7 | ) 8 | 9 | type ClusterTokenReqeust struct { 10 | //token 过期时间,如果不填写,则默认24小时过期 11 | Expired int64 `json:"expired"` 12 | IsPermanently bool `json:"is_permanently"` 13 | } 14 | 15 | type ClusterTokenResponse struct { 16 | Created int64 ` json:"created"` 17 | Updated int64 `json:"updated"` 18 | Expired int64 ` json:"expired"` 19 | 20 | ClusterID string ` json:"cluster_id"` 21 | 22 | Token string ` json:"token"` 23 | IsActive int ` json:"is_active"` 24 | } 25 | 26 | func (client *Client) CreateClusterToken(clusterId string, request *ClusterTokenReqeust) (*ClusterTokenResponse, error) { 27 | response := &ClusterTokenResponse{} 28 | err := client.Invoke("", http.MethodPost, "/clusters/"+clusterId+"/token", nil, request, response) 29 | return response, err 30 | } 31 | 32 | func (client *Client) RevokeToken(token string) error { 33 | return client.Invoke("", http.MethodDelete, "/token/"+token+"/revoke", nil, nil, nil) 34 | } 35 | 36 | func (client *Client) DescribeClusterTokens(clusterId string) ([]*ClusterTokenResponse, error) { 37 | response := make([]*ClusterTokenResponse, 0) 38 | err := client.Invoke("", http.MethodGet, "/clusters/"+clusterId+"/tokens", nil, nil, &response) 39 | return response, err 40 | } 41 | 42 | func (client *Client) DescribeClusterToken(clusterId, token string) (*ClusterTokenResponse, error) { 43 | if clusterId == "" || token == "" { 44 | return nil, common.GetCustomError("InvalidParamter", "The clusterId or token is empty") 45 | } 46 | tokenInfo := &ClusterTokenResponse{} 47 | err := client.Invoke("", http.MethodGet, fmt.Sprintf("/clusters/%s/tokens/%s", clusterId, token), nil, nil, tokenInfo) 48 | return tokenInfo, err 49 | } 50 | -------------------------------------------------------------------------------- /cs/token_test.go: -------------------------------------------------------------------------------- 1 | package cs 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func Test_CreateClusterToken(t *testing.T) { 9 | client := NewTestClientForDebug() 10 | 11 | req := &ClusterTokenReqeust{ 12 | Expired: time.Now().Unix() + 86400, 13 | IsPermanently: false, 14 | } 15 | 16 | token, err := client.CreateClusterToken(TestClusterId, req) 17 | if err != nil { 18 | t.Fatalf("Error %++v", err) 19 | } else { 20 | t.Logf("Token = %++v", token) 21 | } 22 | } 23 | 24 | func Test_RevokeClusterToken(t *testing.T) { 25 | client := NewTestClientForDebug() 26 | req := &ClusterTokenReqeust{ 27 | Expired: time.Now().Unix() + 86400, 28 | IsPermanently: false, 29 | } 30 | 31 | token, err := client.CreateClusterToken(TestClusterId, req) 32 | if err != nil { 33 | t.Fatalf("Error = %++v", err) 34 | } else { 35 | err = client.RevokeToken(token.Token) 36 | if err != nil { 37 | t.Fatalf("Error = %++v", err) 38 | } else { 39 | tokens, err := client.DescribeClusterTokens(TestClusterId) 40 | if err != nil { 41 | t.Fatalf("Error %++v", err) 42 | } else { 43 | for _, token := range tokens { 44 | t.Logf("Token = %++v", token) 45 | } 46 | } 47 | } 48 | } 49 | } 50 | 51 | func Test_DescribeClusterTokens(t *testing.T) { 52 | client := NewTestClientForDebug() 53 | 54 | tokens, err := client.DescribeClusterTokens(TestClusterId) 55 | if err != nil { 56 | t.Fatalf("Error %++v", err) 57 | } else { 58 | for _, token := range tokens { 59 | t.Logf("Token = %++v", token) 60 | } 61 | } 62 | } 63 | 64 | func Test_DescribeClusterToken(t *testing.T) { 65 | client := NewTestClientForDebug() 66 | 67 | token, err := client.DescribeClusterToken(TestClusterId, TestToken) 68 | if err != nil { 69 | t.Fatalf("Error %++v", err) 70 | } else { 71 | t.Logf("Token = %++v", token) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /dm/README.md: -------------------------------------------------------------------------------- 1 | # aliyun direct mail 2 | 3 | 这个服务支持通过阿里云发送短信以及邮件。 4 | 使用接口前需要在控制台设置相关的模版和签名,具体参考DM服务的说明文档: 5 | 6 | [Direct Mail](https://help.aliyun.com/document_detail/29414.html) 7 | 8 | 调用方法如测试文件中的一样 9 | 10 | ```go 11 | func TestSms(t *testing.T) { 12 | ID := os.Getenv("ALI_DM_ACCESS_KEY_ID") 13 | SECRET := os.Getenv("ALI_DM_ACCESS_KEY_SECRET") 14 | SIGNAME := os.Getenv("ALI_DM_SMS_SIGN_NAME") 15 | TEMPCODE := os.Getenv("ALI_DM_SMS_TEMPLATE_CODE") 16 | NUM := os.Getenv("ALI_DM_SMS_TEST_PHONE") 17 | client := NewClient(ID, SECRET) 18 | client.SendSms(SIGNAME, TEMPCODE, NUM, map[string]string{ 19 | "number": "123456", 20 | }) 21 | } 22 | ``` 23 | 24 | 测试这个包,需要设置下面用到的环境变量 25 | ```go 26 | ID := os.Getenv("ALI_DM_ACCESS_KEY_ID") 27 | SECRET := os.Getenv("ALI_DM_ACCESS_KEY_SECRET") 28 | SIGNAME := os.Getenv("ALI_DM_SMS_SIGN_NAME") 29 | TEMPCODE := os.Getenv("ALI_DM_SMS_TEMPLATE_CODE") 30 | NUM := os.Getenv("ALI_DM_SMS_TEST_PHONE") 31 | accountName := os.Getenv("ALI_DM_ACCOUNT_NAME") 32 | templateName := os.Getenv("ALI_DM_TEMPLATE_NAME") 33 | receiverName := os.Getenv("ALI_DM_RECEIVER_NAME") 34 | accountName := os.Getenv("ALI_DM_ACCOUNT_NAME") 35 | replyToAddress := os.Getenv("ALI_DM_REPLY_TO_ADDRESS") 36 | toAddress := os.Getenv("ALI_DM_TO_ADDRESS") 37 | ``` 38 | 39 | maintainer: johnzeng 40 | 41 | #2016.12.20 42 | 将短信API从邮件中分离了出来,并且让DM服务使用Common Client,采用struct形式的参数,与其他服务统一。具体使用方法参见mail_test。 43 | yarous224 -------------------------------------------------------------------------------- /dm/client.go: -------------------------------------------------------------------------------- 1 | package dm 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | ) 6 | 7 | const ( 8 | EmailEndPoint = "https://dm.aliyuncs.com/" 9 | SingleSendMail = "SingleSendMail" 10 | BatchSendMail = "BatchSendMail" 11 | EmailAPIVersion = "2015-11-23" 12 | ) 13 | 14 | type Client struct { 15 | common.Client 16 | } 17 | 18 | func NewClient(accessKeyId, accessKeySecret string) *Client { 19 | client := new(Client) 20 | client.Init(EmailEndPoint, EmailAPIVersion, accessKeyId, accessKeySecret) 21 | return client 22 | } 23 | -------------------------------------------------------------------------------- /dm/mail.go: -------------------------------------------------------------------------------- 1 | package dm 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type SendEmailArgs struct { 10 | AccountName string 11 | AddressType string 12 | } 13 | 14 | type SendBatchMailArgs struct { 15 | SendEmailArgs 16 | TemplateName string 17 | ReceiverName string 18 | TagName string 19 | } 20 | 21 | //remember to setup the accountName in your aliyun console 22 | //addressType should be "1" or "0", 23 | //0:random address, it's recommanded 24 | //1:sender's address 25 | //tagName is optional, you can use "" if you don't wanna use it 26 | //please set the receiverName and template in the console of Aliyun before you call this API,if you use tagName, you should set it as well 27 | 28 | func (this *Client) SendBatchMail(args *SendBatchMailArgs) error { 29 | return this.InvokeByAnyMethod(http.MethodPost, BatchSendMail, "", args, &common.Response{}) 30 | } 31 | 32 | type SendSingleMailArgs struct { 33 | SendEmailArgs 34 | ReplyToAddress bool 35 | ToAddress string 36 | FromAlias string 37 | Subject string 38 | HtmlBody string 39 | TextBody string 40 | } 41 | 42 | //remember to setup the accountName in your aliyun console 43 | //addressType should be "1" or "0", 44 | //0:random address, it's recommanded 45 | //1:sender's address 46 | //please set the receiverName and template in the console of Aliyun before you call this API,if you use tagName, you should set it as well 47 | 48 | //fromAlias, subject, htmlBody, textBody are optional 49 | 50 | func (this *Client) SendSingleMail(args *SendSingleMailArgs) error { 51 | return this.InvokeByAnyMethod(http.MethodPost, SingleSendMail, "", args, &common.Response{}) 52 | } 53 | -------------------------------------------------------------------------------- /dm/mail_test.go: -------------------------------------------------------------------------------- 1 | package dm 2 | 3 | import ( 4 | "os" 5 | "strconv" 6 | "testing" 7 | ) 8 | 9 | func TestBatchMail(t *testing.T) { 10 | ID := os.Getenv("ALI_DM_ACCESS_KEY_ID") 11 | SECRET := os.Getenv("ALI_DM_ACCESS_KEY_SECRET") 12 | accountName := os.Getenv("ALI_DM_ACCOUNT_NAME") 13 | templateName := os.Getenv("ALI_DM_TEMPLATE_NAME") 14 | receiverName := os.Getenv("ALI_DM_RECEIVER_NAME") 15 | client := NewClient(ID, SECRET) 16 | err := client.SendBatchMail(&SendBatchMailArgs{SendEmailArgs: SendEmailArgs{AccountName: accountName, 17 | AddressType: "0"}, 18 | TemplateName: templateName, 19 | ReceiverName: receiverName}) 20 | if nil != err { 21 | t.Error(err.Error()) 22 | } 23 | } 24 | 25 | func TestSingleMail(t *testing.T) { 26 | ID := os.Getenv("ALI_DM_ACCESS_KEY_ID") 27 | SECRET := os.Getenv("ALI_DM_ACCESS_KEY_SECRET") 28 | accountName := os.Getenv("ALI_DM_ACCOUNT_NAME") 29 | replyToAddress, _ := strconv.ParseBool(os.Getenv("ALI_DM_REPLY_TO_ADDRESS")) 30 | toAddress := os.Getenv("ALI_DM_TO_ADDRESS") 31 | client := NewClient(ID, SECRET) 32 | err := client.SendSingleMail(&SendSingleMailArgs{ 33 | SendEmailArgs: SendEmailArgs{ 34 | AccountName: accountName, 35 | AddressType: "0", 36 | }, 37 | ReplyToAddress: replyToAddress, 38 | ToAddress: toAddress}) 39 | if nil != err { 40 | t.Error(err.Error()) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dns/AddDomain.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type AddDomainArgs struct { 10 | DomainName string 11 | 12 | //optional 13 | GroupId string 14 | } 15 | 16 | type AddDomainResponse struct { 17 | common.Response 18 | DomainId string 19 | DomainName string 20 | GroupId string 21 | GroupName string 22 | PunyCode string 23 | DnsServers struct { 24 | DnsServer []string 25 | } 26 | } 27 | 28 | // AddDomain 29 | // 30 | // You can read doc at https://help.aliyun.com/document_detail/29749.html?spm=5176.doc29805.6.592.6LMqlG 31 | func (client *Client) AddDomain(args *AddDomainArgs) (response *AddDomainResponse, err error) { 32 | action := "AddDomain" 33 | response = &AddDomainResponse{} 34 | err = client.Invoke(action, args, response) 35 | if err == nil { 36 | return response, nil 37 | } else { 38 | log.Printf("%s error, %v", action, err) 39 | return response, err 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dns/AddDomainGroup.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type AddDomainGroupArgs struct { 10 | GroupName string 11 | } 12 | 13 | type AddDomainGroupResponse struct { 14 | common.Response 15 | GroupId string 16 | GroupName string 17 | } 18 | 19 | // AddDomainGroup 20 | // 21 | // You can read doc at https://help.aliyun.com/document_detail/29762.html?spm=5176.doc29749.6.604.PJtwG1 22 | func (client *Client) AddDomainGroup(args *AddDomainGroupArgs) (response *AddDomainGroupResponse, err error) { 23 | action := "AddDomainGroup" 24 | response = &AddDomainGroupResponse{} 25 | err = client.Invoke(action, args, response) 26 | if err == nil { 27 | return response, nil 28 | } else { 29 | log.Printf("%s error, %v", action, err) 30 | return response, err 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dns/AddDomainGroup_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAddDomainGroup(t *testing.T) { 8 | client := NewTestClientNew() 9 | args := AddDomainGroupArgs{ 10 | GroupName: TestDomainGroupName, 11 | } 12 | 13 | response, err := client.AddDomainGroup(&args) 14 | if err == nil { 15 | t.Logf("AddDomainGroup %s success, %v", TestDomainGroupName, response) 16 | 17 | deleteDomainGroupArgs := DeleteDomainGroupArgs{ 18 | GroupId: response.GroupId, 19 | } 20 | client.DeleteDomainGroup(&deleteDomainGroupArgs) 21 | 22 | } else { 23 | t.Errorf("Failed to AddDomainGroup, %v", err) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /dns/AddDomainRecord.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type AddDomainRecordArgs struct { 10 | DomainName string 11 | RR string 12 | Type string 13 | Value string 14 | 15 | //optional 16 | TTL int32 17 | Priority int32 18 | Line string 19 | } 20 | 21 | type AddDomainRecordResponse struct { 22 | common.Response 23 | InstanceId string 24 | RecordId string 25 | } 26 | 27 | // AddDomainRecord 28 | // 29 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&AddDomainRecord 30 | func (client *Client) AddDomainRecord(args *AddDomainRecordArgs) (response *AddDomainRecordResponse, err error) { 31 | action := "AddDomainRecord" 32 | response = &AddDomainRecordResponse{} 33 | err = client.Invoke(action, args, response) 34 | if err == nil { 35 | return response, nil 36 | } else { 37 | log.Printf("%s error, %v", action, err) 38 | return response, err 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dns/AddDomainRecord_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAddDomainRecord(t *testing.T) { 8 | client := NewTestClient() 9 | addDomainRecordArgs := AddDomainRecordArgs{ 10 | DomainName: TestDomainName, 11 | RR: "testaddrecord", 12 | Type: ARecord, 13 | Value: "8.8.8.8", 14 | } 15 | response, err := client.AddDomainRecord(&addDomainRecordArgs) 16 | if err == nil { 17 | t.Logf("AddDomainRecord: testaddr for domain: %s Success, %v", 18 | TestDomainName, response) 19 | 20 | deleteDomainRecordArgs := DeleteDomainRecordArgs{ 21 | RecordId: response.RecordId, 22 | } 23 | client.DeleteDomainRecord(&deleteDomainRecordArgs) 24 | } else { 25 | t.Errorf("Failed to AddDomainRecord: testaddr for domain: %s", TestDomainName) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dns/AddDomain_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestAddDomain(t *testing.T) { 8 | client := NewTestClientNew() 9 | args := AddDomainArgs{ 10 | DomainName: TestDomainName, 11 | } 12 | 13 | if res, err := client.AddDomain(&args); err == nil { 14 | t.Logf("AddDomain %s success, %v", TestDomainName, res) 15 | 16 | deleteDomainArgs := DeleteDomainArgs{ 17 | DomainName: TestDomainName, 18 | } 19 | client.DeleteDomain(&deleteDomainArgs) 20 | 21 | } else { 22 | t.Errorf("Failed to AddDomain, %v", err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dns/ChangeDomainGroup.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type ChangeDomainGroupArgs struct { 10 | DomainName string 11 | GroupId string 12 | } 13 | 14 | type ChangeDomainGroupResponse struct { 15 | common.Response 16 | GroupId string 17 | GroupName string 18 | } 19 | 20 | // ChangeDomainGroup 21 | // 22 | // You can read doc at https://help.aliyun.com/document_detail/29765.html?spm=5176.doc29764.6.607.WUJQgE 23 | func (client *Client) ChangeDomainGroup(args *ChangeDomainGroupArgs) (response *ChangeDomainGroupResponse, err error) { 24 | action := "ChangeDomainGroup" 25 | response = &ChangeDomainGroupResponse{} 26 | err = client.Invoke(action, args, response) 27 | if err == nil { 28 | return response, nil 29 | } else { 30 | log.Printf("%s error, %v", action, err) 31 | return response, err 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dns/ChangeDomainGroup_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "testing" 4 | 5 | func TestChangeDomainGroup(t *testing.T) { 6 | client := NewTestClientNew() 7 | 8 | // create origin group 9 | addGroupArgs := AddDomainGroupArgs{ 10 | GroupName: TestDomainGroupName, 11 | } 12 | addGroupRes, _ := client.AddDomainGroup(&addGroupArgs) 13 | 14 | // add domain to origin group 15 | addDomainArgs := AddDomainArgs{ 16 | DomainName: TestDomainName, 17 | GroupId: addGroupRes.GroupId, 18 | } 19 | addDomainRes, _ := client.AddDomain(&addDomainArgs) 20 | 21 | // create new group 22 | addGroupArgs.GroupName = TestChanegGroupName 23 | addGroupRes, _ = client.AddDomainGroup(&addGroupArgs) 24 | 25 | // change to new group 26 | changeArgs := ChangeDomainGroupArgs{ 27 | DomainName: addDomainRes.DomainName, 28 | GroupId: addGroupRes.GroupId, 29 | } 30 | _, err := client.ChangeDomainGroup(&changeArgs) 31 | if err == nil { 32 | t.Logf("ChangeDomainGroup success") 33 | } else { 34 | t.Errorf("Failed to ChangeDomainGroup, %v", err) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dns/DeleteDomain.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type DeleteDomainArgs struct { 10 | DomainName string 11 | } 12 | 13 | type DeleteDomainResponse struct { 14 | common.Response 15 | DomainName string 16 | } 17 | 18 | // DeleteDomain 19 | // 20 | // You can read doc at https://help.aliyun.com/document_detail/29750.html?spm=5176.doc29766.6.593.eELaZ7 21 | func (client *Client) DeleteDomain(args *DeleteDomainArgs) (response *DeleteDomainResponse, err error) { 22 | action := "DeleteDomain" 23 | response = &DeleteDomainResponse{} 24 | err = client.Invoke(action, args, response) 25 | if err == nil { 26 | return response, nil 27 | } else { 28 | log.Printf("%s error, %v", action, err) 29 | return response, err 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dns/DeleteDomainGroup.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type DeleteDomainGroupArgs struct { 10 | GroupId string 11 | } 12 | 13 | type DeleteDomainGroupResponse struct { 14 | common.Response 15 | GroupName string 16 | } 17 | 18 | // DeleteDomainGroup 19 | // 20 | // You can read doc at https://help.aliyun.com/document_detail/29764.html?spm=5176.doc29763.6.606.Vm3FyC 21 | func (client *Client) DeleteDomainGroup(args *DeleteDomainGroupArgs) (response *DeleteDomainGroupResponse, err error) { 22 | action := "DeleteDomainGroup" 23 | response = &DeleteDomainGroupResponse{} 24 | err = client.Invoke(action, args, response) 25 | if err == nil { 26 | return response, nil 27 | } else { 28 | log.Printf("%s error, %v", action, err) 29 | return response, err 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dns/DeleteDomainGroup_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDeleteDomainGroup(t *testing.T) { 8 | client := NewTestClientNew() 9 | args := AddDomainGroupArgs{ 10 | GroupName: TestDomainGroupName, 11 | } 12 | res, _ := client.AddDomainGroup(&args) 13 | 14 | deleteDomainGroupArgs := DeleteDomainGroupArgs{ 15 | GroupId: res.GroupId, 16 | } 17 | response, err := client.DeleteDomainGroup(&deleteDomainGroupArgs) 18 | if err == nil { 19 | t.Logf("DeleteDomainGroup %s success, %v", TestDomainGroupName, response) 20 | } else { 21 | t.Errorf("Failed to DeleteDomainGroup, %v", err) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dns/DeleteDomainRecord.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DeleteDomainRecordArgs struct { 6 | RecordId string 7 | } 8 | 9 | type DeleteDomainRecordResponse struct { 10 | common.Response 11 | InstanceId string 12 | RecordId string 13 | } 14 | 15 | // DeleteDomainRecord 16 | // 17 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DeleteDomainRecord 18 | func (client *Client) DeleteDomainRecord(args *DeleteDomainRecordArgs) (response *DeleteDomainRecordResponse, err error) { 19 | action := "DeleteDomainRecord" 20 | response = &DeleteDomainRecordResponse{} 21 | err = client.Invoke(action, args, response) 22 | if err == nil { 23 | return response, nil 24 | } else { 25 | return nil, err 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dns/DeleteDomainRecord_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDeleteDomainRecord(t *testing.T) { 8 | //prepare 9 | client := NewTestClient() 10 | addDomainRecordArgs := AddDomainRecordArgs{ 11 | DomainName: TestDomainName, 12 | RR: "testdeleterecordid", 13 | Type: ARecord, 14 | Value: "8.8.8.8", 15 | } 16 | 17 | addResponse, err := client.AddDomainRecord(&addDomainRecordArgs) 18 | 19 | //test delete record 20 | deleteDomainRecordArgs := DeleteDomainRecordArgs{ 21 | RecordId: addResponse.RecordId, 22 | } 23 | deleteResponse, err := client.DeleteDomainRecord(&deleteDomainRecordArgs) 24 | if err == nil { 25 | t.Logf("DeleteDomainRecord: %v", deleteResponse) 26 | } else { 27 | t.Errorf("Failed to DeleteDomainRecord: %s", deleteDomainRecordArgs.RecordId) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dns/DeleteDomain_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDeleteDomain(t *testing.T) { 8 | client := NewTestClientNew() 9 | args := AddDomainArgs{ 10 | DomainName: TestDomainName, 11 | } 12 | client.AddDomain(&args) 13 | 14 | deleteDomainArgs := DeleteDomainArgs{ 15 | DomainName: TestDomainName, 16 | } 17 | response, err := client.DeleteDomain(&deleteDomainArgs) 18 | if err == nil { 19 | t.Logf("DeleteDomain %s success, %v", TestDomainName, response) 20 | } else { 21 | t.Errorf("Failed to DeleteDomain, %v", err) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dns/DeleteSubDomainRecords.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DeleteSubDomainRecordsArgs struct { 6 | DomainName string 7 | RR string 8 | 9 | //optional 10 | Type string 11 | } 12 | 13 | type DeleteSubDomainRecordsResponse struct { 14 | common.Response 15 | InstanceId string 16 | RR string 17 | // TotalCount int32 18 | } 19 | 20 | // DeleteSubDomainRecords 21 | // 22 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DeleteSubDomainRecords 23 | func (client *Client) DeleteSubDomainRecords(args *DeleteSubDomainRecordsArgs) (response *DeleteSubDomainRecordsResponse, err error) { 24 | action := "DeleteSubDomainRecords" 25 | response = &DeleteSubDomainRecordsResponse{} 26 | err = client.Invoke(action, args, response) 27 | if err == nil { 28 | return response, nil 29 | } else { 30 | return nil, err 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dns/DeleteSubDomainRecords_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDeleteSubDomainRecords(t *testing.T) { 8 | //prepare 9 | client := NewTestClient() 10 | addDomainRecordArgs := AddDomainRecordArgs{ 11 | DomainName: TestDomainName, 12 | RR: "testdeletesubdomainrecords", 13 | Type: ARecord, 14 | Value: "8.8.8.8", 15 | } 16 | 17 | client.AddDomainRecord(&addDomainRecordArgs) 18 | 19 | //test delete subdomain 20 | deleteDomainRecordArgs := DeleteSubDomainRecordsArgs{ 21 | DomainName: TestDomainName, 22 | RR: "testdeletesubdomainrecords", 23 | } 24 | deleteResponse, err := client.DeleteSubDomainRecords(&deleteDomainRecordArgs) 25 | if err == nil { 26 | t.Logf("DeleteDomainRecord: %v", deleteResponse) 27 | } else { 28 | t.Errorf("Failed to DeleteSubDomainRecords: %s", deleteDomainRecordArgs.RR) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dns/DescribeDomainGroups.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type DomainGroupType struct { 10 | GroupId string 11 | GroupName string 12 | } 13 | 14 | type DescribeDomainGroupsArgs struct { 15 | //optional 16 | common.Pagination 17 | KeyWord string 18 | } 19 | 20 | type DescribeDomainGroupsResponse struct { 21 | response common.Response 22 | common.PaginationResult 23 | DomainGroups struct { 24 | DomainGroup []DomainGroupType 25 | } 26 | } 27 | 28 | // DescribeDomainGroups 29 | // 30 | // You can read doc at https://help.aliyun.com/document_detail/29766.html?spm=5176.doc29765.6.608.qcQr2R 31 | func (client *Client) DescribeDomainGroups(args *DescribeDomainGroupsArgs) (groups []DomainGroupType, err error) { 32 | action := "DescribeDomainGroups" 33 | response := &DescribeDomainGroupsResponse{} 34 | err = client.Invoke(action, args, response) 35 | 36 | if err != nil { 37 | log.Printf("%s error, %v", action, err) 38 | return nil, err 39 | } 40 | 41 | return response.DomainGroups.DomainGroup, nil 42 | } 43 | -------------------------------------------------------------------------------- /dns/DescribeDomainGroups_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "testing" 4 | 5 | func TestDescribeDomainGroups(t *testing.T) { 6 | client := NewTestClientNew() 7 | describeArgs := DescribeDomainGroupsArgs{} 8 | 9 | _, err := client.DescribeDomainGroups(&describeArgs) 10 | if err == nil { 11 | t.Logf("DescribeDomainGroups success") 12 | } else { 13 | t.Errorf("Failed to DescribeDomainGroups: %v", err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dns/DescribeDomainInfo.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type DomainType struct { 10 | DomainId string 11 | DomainName string 12 | AliDomain bool 13 | GroupId string 14 | GroupName string 15 | InstanceId string 16 | VersionCode string 17 | PunyCode string 18 | DnsServers struct { 19 | DnsServer []string 20 | } 21 | } 22 | 23 | type DescribeDomainInfoArgs struct { 24 | DomainName string 25 | } 26 | 27 | type DescribeDomainInfoResponse struct { 28 | response common.Response 29 | DomainType 30 | } 31 | 32 | // DescribeDomainInfo 33 | // 34 | // You can read doc at https://help.aliyun.com/document_detail/29752.html?spm=5176.doc29751.6.595.VJM3Gy 35 | func (client *Client) DescribeDomainInfo(args *DescribeDomainInfoArgs) (domain DomainType, err error) { 36 | action := "DescribeDomainInfo" 37 | response := &DescribeDomainInfoResponse{} 38 | err = client.Invoke(action, args, response) 39 | 40 | if err != nil { 41 | log.Printf("%s error, %v", action, err) 42 | return DomainType{}, err 43 | } 44 | 45 | return response.DomainType, nil 46 | } 47 | -------------------------------------------------------------------------------- /dns/DescribeDomainInfo_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "testing" 4 | 5 | func TestDescribeDomainInfo(t *testing.T) { 6 | client := NewTestClientNew() 7 | describeArgs := DescribeDomainInfoArgs{ 8 | DomainName: TestDomainName, 9 | } 10 | 11 | _, err := client.DescribeDomainInfo(&describeArgs) 12 | if err == nil { 13 | t.Logf("DescribeDomainInfo success") 14 | } else { 15 | t.Errorf("Failed to DescribeDomainInfo: %v", err) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dns/DescribeDomainRecordInfo.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeDomainRecordInfoArgs struct { 6 | RecordId string 7 | } 8 | 9 | type DescribeDomainRecordInfoResponse struct { 10 | common.Response 11 | RecordType 12 | } 13 | 14 | // DescribeDomainRecordInfo 15 | // 16 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeDomainRecordInfo 17 | func (client *Client) DescribeDomainRecordInfo(args *DescribeDomainRecordInfoArgs) (response *DescribeDomainRecordInfoResponse, err error) { 18 | action := "DescribeDomainRecordInfo" 19 | response = &DescribeDomainRecordInfoResponse{} 20 | err = client.Invoke(action, args, response) 21 | if err == nil { 22 | return response, nil 23 | } else { 24 | return nil, err 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dns/DescribeDomainRecordInfoNew.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | // endpoint change to 'http://alidns.aliyuncs.com' then record ttl and priority change to string 6 | type RecordTypeNew struct { 7 | DomainName string 8 | RecordId string 9 | RR string 10 | Type string 11 | Value string 12 | TTL float64 13 | Priority int32 14 | Line string 15 | Status string 16 | Locked bool 17 | } 18 | 19 | type DescribeDomainRecordInfoNewArgs struct { 20 | RecordId string 21 | } 22 | 23 | type DescribeDomainRecordInfoNewResponse struct { 24 | common.Response 25 | RecordTypeNew 26 | } 27 | 28 | // DescribeDomainRecordInformation 29 | // 30 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeDomainRecordInfo 31 | func (client *Client) DescribeDomainRecordInfoNew(args *DescribeDomainRecordInfoNewArgs) (response *DescribeDomainRecordInfoNewResponse, err error) { 32 | action := "DescribeDomainRecordInfo" 33 | response = &DescribeDomainRecordInfoNewResponse{} 34 | err = client.Invoke(action, args, response) 35 | if err == nil { 36 | return response, nil 37 | } else { 38 | return nil, err 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dns/DescribeDomainRecordInfoNew_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDescribeDomainRecordInfoNew(t *testing.T) { 8 | //prepare 9 | client := NewTestClientNew() 10 | describeArgs := DescribeDomainRecordsNewArgs{ 11 | DomainName: TestDomainName, 12 | } 13 | describeArgs.PageSize = 100 14 | 15 | describeResponse, err := client.DescribeDomainRecordsNew(&describeArgs) 16 | if err == nil { 17 | record := describeResponse.DomainRecords.Record[0] 18 | arg := DescribeDomainRecordInfoNewArgs{ 19 | RecordId: record.RecordId, 20 | } 21 | response, err := client.DescribeDomainRecordInfoNew(&arg) 22 | if err == nil { 23 | t.Logf("DescribeDomainRecordInfo success: %v", response) 24 | } else { 25 | t.Errorf("Failed to DescribeDomainRecordInfo: %s", describeArgs.DomainName) 26 | } 27 | } else { 28 | t.Errorf("Failed to DescribeDomainRecords: %s", describeArgs.DomainName) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dns/DescribeDomainRecordInfo_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDescribeDomainRecordInfo(t *testing.T) { 8 | //prepare 9 | client := NewTestClient() 10 | describeArgs := DescribeDomainRecordsArgs{ 11 | DomainName: TestDomainName, 12 | } 13 | describeArgs.PageSize = 100 14 | 15 | describeResponse, err := client.DescribeDomainRecords(&describeArgs) 16 | if err == nil { 17 | record := describeResponse.DomainRecords.Record[0] 18 | arg := DescribeDomainRecordInfoArgs{ 19 | RecordId: record.RecordId, 20 | } 21 | response, err := client.DescribeDomainRecordInfo(&arg) 22 | if err == nil { 23 | t.Logf("DescribeDomainRecordInfo success: %v", response) 24 | } else { 25 | t.Errorf("Failed to DescribeDomainRecordInfo: %s", describeArgs.DomainName) 26 | } 27 | } else { 28 | t.Errorf("Failed to DescribeDomainRecords: %s", describeArgs.DomainName) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dns/DescribeDomainRecords.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeDomainRecordsArgs struct { 6 | DomainName string 7 | 8 | //optional 9 | common.Pagination 10 | RRKeyWord string 11 | TypeKeyWord string 12 | ValueKeyWord string 13 | } 14 | 15 | type DescribeDomainRecordsResponse struct { 16 | common.Response 17 | common.PaginationResult 18 | InstanceId string 19 | DomainRecords struct { 20 | Record []RecordType 21 | } 22 | } 23 | 24 | // DescribeDomainRecords 25 | // 26 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeDomainRecords 27 | func (client *Client) DescribeDomainRecords(args *DescribeDomainRecordsArgs) (response *DescribeDomainRecordsResponse, err error) { 28 | action := "DescribeDomainRecords" 29 | response = &DescribeDomainRecordsResponse{} 30 | err = client.Invoke(action, args, response) 31 | if err == nil { 32 | return response, nil 33 | } else { 34 | return nil, err 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dns/DescribeDomainRecordsNew.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeDomainRecordsNewArgs struct { 6 | DomainName string 7 | 8 | //optional 9 | common.Pagination 10 | RRKeyWord string 11 | TypeKeyWord string 12 | ValueKeyWord string 13 | } 14 | 15 | type DescribeDomainRecordsNewResponse struct { 16 | common.Response 17 | common.PaginationResult 18 | InstanceId string 19 | DomainRecords struct { 20 | Record []RecordTypeNew 21 | } 22 | } 23 | 24 | // DescribeDomainRecordsNew 25 | // 26 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeDomainRecords 27 | func (client *Client) DescribeDomainRecordsNew(args *DescribeDomainRecordsNewArgs) (response *DescribeDomainRecordsNewResponse, err error) { 28 | action := "DescribeDomainRecords" 29 | response = &DescribeDomainRecordsNewResponse{} 30 | err = client.Invoke(action, args, response) 31 | if err == nil { 32 | return response, nil 33 | } else { 34 | return nil, err 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dns/DescribeDomainRecordsNew_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDescribeDomainRecordsNew(t *testing.T) { 8 | //prepare 9 | client := NewTestClientNew() 10 | describeArgs := DescribeDomainRecordsNewArgs{ 11 | DomainName: TestDomainName, 12 | } 13 | describeArgs.PageSize = 100 14 | 15 | describeResponse, err := client.DescribeDomainRecordsNew(&describeArgs) 16 | if err == nil { 17 | t.Logf("DescribeDomainRecords success: TotalCount:%d ", describeResponse.TotalCount) 18 | } else { 19 | t.Errorf("Failed to DescribeDomainRecords: %s", describeArgs.DomainName) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dns/DescribeDomainRecords_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDescribeDomainRecords(t *testing.T) { 8 | //prepare 9 | client := NewTestClient() 10 | describeArgs := DescribeDomainRecordsArgs{ 11 | DomainName: TestDomainName, 12 | } 13 | describeArgs.PageSize = 100 14 | 15 | describeResponse, err := client.DescribeDomainRecords(&describeArgs) 16 | if err == nil { 17 | t.Logf("DescribeDomainRecords success: TotalCount:%d ", describeResponse.TotalCount) 18 | } else { 19 | t.Errorf("Failed to DescribeDomainRecords: %s", describeArgs.DomainName) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dns/DescribeDomains.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type DescribeDomainsArgs struct { 10 | // optional 11 | common.Pagination 12 | KeyWord string 13 | GroupId string 14 | } 15 | 16 | type DescribeDomainsResponse struct { 17 | response common.Response 18 | common.PaginationResult 19 | Domains struct { 20 | Domain []DomainType 21 | } 22 | } 23 | 24 | // DescribeDomains 25 | // 26 | // You can read doc at https://help.aliyun.com/document_detail/29751.html?spm=5176.doc29750.6.594.dvyRJV 27 | func (client *Client) DescribeDomains(args *DescribeDomainsArgs) (domains []DomainType, err error) { 28 | action := "DescribeDomains" 29 | response := &DescribeDomainsResponse{} 30 | err = client.Invoke(action, args, response) 31 | 32 | if err != nil { 33 | log.Printf("%s error, %v", action, err) 34 | return nil, err 35 | } 36 | 37 | return response.Domains.Domain, err 38 | } 39 | -------------------------------------------------------------------------------- /dns/DescribeDomains_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "testing" 4 | 5 | func TestDescribeDomains(t *testing.T) { 6 | client := NewTestClientNew() 7 | describeArgs := DescribeDomainInfoArgs{ 8 | DomainName: TestDomainName, 9 | } 10 | 11 | _, err := client.DescribeDomainInfo(&describeArgs) 12 | if err == nil { 13 | t.Logf("DescribeDomains success") 14 | } else { 15 | t.Errorf("Failed to DescribeDomains: %v", err) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dns/DescribeSubDomainRecords.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeSubDomainRecordsArgs struct { 6 | SubDomain string 7 | 8 | //optional 9 | PageNumber int32 10 | PageSize int32 11 | Type string 12 | } 13 | 14 | type DescribeSubDomainRecordsResponse struct { 15 | common.Response 16 | InstanceId string 17 | TotalCount int32 18 | PageNumber int32 19 | PageSize int32 20 | DomainRecords struct { 21 | Record []RecordType 22 | } 23 | } 24 | 25 | // DescribeSubDomainRecords 26 | // 27 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&DescribeSubDomainRecords 28 | func (client *Client) DescribeSubDomainRecords(args *DescribeSubDomainRecordsArgs) (response *DescribeSubDomainRecordsResponse, err error) { 29 | action := "DescribeSubDomainRecords" 30 | response = &DescribeSubDomainRecordsResponse{} 31 | err = client.Invoke(action, args, response) 32 | if err == nil { 33 | return response, nil 34 | } else { 35 | return nil, err 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dns/DescribeSubDomainRecords_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDescribeSubDomainRecords(t *testing.T) { 8 | //prepare 9 | client := NewTestClient() 10 | describeArgs := DescribeSubDomainRecordsArgs{ 11 | SubDomain: "go." + TestDomainName, 12 | } 13 | 14 | describeResponse, err := client.DescribeSubDomainRecords(&describeArgs) 15 | if err == nil { 16 | t.Logf("DescribeSubDomainRecords success: %v ", describeResponse) 17 | } else { 18 | t.Errorf("Failed to DescribeSubDomainRecords: %s", describeArgs.SubDomain) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dns/GetMainDomainName.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type GetMainDomainNameArgs struct { 6 | InputString string 7 | } 8 | 9 | type GetMainDomainNameResponse struct { 10 | common.Response 11 | InstanceId string 12 | DomainName string 13 | RR string 14 | DomainLevel int32 15 | } 16 | 17 | // GetMainDomainName 18 | // 19 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/domain-related&GetMainDomainName 20 | func (client *Client) GetMainDomainName(args *GetMainDomainNameArgs) (response *GetMainDomainNameResponse, err error) { 21 | action := "GetMainDomainName" 22 | response = &GetMainDomainNameResponse{} 23 | err = client.Invoke(action, args, response) 24 | if err == nil { 25 | return response, nil 26 | } else { 27 | return nil, err 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dns/GetMainDomainName_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestGetMainDomainName(t *testing.T) { 8 | //prepare 9 | client := NewTestClient() 10 | args := GetMainDomainNameArgs{ 11 | InputString: "go." + TestDomainName, 12 | } 13 | 14 | resp, err := client.GetMainDomainName(&args) 15 | if err == nil { 16 | t.Logf("GetMainDomainName success: %v ", resp) 17 | } else { 18 | t.Errorf("Failed to GetMainDomainName: %s", args.InputString) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dns/UpdateDomainGroup.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type UpdateDomainGroupArgs struct { 10 | GroupId string 11 | GroupName string 12 | } 13 | 14 | type UpdateDomainGroupResponse struct { 15 | common.Response 16 | GroupId string 17 | GroupName string 18 | } 19 | 20 | // UpdateDomainGroup 21 | // 22 | // You can read doc at https://help.aliyun.com/document_detail/29763.html?spm=5176.doc29762.6.605.iFRKjn 23 | func (client *Client) UpdateDomainGroup(args *UpdateDomainGroupArgs) (response *UpdateDomainGroupResponse, err error) { 24 | action := "UpdateDomainGroup" 25 | response = &UpdateDomainGroupResponse{} 26 | err = client.Invoke(action, args, response) 27 | if err == nil { 28 | return response, nil 29 | } else { 30 | log.Printf("%s error, %v", action, err) 31 | return response, err 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dns/UpdateDomainGroup_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "testing" 4 | 5 | func TestUpdateDomainGroup(t *testing.T) { 6 | client := NewTestClientNew() 7 | 8 | addGroupArgs := AddDomainGroupArgs{ 9 | GroupName: TestDomainGroupName, 10 | } 11 | addGroupRes, _ := client.AddDomainGroup(&addGroupArgs) 12 | 13 | updateArgs := UpdateDomainGroupArgs{ 14 | GroupId: addGroupRes.GroupId, 15 | GroupName: TestChanegGroupName, 16 | } 17 | _, err := client.UpdateDomainGroup(&updateArgs) 18 | if err == nil { 19 | t.Logf("UpdateDomainGroup success") 20 | } else { 21 | t.Errorf("Failed to UpdateDomainGroup, %v", err) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dns/UpdateDomainRecord.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type UpdateDomainRecordArgs struct { 6 | RecordId string 7 | RR string 8 | Type string 9 | Value string 10 | 11 | //optional 12 | TTL int32 13 | Priority int32 14 | Line string 15 | } 16 | 17 | type UpdateDomainRecordResponse struct { 18 | common.Response 19 | InstanceId string 20 | RecordId string 21 | } 22 | 23 | // UpdateDomainRecord 24 | // 25 | // You can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/record-related&UpdateDomainRecord 26 | func (client *Client) UpdateDomainRecord(args *UpdateDomainRecordArgs) (response *UpdateDomainRecordResponse, err error) { 27 | action := "UpdateDomainRecord" 28 | response = &UpdateDomainRecordResponse{} 29 | err = client.Invoke(action, args, response) 30 | if err == nil { 31 | return response, nil 32 | } else { 33 | return nil, err 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dns/UpdateDomainRecord_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestUpdateDomainRecord(t *testing.T) { 8 | //prepare 9 | client := NewTestClient() 10 | addDomainRecordArgs := AddDomainRecordArgs{ 11 | DomainName: TestDomainName, 12 | RR: "testupdaterecordid", 13 | Value: "8.8.8.8", 14 | Type: ARecord, 15 | } 16 | 17 | addResponse, err := client.AddDomainRecord(&addDomainRecordArgs) 18 | 19 | // test update record 20 | updateArgs := UpdateDomainRecordArgs{ 21 | RecordId: addResponse.RecordId, 22 | RR: addDomainRecordArgs.RR, 23 | Value: "4.4.4.4", 24 | Type: ARecord, 25 | } 26 | 27 | _, err = client.UpdateDomainRecord(&updateArgs) 28 | if err == nil { 29 | t.Logf("UpdateDomainRecord success: RR:%s Value:%s", updateArgs.RR, updateArgs.Value) 30 | } else { 31 | t.Errorf("Failed to UpdateDomainRecord: %s", updateArgs.RecordId) 32 | } 33 | 34 | //clearup 35 | deleteDomainRecordArgs := DeleteDomainRecordArgs{ 36 | RecordId: addResponse.RecordId, 37 | } 38 | _, err = client.DeleteDomainRecord(&deleteDomainRecordArgs) 39 | if err != nil { 40 | t.Errorf("Failed to DeleteDomainRecord: %s", deleteDomainRecordArgs.RecordId) 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /dns/client.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type Client struct { 10 | common.Client 11 | } 12 | 13 | const ( 14 | // DNSDefaultEndpoint is the default API endpoint of DNS services 15 | DNSDefaultEndpoint = "http://dns.aliyuncs.com" 16 | DNSAPIVersion = "2015-01-09" 17 | 18 | DNSDefaultEndpointNew = "http://alidns.aliyuncs.com" 19 | ) 20 | 21 | // NewClient creates a new instance of DNS client 22 | func NewClient(accessKeyId, accessKeySecret string) *Client { 23 | endpoint := os.Getenv("DNS_ENDPOINT") 24 | if endpoint == "" { 25 | endpoint = DNSDefaultEndpoint 26 | } 27 | return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) 28 | } 29 | 30 | // NewClientNew creates a new instance of DNS client, with http://alidns.aliyuncs.com as default endpoint 31 | func NewClientNew(accessKeyId, accessKeySecret string) *Client { 32 | endpoint := os.Getenv("DNS_ENDPOINT") 33 | if endpoint == "" { 34 | endpoint = DNSDefaultEndpointNew 35 | } 36 | return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) 37 | } 38 | 39 | // NewCustomClient creates a new instance of ECS client with customized API endpoint 40 | func NewCustomClient(accessKeyId, accessKeySecret string, endpoint string) *Client { 41 | client := &Client{} 42 | client.Init(endpoint, DNSAPIVersion, accessKeyId, accessKeySecret) 43 | return client 44 | } 45 | 46 | func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client { 47 | client := &Client{} 48 | client.Init(endpoint, DNSAPIVersion, accessKeyId, accessKeySecret) 49 | return client 50 | } 51 | -------------------------------------------------------------------------------- /dns/config_test.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | //Modify with your Access Key Id and Access Key Secret 4 | const ( 5 | TestAccessKeyId = "MY_ACCESS_KEY_ID" 6 | TestAccessKeySecret = "MY_ACCESS_KEY_SECRET" 7 | TestDomainName = "aisafe.win" 8 | TestDomainGroupName = "testgroup" 9 | TestChanegGroupName = "testchangegroup" 10 | ) 11 | 12 | var testClient *Client 13 | 14 | func NewTestClient() *Client { 15 | if testClient == nil { 16 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 17 | } 18 | return testClient 19 | } 20 | 21 | // change DNSDefaultEndpoint to "http://alidns.aliyuncs.com" 22 | func NewTestClientNew() *Client { 23 | if testClient == nil { 24 | testClient = NewClientNew(TestAccessKeyId, TestAccessKeySecret) 25 | } 26 | return testClient 27 | } 28 | 29 | var testDebugClient *Client 30 | 31 | func NewTestClientForDebug() *Client { 32 | if testDebugClient == nil { 33 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 34 | testDebugClient.SetDebug(true) 35 | } 36 | return testDebugClient 37 | } 38 | -------------------------------------------------------------------------------- /dns/record.go: -------------------------------------------------------------------------------- 1 | package dns 2 | 3 | // 4 | //you can read doc at https://docs.aliyun.com/#/pub/dns/api-reference/enum-type&record-format 5 | const ( 6 | ARecord = "A" 7 | NSRecord = "NS" 8 | MXRecord = "MX" 9 | TXTRecord = "TXT" 10 | CNAMERecord = "CNAME" 11 | SRVRecord = "SRV" 12 | AAAARecord = "AAAA" 13 | RedirectURLRecord = "REDIRECT_URL" 14 | ForwordURLRecord = "FORWORD_URL" 15 | ) 16 | 17 | type RecordType struct { 18 | DomainName string 19 | RecordId string 20 | RR string 21 | Type string 22 | Value string 23 | TTL int32 24 | Priority int32 25 | Line string 26 | Status string 27 | Locked bool 28 | } 29 | -------------------------------------------------------------------------------- /ecs/config_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | //Modify with your Access Key Id and Access Key Secret 10 | 11 | var ( 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("TestVswitchID") 18 | 19 | TestInstanceId = os.Getenv("InstanceId") 20 | TestSecurityGroupId = os.Getenv("TestSecurityGroupId") 21 | TestResourceGroupId = os.Getenv("TestResourceGroupId") 22 | TestImageId = os.Getenv("TestImageId") 23 | TestAccountId = "MY_TEST_ACCOUNT_ID" //Get from https://account.console.aliyun.com 24 | TestInstanceType = os.Getenv("InstanceType") 25 | TestVSwitchID = "MY_TEST_VSWITCHID" 26 | 27 | TestIAmRich = false 28 | TestQuick = false 29 | ) 30 | 31 | var testClient *Client 32 | 33 | func NewTestClient() *Client { 34 | if testClient == nil { 35 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 36 | } 37 | return testClient 38 | } 39 | 40 | var testDebugClient *Client 41 | 42 | func NewTestClientForDebug() *Client { 43 | if testDebugClient == nil { 44 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 45 | testDebugClient.SetDebug(true) 46 | } 47 | return testDebugClient 48 | } 49 | 50 | var testVpcDebugClient *Client 51 | 52 | func NewVpcTestClientForDebug() *Client { 53 | if testVpcDebugClient == nil { 54 | testVpcDebugClient = NewVPCClient(TestAccessKeyId, TestAccessKeySecret, TestRegionID) 55 | testVpcDebugClient.SetDebug(true) 56 | } 57 | return testVpcDebugClient 58 | } 59 | 60 | var testLocationClient *Client 61 | 62 | func NetTestLocationClientForDebug() *Client { 63 | if testLocationClient == nil { 64 | testLocationClient = NewECSClientWithSecurityToken4RegionalDomain(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, TestRegionID) 65 | testLocationClient.SetDebug(true) 66 | } 67 | 68 | return testLocationClient 69 | } 70 | -------------------------------------------------------------------------------- /ecs/instance_types_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDescribeInstanceTypes(t *testing.T) { 8 | client := NewTestClient() 9 | instanceTypes, err := client.DescribeInstanceTypes() 10 | if err != nil { 11 | t.Fatalf("Failed to DescribeInstanceTypes: %v", err) 12 | } 13 | for _, instanceType := range instanceTypes { 14 | t.Logf("InstanceType: %++v", instanceType) 15 | } 16 | 17 | instanceTypes, err = client.DescribeInstanceTypesNew(&DescribeInstanceTypesArgs{ 18 | InstanceTypes: []string{"ecs.ec5.24xlarge", "ecs.ddh6s.custom.c4m48"}, 19 | }) 20 | if err != nil { 21 | t.Fatalf("Failed to DescribeInstanceTypesNew: %v", err) 22 | } 23 | for _, instanceType := range instanceTypes { 24 | t.Logf("InstanceType: %++v", instanceType) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ecs/monitoring_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/denverdino/aliyungo/util" 8 | ) 9 | 10 | func TestMonitoring(t *testing.T) { 11 | client := NewTestClient() 12 | //client.SetDebug(true) 13 | 14 | //Describe test instance 15 | instance, err := client.DescribeInstanceAttribute(TestInstanceId) 16 | if err != nil { 17 | t.Fatalf("Failed to describe instance %s: %v", TestInstanceId, err) 18 | } 19 | t.Logf("Instance: %++v %v", instance, err) 20 | 21 | //Describe Instance Monitor Data 22 | now := time.Now().UTC() 23 | 24 | starting := time.Date(now.Year(), now.Month(), now.Day(), now.Hour()-2, now.Minute(), now.Second(), now.Nanosecond(), now.Location()) 25 | ending := time.Date(now.Year(), now.Month(), now.Day(), now.Hour()-1, now.Minute(), now.Second(), now.Nanosecond(), now.Location()) 26 | 27 | args := DescribeInstanceMonitorDataArgs{ 28 | InstanceId: TestInstanceId, 29 | StartTime: util.ISO6801Time(starting), 30 | EndTime: util.ISO6801Time(ending), 31 | } 32 | 33 | monitorData, err := client.DescribeInstanceMonitorData(&args) 34 | 35 | if err != nil { 36 | t.Fatalf("Failed to describe monitoring data for instance %s: %v", TestInstanceId, err) 37 | } 38 | 39 | for _, data := range monitorData { 40 | t.Logf("Monitor Data: %++v", data) 41 | } 42 | //Describe EIP monitor data 43 | 44 | //Describe disk monitor data 45 | diskArgs := DescribeDisksArgs{ 46 | InstanceId: TestInstanceId, 47 | RegionId: instance.RegionId, 48 | } 49 | 50 | disks, _, err := client.DescribeDisks(&diskArgs) 51 | if err != nil { 52 | t.Fatalf("Failed to DescribeDisks for instance %s: %v", TestInstanceId, err) 53 | } 54 | 55 | for _, disk := range disks { 56 | args := DescribeDiskMonitorDataArgs{ 57 | DiskId: disk.DiskId, 58 | StartTime: util.ISO6801Time(starting), 59 | EndTime: util.ISO6801Time(ending), 60 | } 61 | monitorData, _, err := client.DescribeDiskMonitorData(&args) 62 | 63 | if err != nil { 64 | t.Fatalf("Failed to describe monitoring data for disk %s: %v", disk.DiskId, err) 65 | } 66 | 67 | for _, data := range monitorData { 68 | t.Logf("Monitor Data: %++v", data) 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ecs/nat_gateway_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import "testing" 4 | 5 | func TestDescribeNatGateway(t *testing.T) { 6 | 7 | client := NewTestClient() 8 | args := DescribeBandwidthPackagesArgs{ 9 | RegionId: "cn-beijing", 10 | BandwidthPackageId: "bwp-2zes6svn910zjqhcyqnxm", 11 | NatGatewayId: "ngw-2zex6oklf8901t76yut6c", 12 | } 13 | packages, err := client.DescribeBandwidthPackages(&args) 14 | if err != nil { 15 | t.Fatalf("Failed to DescribeBandwidthPackages: %v", err) 16 | } 17 | for _, pack := range packages.BandwidthPackages.BandwidthPackage { 18 | t.Logf("pack.IpCount: %++v", pack.IpCount) 19 | t.Logf("pack.Bandwidth: %++v", pack.Bandwidth) 20 | t.Logf("pack.ZoneId: %++v", pack.ZoneId) 21 | t.Logf("pack.ipAddress: %++v", len(pack.PublicIpAddresses.PublicIpAddresse)) 22 | } 23 | } 24 | 25 | func TestClient_DescribeNatGateways(t *testing.T) { 26 | client := NewVpcTestClientForDebug() 27 | args := &DescribeNatGatewaysArgs{ 28 | RegionId: TestRegionID, 29 | VpcId: TestVpcId, 30 | } 31 | 32 | natGateways, _, err := client.DescribeNatGateways(args) 33 | if err != nil { 34 | t.Fatalf("Error %++v", err) 35 | } else { 36 | for index, item := range natGateways { 37 | t.Logf("natGateways[%d]=%++v", index, item) 38 | } 39 | } 40 | } 41 | 42 | func TestClient_CreateNatGateway(t *testing.T) { 43 | client := NewVpcTestClientForDebug() 44 | args := &CreateNatGatewayArgs{ 45 | RegionId: TestRegionID, 46 | VpcId: TestVpcId, 47 | VSwitchId: TestVswitchID, 48 | NatType: NgwNatTypeEnhanced, 49 | } 50 | 51 | resp, err := client.CreateNatGateway(args) 52 | if err != nil { 53 | t.Fatalf("Error %++v", err) 54 | } else { 55 | t.Logf("ngw id :%s", resp.NatGatewayId) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ecs/regions.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeRegionsArgs struct { 6 | } 7 | 8 | // 9 | // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype®iontype 10 | type RegionType struct { 11 | RegionId common.Region 12 | LocalName string 13 | } 14 | 15 | type DescribeRegionsResponse struct { 16 | common.Response 17 | Regions struct { 18 | Region []RegionType 19 | } 20 | } 21 | 22 | // DescribeRegions describes regions 23 | // 24 | // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/region&describeregions 25 | func (client *Client) DescribeRegions() (regions []RegionType, err error) { 26 | response := DescribeRegionsResponse{} 27 | 28 | err = client.Invoke("DescribeRegions", &DescribeRegionsArgs{}, &response) 29 | 30 | if err != nil { 31 | return []RegionType{}, err 32 | } 33 | return response.Regions.Region, nil 34 | } 35 | -------------------------------------------------------------------------------- /ecs/route_entry.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeRouteEntryListArgs struct { 6 | RegionId string 7 | RouteTableId string 8 | DestinationCidrBlock string 9 | IpVersion string 10 | MaxResult int 11 | NextHopId string 12 | NextHopType string 13 | NextToken string 14 | RouteEntryId string 15 | RouteEntryName string 16 | RouteEntryType string 17 | } 18 | 19 | type DescribeRouteEntryListResponse struct { 20 | common.Response 21 | NextToken string 22 | RouteEntrys struct { 23 | RouteEntry []RouteEntry 24 | } 25 | } 26 | 27 | type RouteEntry struct { 28 | DestinationCidrBlock string 29 | IpVersion string 30 | RouteEntryId string 31 | RouteEntryName string 32 | RouteTableId string 33 | Status string 34 | Type string 35 | NextHops struct { 36 | NextHop []NextHop 37 | } 38 | } 39 | 40 | type NextHop struct { 41 | Enabled int 42 | Weight int 43 | NextHopId string 44 | NextHopRegionId string 45 | NextHopType string 46 | NextHopRelatedInfo NextHopRelatedInfo 47 | } 48 | 49 | type NextHopRelatedInfo struct { 50 | RegionId string 51 | InstanceId string 52 | InstanceType string 53 | } 54 | 55 | // DescribeRouteEntryList describes route entries 56 | // 57 | func (client *Client) DescribeRouteEntryList(args *DescribeRouteEntryListArgs) (*DescribeRouteEntryListResponse, error) { 58 | response := &DescribeRouteEntryListResponse{} 59 | err := client.Invoke("DescribeRouteEntryList", args, &response) 60 | return response, err 61 | } 62 | -------------------------------------------------------------------------------- /ecs/route_entry_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestClient_DescribeRouteEntry(t *testing.T) { 8 | client := NewVpcTestClientForDebug() 9 | 10 | nextHopId := "i-xxxx" 11 | destinationCidrBlock := "172.xxx/x" 12 | args := &DescribeRouteEntryListArgs{ 13 | RegionId: "cn-hangzhou", 14 | RouteTableId: "vtb-xxxxx", 15 | DestinationCidrBlock: destinationCidrBlock, 16 | NextHopId: nextHopId, 17 | RouteEntryType: "Custom", 18 | } 19 | 20 | response, err := client.DescribeRouteEntryList(args) 21 | 22 | if err != nil { 23 | t.Fatalf("Error %++v", err) 24 | } else { 25 | t.Logf("Result %++v", response) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ecs/route_tables_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | func testRouteTable(t *testing.T, client *Client, regionId common.Region, vpcId string, vrouterId string, routeTableId string, instanceId string) { 10 | cidrBlock := "0.0.0.0/0" 11 | createArgs := CreateRouteEntryArgs{ 12 | RouteTableId: routeTableId, 13 | DestinationCidrBlock: cidrBlock, 14 | NextHopType: NextHopInstance, 15 | NextHopId: instanceId, 16 | ClientToken: client.GenerateClientToken(), 17 | } 18 | 19 | err := client.CreateRouteEntry(&createArgs) 20 | if err != nil { 21 | t.Errorf("Failed to create route entry: %v", err) 22 | } 23 | 24 | describeArgs := DescribeRouteTablesArgs{ 25 | VRouterId: vrouterId, 26 | } 27 | 28 | routeTables, _, err := client.DescribeRouteTables(&describeArgs) 29 | 30 | if err != nil { 31 | t.Errorf("Failed to describe route tables: %v", err) 32 | } else { 33 | t.Logf("RouteTables of VRouter %s: %++v", vrouterId, routeTables) 34 | } 35 | 36 | err = client.WaitForAllRouteEntriesAvailable(vrouterId, routeTableId, 60) 37 | if err != nil { 38 | t.Errorf("Failed to wait route entries: %v", err) 39 | } 40 | deleteArgs := DeleteRouteEntryArgs{ 41 | RouteTableId: routeTableId, 42 | DestinationCidrBlock: cidrBlock, 43 | NextHopId: instanceId, 44 | } 45 | 46 | err = client.DeleteRouteEntry(&deleteArgs) 47 | if err != nil { 48 | t.Errorf("Failed to delete route entry: %v", err) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /ecs/snapshots_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSnapshot(t *testing.T) { 8 | 9 | client := NewTestClient() 10 | 11 | instance, err := client.DescribeInstanceAttribute(TestInstanceId) 12 | if err != nil { 13 | t.Fatalf("Failed to DescribeInstanceAttribute for instance %s: %v", TestInstanceId, err) 14 | } 15 | 16 | args := DescribeSnapshotsArgs{} 17 | 18 | args.InstanceId = TestInstanceId 19 | args.RegionId = instance.RegionId 20 | snapshots, _, err := client.DescribeSnapshots(&args) 21 | 22 | if err != nil { 23 | t.Errorf("Failed to DescribeSnapshots for instance %s: %v", TestInstanceId, err) 24 | } 25 | 26 | for _, snapshot := range snapshots { 27 | t.Logf("Snapshot of instance %s: %++v", TestInstanceId, snapshot) 28 | } 29 | } 30 | 31 | func TestSnapshotCreationAndDeletion(t *testing.T) { 32 | if TestQuick { 33 | return 34 | } 35 | 36 | client := NewTestClient() 37 | 38 | instance, err := client.DescribeInstanceAttribute(TestInstanceId) 39 | if err != nil { 40 | t.Fatalf("Failed to DescribeInstanceAttribute for instance %s: %v", TestInstanceId, err) 41 | } 42 | 43 | //Describe disk monitor data 44 | diskArgs := DescribeDisksArgs{ 45 | InstanceId: TestInstanceId, 46 | RegionId: instance.RegionId, 47 | } 48 | 49 | disks, _, err := client.DescribeDisks(&diskArgs) 50 | if err != nil { 51 | t.Fatalf("Failed to DescribeDisks for instance %s: %v", TestInstanceId, err) 52 | } 53 | 54 | diskId := disks[0].DiskId 55 | 56 | args := CreateSnapshotArgs{ 57 | DiskId: diskId, 58 | SnapshotName: "My_Test_Snapshot", 59 | Description: "My Test Snapshot Description", 60 | ClientToken: client.GenerateClientToken(), 61 | } 62 | 63 | snapshotId, err := client.CreateSnapshot(&args) 64 | if err != nil { 65 | t.Errorf("Failed to CreateSnapshot for disk %s: %v", diskId, err) 66 | } 67 | client.WaitForSnapShotReady(instance.RegionId, snapshotId, 0) 68 | 69 | err = client.DeleteSnapshot(snapshotId) 70 | if err != nil { 71 | t.Errorf("Failed to DeleteSnapshot for disk %s: %v", diskId, err) 72 | } 73 | 74 | t.Logf("Snapshot %s is deleted successfully.", snapshotId) 75 | 76 | } 77 | -------------------------------------------------------------------------------- /ecs/snat_entry_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import "testing" 4 | 5 | func TestDescribeSnatTableEntry(t *testing.T) { 6 | 7 | client := NewTestClient() 8 | args := DescribeSnatTableEntriesArgs{ 9 | RegionId: "cn-beijing", 10 | SnatTableId: "stb-abc", 11 | } 12 | _, _, err := client.DescribeSnatTableEntries(&args) 13 | if err != nil { 14 | t.Fatalf("Failed to DescribeBandwidthPackages: %v", err) 15 | } 16 | } 17 | 18 | func TestCreateSnatEntryWithSourceCIDR(t *testing.T) { 19 | client := NewTestClient() 20 | args := CreateSnatEntryArgs{ 21 | RegionId: "cn-beijing", 22 | SnatTableId: "stb-xxx", 23 | SnatIp: "47.XX.XX.98", 24 | SourceCIDR: "192.168.1.1/32", 25 | } 26 | 27 | _, err := client.CreateSnatEntry(&args) 28 | if err != nil { 29 | t.Errorf("failed to CreateSnatEntry with SourceCIDR: %v", err) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ecs/vrouters.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | "github.com/denverdino/aliyungo/util" 6 | ) 7 | 8 | type DescribeVRoutersArgs struct { 9 | VRouterId string 10 | RegionId common.Region 11 | common.Pagination 12 | } 13 | 14 | // 15 | // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vroutersettype 16 | type VRouterSetType struct { 17 | VRouterId string 18 | RegionId common.Region 19 | VpcId string 20 | RouteTableIds struct { 21 | RouteTableId []string 22 | } 23 | VRouterName string 24 | Description string 25 | CreationTime util.ISO6801Time 26 | } 27 | 28 | type DescribeVRoutersResponse struct { 29 | common.Response 30 | common.PaginationResult 31 | VRouters struct { 32 | VRouter []VRouterSetType 33 | } 34 | } 35 | 36 | // DescribeVRouters describes Virtual Routers 37 | // 38 | // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vrouter&describevrouters 39 | func (client *Client) DescribeVRouters(args *DescribeVRoutersArgs) (vrouters []VRouterSetType, pagination *common.PaginationResult, err error) { 40 | response, err := client.DescribeVRoutersWithRaw(args) 41 | if err == nil { 42 | return response.VRouters.VRouter, &response.PaginationResult, nil 43 | } 44 | 45 | return nil, nil, err 46 | } 47 | 48 | func (client *Client) DescribeVRoutersWithRaw(args *DescribeVRoutersArgs) (response *DescribeVRoutersResponse, err error) { 49 | args.Validate() 50 | response = &DescribeVRoutersResponse{} 51 | 52 | err = client.Invoke("DescribeVRouters", args, response) 53 | 54 | if err == nil { 55 | return response, nil 56 | } 57 | 58 | return nil, err 59 | } 60 | 61 | type ModifyVRouterAttributeArgs struct { 62 | VRouterId string 63 | VRouterName string 64 | Description string 65 | } 66 | 67 | type ModifyVRouterAttributeResponse struct { 68 | common.Response 69 | } 70 | 71 | // ModifyVRouterAttribute modifies attribute of Virtual Router 72 | // 73 | // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vrouter&modifyvrouterattribute 74 | func (client *Client) ModifyVRouterAttribute(args *ModifyVRouterAttributeArgs) error { 75 | response := ModifyVRouterAttributeResponse{} 76 | return client.Invoke("ModifyVRouterAttribute", args, &response) 77 | } 78 | -------------------------------------------------------------------------------- /ecs/vrouters_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | func testVRouter(t *testing.T, client *Client, regionId common.Region, vpcId string, vrouterId string, instanceId string) { 10 | 11 | newName := "My_Aliyun_test_VRouter" 12 | 13 | modifyArgs := ModifyVRouterAttributeArgs{ 14 | VRouterId: vrouterId, 15 | VRouterName: newName, 16 | Description: newName, 17 | } 18 | 19 | err := client.ModifyVRouterAttribute(&modifyArgs) 20 | if err != nil { 21 | t.Errorf("Failed to modify VRouters: %v", err) 22 | } 23 | 24 | args := DescribeVRoutersArgs{ 25 | VRouterId: vrouterId, 26 | RegionId: regionId, 27 | } 28 | 29 | vrouters, _, err := client.DescribeVRouters(&args) 30 | if err != nil { 31 | t.Errorf("Failed to describe VRouters: %v", err) 32 | } 33 | t.Logf("VRouters: %++v", vrouters) 34 | if vrouters[0].VRouterName != newName { 35 | t.Errorf("Failed to modify VRouters with new name: %s", newName) 36 | } 37 | 38 | testRouteTable(t, client, regionId, vpcId, vrouterId, vrouters[0].RouteTableIds.RouteTableId[0], instanceId) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ecs/vswitches_test.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | func testCreateVSwitch(t *testing.T, client *Client, regionId common.Region, zoneId string, vpcId string, vrouterId string) (vSwitchId string, err error) { 10 | 11 | args := CreateVSwitchArgs{ 12 | ZoneId: zoneId, 13 | CidrBlock: "172.16.10.0/24", 14 | VpcId: vpcId, 15 | VSwitchName: "AliyunGo_test_vSwitch", 16 | Description: "AliyunGo test vSwitch", 17 | ClientToken: client.GenerateClientToken(), 18 | } 19 | 20 | vSwitchId, err = client.CreateVSwitch(&args) 21 | 22 | if err != nil { 23 | t.Errorf("Failed to create VSwitch: %v", err) 24 | return "", err 25 | } 26 | 27 | t.Logf("VSwitch is created successfully: %s", vSwitchId) 28 | 29 | err = client.WaitForVSwitchAvailable(vpcId, vSwitchId, 60) 30 | if err != nil { 31 | t.Errorf("Failed to wait VSwitch %s to available: %v", vSwitchId, err) 32 | } 33 | 34 | newName := args.VSwitchName + "_update" 35 | modifyArgs := ModifyVSwitchAttributeArgs{ 36 | VSwitchId: vSwitchId, 37 | VSwitchName: newName, 38 | Description: newName, 39 | } 40 | 41 | err = client.ModifyVSwitchAttribute(&modifyArgs) 42 | if err != nil { 43 | t.Errorf("Failed to modify VSwitch %s: %v", vSwitchId, err) 44 | } 45 | 46 | argsDescribe := DescribeVSwitchesArgs{ 47 | VpcId: vpcId, 48 | VSwitchId: vSwitchId, 49 | } 50 | 51 | vswitches, _, err := client.DescribeVSwitches(&argsDescribe) 52 | if err != nil { 53 | t.Errorf("Failed to describe VSwitch: %v", err) 54 | } 55 | 56 | if vswitches[0].VSwitchName != newName { 57 | t.Errorf("Failed to modify VSwitch with new name: %s", newName) 58 | } 59 | 60 | t.Logf("VSwitch is : %++v", vswitches) 61 | 62 | return vSwitchId, err 63 | } 64 | -------------------------------------------------------------------------------- /ess/client.go: -------------------------------------------------------------------------------- 1 | package ess 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | 6 | "os" 7 | ) 8 | 9 | type Client struct { 10 | common.Client 11 | } 12 | 13 | const ( 14 | // ESSDefaultEndpoint is the default API endpoint of ESS services 15 | ESSDefaultEndpoint = "https://ess.aliyuncs.com" 16 | ESSAPIVersion = "2014-08-28" 17 | ESSServiceCode = "ess" 18 | ) 19 | 20 | // NewClient creates a new instance of RDS client 21 | func NewClient(accessKeyId, accessKeySecret string) *Client { 22 | endpoint := os.Getenv("ESS_ENDPOINT") 23 | if endpoint == "" { 24 | endpoint = ESSDefaultEndpoint 25 | } 26 | return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) 27 | } 28 | 29 | func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client { 30 | client := &Client{} 31 | client.Init(endpoint, ESSAPIVersion, accessKeyId, accessKeySecret) 32 | return client 33 | } 34 | 35 | func NewESSClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client { 36 | endpoint := os.Getenv("ESS_ENDPOINT") 37 | if endpoint == "" { 38 | endpoint = ESSDefaultEndpoint 39 | } 40 | 41 | return NewClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID) 42 | } 43 | 44 | func NewClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client { 45 | client := &Client{} 46 | client.NewInit(endpoint, ESSAPIVersion, accessKeyId, accessKeySecret, ESSServiceCode, regionID) 47 | return client 48 | } 49 | -------------------------------------------------------------------------------- /ess/config_test.go: -------------------------------------------------------------------------------- 1 | package ess 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | "github.com/denverdino/aliyungo/ecs" 6 | ) 7 | 8 | const ( 9 | TestAccessKeyId = "MY_ACCESS_KEY_ID" 10 | TestAccessKeySecret = "MY_ACCESS_KEY_SECRET" 11 | RegionId = "MY_TEST_REGION" 12 | ScalingGroupId = "MY_TEST_SCALING_GROUP_ID" 13 | TestInstanceId = "MY_TEST_INSTANCE_ID" 14 | TestRuleArn = "MY_TEST_RULE_ARN" 15 | TestScheduleLaunchTime = "MY_TEST_SCHEDULE_LAUNCH_TIME" 16 | TestIAmRich = false 17 | ) 18 | 19 | var testClient *Client 20 | 21 | func NewTestClient(regionId common.Region) *Client { 22 | if testClient == nil { 23 | testClient = NewESSClient(TestAccessKeyId, TestAccessKeySecret, regionId) 24 | } 25 | return testClient 26 | } 27 | 28 | var testDebugClient *Client 29 | 30 | func NewTestClientForDebug(regionId common.Region) *Client { 31 | if testDebugClient == nil { 32 | testDebugClient = NewESSClient(TestAccessKeyId, TestAccessKeySecret, regionId) 33 | testDebugClient.SetDebug(true) 34 | } 35 | return testDebugClient 36 | } 37 | 38 | var testEcsClient *ecs.Client 39 | 40 | func NewTestEcsClient(regionId common.Region) *ecs.Client { 41 | if testEcsClient == nil { 42 | testEcsClient = ecs.NewECSClient(TestAccessKeyId, TestAccessKeySecret, regionId) 43 | } 44 | return testEcsClient 45 | } 46 | -------------------------------------------------------------------------------- /ess/configuration_test.go: -------------------------------------------------------------------------------- 1 | package ess 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | func TestEssScalingConfigurationCreationAndDeletion(t *testing.T) { 10 | 11 | if TestIAmRich == false { 12 | // Avoid payment 13 | return 14 | } 15 | 16 | client := NewTestClient(common.Region(RegionId)) 17 | ecsClient := NewTestEcsClient(common.Region(RegionId)) 18 | 19 | ecs, err := ecsClient.DescribeInstanceAttribute(TestInstanceId) 20 | if err != nil { 21 | t.Fatalf("Failed to describe ecs %s: %v", TestInstanceId, err) 22 | } 23 | t.Logf("ECS instance: %++v %v", ecs, err) 24 | 25 | cArgs := CreateScalingConfigurationArgs{ 26 | ScalingGroupId: ScalingGroupId, 27 | ImageId: ecs.ImageId, 28 | InstanceType: ecs.InstanceType, 29 | SecurityGroupId: ecs.SecurityGroupIds.SecurityGroupId[0], 30 | } 31 | 32 | csc, err := client.CreateScalingConfiguration(&cArgs) 33 | if err != nil { 34 | t.Errorf("Failed to create scaling configuration %v", err) 35 | } 36 | configurationId := csc.ScalingConfigurationId 37 | t.Logf("Configuration %s is created successfully.", configurationId) 38 | 39 | sArgs := DescribeScalingConfigurationsArgs{ 40 | RegionId: RegionId, 41 | ScalingGroupId: ScalingGroupId, 42 | ScalingConfigurationId: []string{configurationId}, 43 | } 44 | sResp, _, err := client.DescribeScalingConfigurations(&sArgs) 45 | if len(sResp) < 1 { 46 | t.Fatalf("Failed to describe confituration %s", configurationId) 47 | } 48 | 49 | config := sResp[0] 50 | t.Logf("Configuration: %++v %v", config, err) 51 | 52 | dcArgs := DeleteScalingConfigurationArgs{ 53 | ScalingGroupId: ScalingGroupId, 54 | ScalingConfigurationId: configurationId, 55 | ImageId: config.ImageId, 56 | } 57 | 58 | _, err = client.DeleteScalingConfiguration(&dcArgs) 59 | if err != nil { 60 | t.Errorf("Failed to delete scaling configuration %v", err) 61 | } 62 | 63 | t.Logf("Configuration %s is deleted successfully.", configurationId) 64 | 65 | } 66 | -------------------------------------------------------------------------------- /ess/rule_test.go: -------------------------------------------------------------------------------- 1 | package ess 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | "github.com/denverdino/aliyungo/util" 8 | ) 9 | 10 | func TestEssScalingRuleCreationAndDeletion(t *testing.T) { 11 | 12 | if TestIAmRich == false { 13 | // Avoid payment 14 | return 15 | } 16 | client := NewTestClient(common.Region(RegionId)) 17 | cArgs := CreateScalingRuleArgs{ 18 | RegionId: common.Region(RegionId), 19 | ScalingGroupId: ScalingGroupId, 20 | AdjustmentType: TotalCapacity, 21 | AdjustmentValue: 3, 22 | ScalingRuleName: "srn", 23 | } 24 | 25 | csc, err := client.CreateScalingRule(&cArgs) 26 | if err != nil { 27 | t.Errorf("Failed to create scaling rule %v", err) 28 | } 29 | ruleId := csc.ScalingRuleId 30 | t.Logf("Rule %s is created successfully.", ruleId) 31 | 32 | mArgs := ModifyScalingRuleArgs{ 33 | RegionId: common.Region(RegionId), 34 | ScalingRuleId: ruleId, 35 | AdjustmentValue: 2, 36 | ScalingRuleName: "srnm", 37 | } 38 | 39 | _, err = client.ModifyScalingRule(&mArgs) 40 | if err != nil { 41 | t.Errorf("Failed to modify scaling rule %v", err) 42 | } 43 | t.Logf("Rule %s is modify successfully.", ruleId) 44 | 45 | eArgs := ExecuteScalingRuleArgs{ 46 | ScalingRuleAri: csc.ScalingRuleAri, 47 | ClientToken: util.CreateRandomString(), 48 | } 49 | _, err = client.ExecuteScalingRule(&eArgs) 50 | if err != nil { 51 | t.Errorf("Failed to execute scaling rule: %v", err) 52 | } 53 | t.Logf("Rule %s is execute successfully.", ruleId) 54 | 55 | sArgs := DescribeScalingRulesArgs{ 56 | RegionId: common.Region(RegionId), 57 | ScalingGroupId: ScalingGroupId, 58 | ScalingRuleId: []string{ruleId}, 59 | } 60 | sResp, _, err := client.DescribeScalingRules(&sArgs) 61 | if len(sResp) < 1 { 62 | t.Fatalf("Failed to describe rules %s", ruleId) 63 | } 64 | 65 | rule := sResp[0] 66 | t.Logf("Rule: %++v %v", rule, err) 67 | 68 | dcArgs := DeleteScalingRuleArgs{ 69 | RegionId: common.Region(RegionId), 70 | ScalingRuleId: ruleId, 71 | } 72 | 73 | _, err = client.DeleteScalingRule(&dcArgs) 74 | if err != nil { 75 | t.Errorf("Failed to delete scaling rule %v", err) 76 | } 77 | 78 | t.Logf("Rule %s is deleted successfully.", ruleId) 79 | 80 | } 81 | -------------------------------------------------------------------------------- /ess/schedule_test.go: -------------------------------------------------------------------------------- 1 | package ess 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | func TestEssScalingScheduleCreationAndDeletion(t *testing.T) { 10 | 11 | if TestIAmRich == false { 12 | // Avoid payment 13 | return 14 | } 15 | client := NewTestClient(common.Region(RegionId)) 16 | cArgs := CreateScheduledTaskArgs{ 17 | RegionId: common.Region(RegionId), 18 | ScheduledAction: TestRuleArn, 19 | LaunchTime: TestScheduleLaunchTime, 20 | ScheduledTaskName: "stn", 21 | } 22 | 23 | csc, err := client.CreateScheduledTask(&cArgs) 24 | if err != nil { 25 | t.Errorf("Failed to create scaling schedule %v", err) 26 | } 27 | taskId := csc.ScheduledTaskId 28 | t.Logf("Schedule task %s is created successfully.", taskId) 29 | 30 | mArgs := ModifyScheduledTaskArgs{ 31 | RegionId: common.Region(RegionId), 32 | ScheduledTaskId: taskId, 33 | RecurrenceType: RecurrenceType("Monthly"), 34 | RecurrenceValue: "1-1", 35 | RecurrenceEndTime: TestScheduleLaunchTime, 36 | TaskEnabled: true, 37 | } 38 | 39 | _, err = client.ModifyScheduledTask(&mArgs) 40 | if err != nil { 41 | t.Errorf("Failed to modify schedule task %v", err) 42 | } 43 | t.Logf("Schedule task %s is modify successfully.", taskId) 44 | 45 | sArgs := DescribeScheduledTasksArgs{ 46 | RegionId: common.Region(RegionId), 47 | ScheduledTaskId: []string{taskId}, 48 | } 49 | sResp, _, err := client.DescribeScheduledTasks(&sArgs) 50 | if len(sResp) < 1 { 51 | t.Fatalf("Failed to describe schedule task %s", taskId) 52 | } 53 | 54 | task := sResp[0] 55 | t.Logf("Task: %++v %v", task, err) 56 | 57 | dcArgs := DeleteScheduledTaskArgs{ 58 | RegionId: common.Region(RegionId), 59 | ScheduledTaskId: taskId, 60 | } 61 | 62 | _, err = client.DeleteScheduledTask(&dcArgs) 63 | if err != nil { 64 | t.Errorf("Failed to delete schedule task %v", err) 65 | } 66 | 67 | t.Logf("Task %s is deleted successfully.", taskId) 68 | 69 | } 70 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/denverdino/aliyungo 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/golang/protobuf v1.5.2 // indirect 7 | github.com/magiconair/properties v1.8.6 // indirect 8 | github.com/opentracing/opentracing-go v1.2.0 // indirect 9 | github.com/pkg/errors v0.9.1 // indirect 10 | github.com/stretchr/testify v1.7.1 // indirect 11 | github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect 12 | github.com/uber/jaeger-lib v2.4.1+incompatible // indirect 13 | go.uber.org/atomic v1.9.0 // indirect 14 | golang.org/x/text v0.3.7 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /kms/client.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | const ( 10 | // KMSDefaultEndpoint is the default API endpoint of KMS services 11 | KMSDefaultEndpoint = "https://kms.cn-hangzhou.aliyuncs.com" 12 | KMSAPIVersion = "2016-01-20" 13 | KMSServiceCode = "kms" 14 | ) 15 | 16 | type Client struct { 17 | common.Client 18 | } 19 | 20 | // NewClient creates a new instance of KMS client 21 | func NewClient(accessKeyId, accessKeySecret string) *Client { 22 | endpoint := os.Getenv("KMS_ENDPOINT") 23 | if endpoint == "" { 24 | endpoint = KMSDefaultEndpoint 25 | } 26 | return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) 27 | } 28 | 29 | func NewClientWithRegion(accessKeyId string, accessKeySecret string, regionID common.Region) *Client { 30 | endpoint := os.Getenv("KMS_ENDPOINT") 31 | if endpoint == "" { 32 | endpoint = KMSDefaultEndpoint 33 | } 34 | client := &Client{} 35 | client.NewInit(endpoint, KMSAPIVersion, accessKeyId, accessKeySecret, KMSServiceCode, regionID) 36 | return client 37 | } 38 | 39 | func NewClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string) *Client { 40 | client := &Client{} 41 | client.Init(endpoint, KMSAPIVersion, accessKeyId, accessKeySecret) 42 | return client 43 | } 44 | 45 | func NewECSClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client { 46 | endpoint := os.Getenv("KMS_ENDPOINT") 47 | if endpoint == "" { 48 | endpoint = KMSDefaultEndpoint 49 | } 50 | 51 | return NewKMSClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID) 52 | } 53 | 54 | func NewKMSClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *Client { 55 | client := &Client{} 56 | client.WithEndpoint(endpoint). 57 | WithVersion(KMSAPIVersion). 58 | WithAccessKeyId(accessKeyId). 59 | WithAccessKeySecret(accessKeySecret). 60 | WithSecurityToken(securityToken). 61 | WithServiceCode(KMSServiceCode). 62 | WithRegionID(regionID). 63 | InitClient() 64 | return client 65 | } 66 | -------------------------------------------------------------------------------- /kms/config_test.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | var ( 10 | TestAccessKeyId = os.Getenv("AccessKeyId") 11 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 12 | TestSecurityToken = os.Getenv("SecurityToken") 13 | TestRegionID = common.Region(os.Getenv("RegionId")) 14 | TestKeyId = os.Getenv("KeyId") 15 | 16 | encryptionContext = map[string]string{ 17 | "Key1": "Value1", 18 | "Key2": "Value2", 19 | } 20 | 21 | debugClient = NetTestLocationClientForDebug() 22 | ) 23 | 24 | var testClient *Client 25 | 26 | func NewTestClient() *Client { 27 | if testClient == nil { 28 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 29 | } 30 | return testClient 31 | } 32 | 33 | var testDebugClient *Client 34 | 35 | func NewTestClientForDebug() *Client { 36 | if testDebugClient == nil { 37 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 38 | testDebugClient.SetDebug(true) 39 | } 40 | return testDebugClient 41 | } 42 | 43 | var testLocationClient *Client 44 | 45 | func NetTestLocationClientForDebug() *Client { 46 | if testLocationClient == nil { 47 | testLocationClient = NewClientWithRegion(TestAccessKeyId, TestAccessKeySecret, TestRegionID) 48 | testLocationClient.SetDebug(true) 49 | } 50 | 51 | return testLocationClient 52 | } 53 | -------------------------------------------------------------------------------- /kms/decrypt.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | //https://help.aliyun.com/document_detail/28950.html?spm=5176.doc28947.6.564.JrFZRr 6 | type DecryptArgs struct { 7 | CiphertextBlob string 8 | EncryptionContext map[string]string 9 | } 10 | 11 | type DecryptResponse struct { 12 | common.Response 13 | Plaintext string 14 | KeyId string 15 | } 16 | 17 | func (client *Client) Decrypt(args *DecryptArgs) (*DecryptResponse, error) { 18 | response := &DecryptResponse{} 19 | err := client.Invoke("Decrypt", args, response) 20 | return response, err 21 | } 22 | -------------------------------------------------------------------------------- /kms/decrypt_test.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import "testing" 4 | 5 | func TestClient_Decrypt(t *testing.T) { 6 | encryptArgs := &EncryptAgrs{ 7 | KeyId: TestKeyId, 8 | EncryptionContext: encryptionContext, 9 | Plaintext: "abc", 10 | } 11 | 12 | encryptResponse, err := debugClient.Encrypt(encryptArgs) 13 | if err != nil { 14 | t.Fatalf("Error %++v", err) 15 | } else { 16 | t.Logf("Result = %++v", encryptResponse) 17 | } 18 | 19 | args := &DecryptArgs{ 20 | CiphertextBlob: encryptResponse.CiphertextBlob, 21 | EncryptionContext: encryptionContext, 22 | } 23 | 24 | response, err := debugClient.Decrypt(args) 25 | if err != nil { 26 | t.Fatalf("Error %++v", err) 27 | } else { 28 | t.Logf("Result = %++v", response) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /kms/encrypt.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | //https://help.aliyun.com/document_detail/28949.html?spm=5176.doc28950.6.569.kI1mTw 6 | type EncryptAgrs struct { 7 | KeyId string 8 | Plaintext string 9 | EncryptionContext map[string]string 10 | } 11 | 12 | type EncryptResponse struct { 13 | common.Response 14 | CiphertextBlob string 15 | KeyId string 16 | } 17 | 18 | func (client *Client) Encrypt(args *EncryptAgrs) (*EncryptResponse, error) { 19 | response := &EncryptResponse{} 20 | err := client.Invoke("Encrypt", args, response) 21 | return response, err 22 | } 23 | -------------------------------------------------------------------------------- /kms/encrypt_test.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import "testing" 4 | 5 | func TestClient_Encrypt(t *testing.T) { 6 | args := &EncryptAgrs{ 7 | KeyId: TestKeyId, 8 | Plaintext: "abc", 9 | EncryptionContext: encryptionContext, 10 | } 11 | 12 | response, err := debugClient.Encrypt(args) 13 | if err != nil { 14 | t.Fatalf("Error %++v", err) 15 | } else { 16 | t.Logf("Result = %++v", response) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /kms/regions.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeRegionsArgs struct { 6 | } 7 | 8 | type DescribeRegionsResponse struct { 9 | common.Response 10 | Regions Regions 11 | } 12 | 13 | type Regions struct { 14 | Region []Region 15 | } 16 | 17 | type Region struct { 18 | RegionId string 19 | } 20 | 21 | func (client *Client) DescribeRegions() (*DescribeRegionsResponse, error) { 22 | response := &DescribeRegionsResponse{} 23 | err := client.Invoke("DescribeRegions", &DescribeRegionsArgs{}, response) 24 | return response, err 25 | } 26 | -------------------------------------------------------------------------------- /kms/regions_test.go: -------------------------------------------------------------------------------- 1 | package kms 2 | 3 | import "testing" 4 | 5 | func TestClient_DescribeRegions(t *testing.T) { 6 | 7 | response, err := debugClient.DescribeRegions() 8 | if err != nil { 9 | t.Fatalf("Error %++v", err) 10 | } else { 11 | t.Logf("Reuslt = %++v", response) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /location/client.go: -------------------------------------------------------------------------------- 1 | package location 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | type Client struct { 10 | common.Client 11 | } 12 | 13 | const ( 14 | // LocationDefaultEndpoint is the default API endpoint of Location services 15 | LocationDefaultEndpoint = "https://location.aliyuncs.com" 16 | LocationAPIVersion = "2015-06-12" 17 | ) 18 | 19 | // NewClient creates a new instance of Location client 20 | func NewClient(accessKeyId, accessKeySecret string) *Client { 21 | endpoint := os.Getenv("LOCATION_ENDPOINT") 22 | if endpoint == "" { 23 | endpoint = LocationDefaultEndpoint 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, LocationAPIVersion, accessKeyId, accessKeySecret) 31 | return client 32 | } 33 | -------------------------------------------------------------------------------- /location/config_test.go: -------------------------------------------------------------------------------- 1 | package location 2 | 3 | const ( 4 | TestAccessKeyId = "MY_ACCESS_KEY_ID" 5 | TestAccessKeySecret = "MY_ACCESS_KEY_SECRET" 6 | ) 7 | 8 | var testClient *Client 9 | 10 | func NewTestClient() *Client { 11 | if testClient == nil { 12 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 13 | } 14 | return testClient 15 | } 16 | 17 | var testDebugClient *Client 18 | 19 | func NewTestClientForDebug() *Client { 20 | if testDebugClient == nil { 21 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 22 | testDebugClient.SetDebug(true) 23 | } 24 | return testDebugClient 25 | } 26 | -------------------------------------------------------------------------------- /location/endpoints.go: -------------------------------------------------------------------------------- 1 | package location 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | ) 6 | 7 | type DescribeEndpointArgs struct { 8 | Id common.Region 9 | ServiceCode string 10 | Type string 11 | } 12 | 13 | type EndpointItem struct { 14 | Protocols struct { 15 | Protocols []string 16 | } 17 | Type string 18 | Namespace string 19 | Id common.Region 20 | SerivceCode string 21 | Endpoint string 22 | } 23 | 24 | type DescribeEndpointResponse struct { 25 | common.Response 26 | EndpointItem 27 | } 28 | 29 | func (client *Client) DescribeEndpoint(args *DescribeEndpointArgs) (*DescribeEndpointResponse, error) { 30 | response := &DescribeEndpointResponse{} 31 | err := client.Invoke("DescribeEndpoint", args, response) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return response, err 36 | } 37 | 38 | type DescribeEndpointsArgs struct { 39 | Id common.Region 40 | ServiceCode string 41 | Type string 42 | } 43 | 44 | type DescribeEndpointsResponse struct { 45 | common.Response 46 | Endpoints struct { 47 | Endpoint []EndpointItem 48 | } 49 | } 50 | 51 | func (client *Client) DescribeEndpoints(args *DescribeEndpointsArgs) (*DescribeEndpointsResponse, error) { 52 | response := &DescribeEndpointsResponse{} 53 | err := client.Invoke("DescribeEndpoints", args, response) 54 | if err != nil { 55 | return nil, err 56 | } 57 | return response, err 58 | } 59 | -------------------------------------------------------------------------------- /location/endpoints_test.go: -------------------------------------------------------------------------------- 1 | package location 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | func TestDescribeEndpoint(t *testing.T) { 10 | client := NewTestClientForDebug() 11 | 12 | args := &DescribeEndpointArgs{ 13 | Id: common.Hangzhou, 14 | ServiceCode: "slb", 15 | Type: "openAPI", 16 | } 17 | 18 | endpoint, err := client.DescribeEndpoint(args) 19 | if err != nil { 20 | t.Fatalf("Failed to describe endpoint %++v", err) 21 | } 22 | 23 | t.Logf("endpoint is %++v", endpoint) 24 | } 25 | 26 | func TestDescribeEndpoints(t *testing.T) { 27 | client := NewTestClientForDebug() 28 | 29 | args := &DescribeEndpointsArgs{ 30 | Id: common.Hangzhou, 31 | ServiceCode: "slb", 32 | Type: "openAPI", 33 | } 34 | 35 | endpoints, err := client.DescribeEndpoints(args) 36 | if err != nil { 37 | t.Fatalf("Failed to describe endpoints %++v", err) 38 | } 39 | 40 | t.Logf("endpoints is %++v", endpoints) 41 | } 42 | -------------------------------------------------------------------------------- /location/regions.go: -------------------------------------------------------------------------------- 1 | package location 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | ) 6 | 7 | type DescribeRegionsArgs struct { 8 | Password string 9 | } 10 | 11 | type DescribeRegionsResponse struct { 12 | common.Response 13 | 14 | TotalCount int 15 | RegionIds struct { 16 | RegionIds []string 17 | } 18 | } 19 | 20 | func (client *Client) DescribeRegions(args *DescribeRegionsArgs) (*DescribeRegionsResponse, error) { 21 | response := &DescribeRegionsResponse{} 22 | err := client.Invoke("DescribeRegions", args, response) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return response, err 27 | } 28 | -------------------------------------------------------------------------------- /location/regions_test.go: -------------------------------------------------------------------------------- 1 | package location 2 | 3 | import "testing" 4 | 5 | func TestDescribeRegions(t *testing.T) { 6 | client := NewTestClientForDebug() 7 | 8 | args := &DescribeRegionsArgs{ 9 | //RegionId: common.Beijing, 10 | } 11 | 12 | regions, err := client.DescribeRegions(args) 13 | if err != nil { 14 | t.Fatalf("Failed to describe regions %++v", err) 15 | } 16 | 17 | t.Logf("regions is %++v", regions) 18 | } 19 | -------------------------------------------------------------------------------- /location/services.go: -------------------------------------------------------------------------------- 1 | package location 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | ) 6 | 7 | type DescribeServicesArgs struct { 8 | RegionId common.Region 9 | } 10 | 11 | type DescribeServicesResponse struct { 12 | common.Response 13 | 14 | TotalCount int 15 | Services struct { 16 | Services []string 17 | } 18 | } 19 | 20 | func (client *Client) DescribeServices(args *DescribeServicesArgs) (*DescribeServicesResponse, error) { 21 | response := &DescribeServicesResponse{} 22 | err := client.Invoke("DescribeServices", args, response) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return response, err 27 | } 28 | -------------------------------------------------------------------------------- /location/services_test.go: -------------------------------------------------------------------------------- 1 | package location 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | func TestDescribeServices(t *testing.T) { 10 | client := NewTestClientForDebug() 11 | 12 | args := &DescribeServicesArgs{ 13 | RegionId: common.Beijing, 14 | } 15 | 16 | services, err := client.DescribeServices(args) 17 | if err != nil { 18 | t.Fatalf("Failed to describe services %++v", err) 19 | } 20 | 21 | t.Logf("services is %++v", services) 22 | } 23 | -------------------------------------------------------------------------------- /mns/client.go: -------------------------------------------------------------------------------- 1 | package mns 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | const ( 8 | MNSAPIVersion = "2015-06-06" 9 | ) 10 | 11 | type Client struct { 12 | AccessKeyId string 13 | AccessKeySecret string 14 | SecurityToken string 15 | Endpoint string 16 | Version string 17 | httpClient *http.Client 18 | debug bool 19 | } 20 | 21 | func (client *Client) SetDebug(debug bool) { 22 | client.debug = debug 23 | } 24 | 25 | // SetTransport sets transport to the http client 26 | func (client *Client) SetTransport(transport http.RoundTripper) { 27 | if client.httpClient == nil { 28 | client.httpClient = &http.Client{} 29 | } 30 | client.httpClient.Transport = transport 31 | } 32 | 33 | func NewClient(accessKeyId, accessKeySecret, endpoint string) (client *Client) { 34 | client = &Client{ 35 | AccessKeyId: accessKeyId, 36 | AccessKeySecret: accessKeySecret, 37 | Endpoint: endpoint, 38 | Version: MNSAPIVersion, 39 | httpClient: &http.Client{}, 40 | } 41 | return client 42 | } 43 | 44 | func NewClientForAssumeRole(accessKeyId, accessKeySecret, securityToken, endpoint string) (client *Client) { 45 | client = &Client{ 46 | AccessKeyId: accessKeyId, 47 | AccessKeySecret: accessKeySecret, 48 | SecurityToken: securityToken, 49 | Endpoint: endpoint, 50 | Version: MNSAPIVersion, 51 | httpClient: &http.Client{}, 52 | } 53 | return client 54 | } 55 | -------------------------------------------------------------------------------- /mns/types.go: -------------------------------------------------------------------------------- 1 | package mns 2 | 3 | type Queue struct { 4 | *Client 5 | QueueName string 6 | Base64 bool 7 | } 8 | 9 | type Message struct { 10 | MessageBody string `xml:"MessageBody"` 11 | } 12 | 13 | type MsgSend struct { 14 | MessageId string `xml:"MessageId"` 15 | MessageBodyMD5 string `xml:"MessageBodyMD5"` 16 | } 17 | 18 | type MsgReceive struct { 19 | MessageId string `xml:"MessageId"` 20 | MessageBodyMD5 string `xml:"MessageBodyMD5"` 21 | MessageBody string `xml:"MessageBody"` 22 | ReceiptHandle string `xml:"ReceiptHandle"` 23 | EnqueueTime int64 `xml:"EnqueueTime"` 24 | NextVisibleTime int64 `xml:"NextVisibleTime"` 25 | DequeueCount int `xml:"DequeueCount"` 26 | Priority int `xml:"Priority"` 27 | } 28 | -------------------------------------------------------------------------------- /mns/util.go: -------------------------------------------------------------------------------- 1 | package mns 2 | 3 | import ( 4 | "crypto/hmac" 5 | "crypto/md5" 6 | "crypto/sha1" 7 | "encoding/base64" 8 | "encoding/hex" 9 | "fmt" 10 | "io" 11 | "time" 12 | ) 13 | 14 | // 获取当前时间戳(毫秒) 15 | func GetCurrentMillisecond() int64 { 16 | return time.Now().UnixNano() / int64(time.Millisecond) 17 | } 18 | 19 | // 获取当前时间戳(秒) 20 | func GetCurrentUnixMicro() int64 { 21 | return time.Now().Unix() * 1000 22 | } 23 | 24 | // 对字符串进行sha1 计算 25 | func Sha1(data string) string { 26 | t := sha1.New() 27 | io.WriteString(t, data) 28 | return fmt.Sprintf("%x", t.Sum(nil)) 29 | } 30 | 31 | // 对数据进行md5计算 32 | func Md5(byteMessage []byte) string { 33 | h := md5.New() 34 | h.Write(byteMessage) 35 | return hex.EncodeToString(h.Sum(nil)) 36 | } 37 | 38 | func HamSha1(data string, key []byte) string { 39 | hmac := hmac.New(sha1.New, key) 40 | hmac.Write([]byte(data)) 41 | 42 | return base64.StdEncoding.EncodeToString(hmac.Sum(nil)) 43 | } 44 | 45 | func dump(data interface{}) { 46 | fmt.Println(data) 47 | } 48 | -------------------------------------------------------------------------------- /mq/client_test.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import "testing" 4 | 5 | // 您在控制台创建的Topic 6 | var Topic = "" 7 | 8 | // 公测集群URL 9 | var ENDPOINT = "" 10 | 11 | // 阿里云官网身份验证访问码 12 | var Ak = "" 13 | 14 | // 阿里云身份验证密钥 15 | var Sk = "" 16 | 17 | // MQ控制台创建的Producer ID 18 | var ProducerID = "" 19 | 20 | // MQ控制台创建的Consumer ID 21 | var ConsumerID = "" 22 | 23 | func TestNewClient(t *testing.T) { 24 | client := NewClient(Ak, Sk, ENDPOINT, Topic, ProducerID, ConsumerID, "http", "http") 25 | msgId, err := client.Send(GetCurrentUnixMicro(), []byte("hello world")) 26 | if err != nil { 27 | t.Error(err) 28 | } else { 29 | t.Logf("The message id successfully send is %v", msgId) 30 | } 31 | } 32 | 33 | func TestReceiveClient(t *testing.T) { 34 | 35 | // time.Sleep(100 * time.Second) 36 | client := NewClient(Ak, Sk, ENDPOINT, Topic, ProducerID, ConsumerID, "http", "http") 37 | respChan := make(chan string) 38 | errChan := make(chan error) 39 | end := make(chan int) 40 | message := "" 41 | go func() { 42 | select { 43 | case resp := <-respChan: 44 | { 45 | t.Logf("message: %s", resp) 46 | message = resp 47 | end <- 1 48 | } 49 | case err := <-errChan: 50 | { 51 | t.Logf("err: %v", err) 52 | end <- 1 53 | } 54 | } 55 | }() 56 | 57 | client.ReceiveMessage(respChan, errChan) 58 | <-end 59 | 60 | if message != "hello world" { 61 | t.Errorf("message: %s", message) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /mq/types.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | var newline string = "\n" 4 | 5 | type SendMessage struct { 6 | Topic string 7 | Tag string 8 | ProducerId string 9 | Key string 10 | Body string 11 | Time int64 12 | } 13 | 14 | type Messages struct { 15 | Topic string 16 | Tag string 17 | ConsumerId string 18 | Time int64 19 | } 20 | 21 | type Message struct { 22 | Body string `json:"body"` 23 | BornTime string `json:"bornTime"` 24 | Key string `json:"key"` 25 | MsgHandle string `json:"msgHandle"` 26 | MsgId string `json:"msgId"` 27 | ReconsumeTimes int `json:"reconsumeTimes"` 28 | Tag string `json:"tag"` 29 | } 30 | 31 | // 生产者状态码 32 | func getStatusCodeMessage(statusCode int) string { 33 | switch statusCode { 34 | case 200: 35 | return "" 36 | case 201: 37 | return "" 38 | case 204: 39 | return "" 40 | case 400: 41 | return "Bad Request" 42 | case 403: 43 | return "Authentication Failed" 44 | case 408: 45 | return "Request Timeout" 46 | default: 47 | return "Unknown Error" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nas/CreateAccessRule.go: -------------------------------------------------------------------------------- 1 | package nas 2 | 3 | type CreateAccessRuleRequest struct { 4 | AccessGroupName string 5 | SourceCidrIp string 6 | Policy string 7 | SquashType string 8 | Priority string 9 | Version string 10 | RegionId string 11 | } 12 | 13 | type CreateAccessRuleResponse struct { 14 | Code string 15 | } 16 | 17 | func (client *Client) CreateAccessRule(args *CreateAccessRuleRequest) (resp CreateAccessRuleResponse, err error) { 18 | response := CreateAccessRuleResponse{} 19 | args.Version = VERSION 20 | args.Policy = DEFAULT_POLICY 21 | args.SquashType = DEFAULT_SQUASHTYPE 22 | args.Priority = DEFAULT_PRIORITY 23 | 24 | err = client.Invoke("CreateAccessRule", args, &response) 25 | return response, err 26 | } 27 | -------------------------------------------------------------------------------- /nas/CreateFileSystem.go: -------------------------------------------------------------------------------- 1 | package nas 2 | 3 | type CreateFileSystemRequest struct { 4 | ZoneId string 5 | Version string 6 | RegionId string 7 | } 8 | 9 | type CreateFileSystemResponse struct { 10 | FileSystemName string 11 | RequestId string 12 | Code string 13 | } 14 | 15 | func (client *Client) CreateFileSystem(args *CreateFileSystemRequest) (resp CreateFileSystemResponse, err error) { 16 | response := CreateFileSystemResponse{} 17 | args.Version = VERSION 18 | 19 | err = client.Invoke("CreateFileSystem", args, &response) 20 | return response, err 21 | } 22 | -------------------------------------------------------------------------------- /nas/CreateMountTarget.go: -------------------------------------------------------------------------------- 1 | package nas 2 | 3 | type CreateMountTargetRequest struct { 4 | FileSystemName string 5 | AccessGroupName string 6 | NetworkType string 7 | VpcId string 8 | VSwitchId string 9 | Version string 10 | RegionId string 11 | } 12 | 13 | type CreateMountTargetResponse struct { 14 | Code string 15 | } 16 | 17 | func (client *Client) CreateMountTarget(args *CreateMountTargetRequest) (resp CreateMountTargetResponse, err error) { 18 | response := CreateMountTargetResponse{} 19 | args.Version = VERSION 20 | 21 | err = client.Invoke("CreateMountTarget", args, &response) 22 | return response, err 23 | } 24 | -------------------------------------------------------------------------------- /nas/DescribeAccessRules.go: -------------------------------------------------------------------------------- 1 | package nas 2 | 3 | type DescribeAccessRulesRequest struct { 4 | AccessGroupName string 5 | Version string 6 | RegionId string 7 | } 8 | 9 | type DescribeAccessRulesResponse struct { 10 | Rules []Rule 11 | Code string 12 | } 13 | 14 | type Rule struct { 15 | Priority string 16 | SourceCidrIp string 17 | SquashType string 18 | RuleId string 19 | Policy string 20 | } 21 | 22 | func (client *Client) DescribeAccessRules(args *DescribeAccessRulesRequest) (resp DescribeAccessRulesResponse, err error) { 23 | response := DescribeAccessRulesResponse{} 24 | args.Version = VERSION 25 | err = client.Invoke("DescribeAccessRules", args, &response) 26 | return response, err 27 | } 28 | -------------------------------------------------------------------------------- /nas/DescribeFileSystems.go: -------------------------------------------------------------------------------- 1 | package nas 2 | 3 | type DescribeFileSystemsRequest struct { 4 | FileSystemName string 5 | Version string 6 | RegionId string 7 | } 8 | 9 | type DescribeFileSystemsResponse struct { 10 | FileSystems []FileSystem 11 | Code string 12 | } 13 | 14 | type FileSystem struct { 15 | CreateTime uint64 16 | MountTargetCount uint64 17 | PackageId string 18 | FileSystemName string 19 | FileSystemType string 20 | MeteredSize uint64 21 | FileSystemDesc string 22 | QuotaSize uint64 23 | ZoneId string 24 | } 25 | 26 | func (client *Client) DescribeFileSystems(args *DescribeFileSystemsRequest) (resp DescribeFileSystemsResponse, err error) { 27 | response := DescribeFileSystemsResponse{} 28 | args.Version = VERSION 29 | err = client.Invoke("DescribeFileSystems", args, &response) 30 | return response, err 31 | } 32 | -------------------------------------------------------------------------------- /nas/DescribeMountTargets.go: -------------------------------------------------------------------------------- 1 | package nas 2 | 3 | type DescribeMountTargetsRequest struct { 4 | FileSystemName string 5 | Version string 6 | RegionId string 7 | } 8 | 9 | type DescribeMountTargetsResponse struct { 10 | MountTargets []MountTarget 11 | Code string 12 | } 13 | 14 | type MountTarget struct { 15 | AccessGroupName string 16 | MountTargetIp string 17 | NetworkType string 18 | Status string 19 | MountTargetId string 20 | VpcId string 21 | VSwitchId string 22 | DomainName string 23 | CloudInstId string 24 | } 25 | 26 | func (client *Client) DescribeMountTargets(args *DescribeMountTargetsRequest) (resp DescribeMountTargetsResponse, err error) { 27 | response := DescribeMountTargetsResponse{} 28 | args.Version = VERSION 29 | err = client.Invoke("DescribeMountTargets", args, &response) 30 | return response, err 31 | } 32 | -------------------------------------------------------------------------------- /nas/client.go: -------------------------------------------------------------------------------- 1 | package nas 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | ) 6 | 7 | const ( 8 | VERSION = "2016-02-29" 9 | END_POINT = "https://nasservice-inner.aliyuncs.com" 10 | DEFAULT_POLICY = "readwrite" 11 | DEFAULT_SQUASHTYPE = "no_squash" 12 | DEFAULT_PRIORITY = "1" 13 | ) 14 | 15 | type Client struct { 16 | common.Client 17 | } 18 | 19 | // NewClient creates a new instance of NAS client 20 | func NewClient(accessKeyId, accessKeySecret string) *Client { 21 | client := &Client{} 22 | client.Init(END_POINT, VERSION, accessKeyId, accessKeySecret) 23 | return client 24 | } 25 | -------------------------------------------------------------------------------- /opensearch/application.go: -------------------------------------------------------------------------------- 1 | package opensearch 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | //应用管理类API 8 | const ( 9 | status = "status" 10 | ) 11 | 12 | //查看应用信息 13 | func (this *Client) GetStatus(appName string, resp interface{}) error { 14 | return this.InvokeByAnyMethod(http.MethodGet, "", "/index/"+appName, OpenSearchArgs{Action: status}, resp) 15 | } 16 | -------------------------------------------------------------------------------- /opensearch/client.go: -------------------------------------------------------------------------------- 1 | package opensearch 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | const ( 6 | Internet = "" 7 | Intranet = "intranet." 8 | VPC = "vpc." 9 | APIVersion = "v2" 10 | ) 11 | 12 | type Client struct { 13 | common.Client 14 | } 15 | 16 | //OpenSearch的API比较奇怪,action不在公共参数里面 17 | type OpenSearchArgs struct { 18 | Action string `ArgName:"action"` 19 | } 20 | 21 | func NewClient(networkType string, region common.Region, accessKeyId, accessKeySecret string) *Client { 22 | client := new(Client) 23 | client.Init("http://"+networkType+"opensearch-"+string(region)+".aliyuncs.com", APIVersion, accessKeyId, accessKeySecret) 24 | return client 25 | } 26 | -------------------------------------------------------------------------------- /opensearch/data.go: -------------------------------------------------------------------------------- 1 | package opensearch 2 | 3 | import "net/http" 4 | 5 | type PushArgs struct { 6 | OpenSearchArgs // 这个参数不用填 7 | Table_name string `ArgName:"table_name"` //要上传数据的表名 8 | Items string `ArgName:"items"` //规定JSON格式 9 | } 10 | 11 | //上传文档 12 | //支持新增、更新、删除的批量操作 13 | func (this *Client) Push(appName string, args PushArgs, resp interface{}) error { 14 | args.OpenSearchArgs.Action = "push" 15 | return this.InvokeByAnyMethod(http.MethodPost, "", "/index/doc/"+appName, args, resp) 16 | } 17 | -------------------------------------------------------------------------------- /opensearch/search.go: -------------------------------------------------------------------------------- 1 | package opensearch 2 | 3 | import "net/http" 4 | 5 | type SearchArgs struct { 6 | //搜索主体 7 | Query string `ArgName:"query"` 8 | //要查询的应用名 9 | Index_name string `ArgName:"index_name"` 10 | //[可以通过此参数获取本次查询需要的字段内容] 11 | Fetch_fields string `ArgName:"fetch_fields"` 12 | //[指定要使用的查询分析规则] 13 | Qp string `ArgName:"qp"` 14 | //[关闭已生效的查询分析功能] 15 | Disable string `ArgName:"disable"` 16 | //[设置粗排表达式名字] 17 | First_formula_name string `ArgName:"first_formula_name"` 18 | //[设置精排表达式名字] 19 | Formula_name string `ArgName:"formula_name"` 20 | //[动态摘要的配置] 21 | Summary string `ArgName:"summary"` 22 | } 23 | 24 | //搜索 25 | //系统提供了丰富的搜索语法以满足用户各种场景下的搜索需求 26 | func (this *Client) Search(args SearchArgs, resp interface{}) error { 27 | return this.InvokeByAnyMethod(http.MethodGet, "", "/search", args, resp) 28 | } 29 | -------------------------------------------------------------------------------- /oss/config_test.go: -------------------------------------------------------------------------------- 1 | package oss_test 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/oss" 7 | ) 8 | 9 | // 10 | //There are two ways to run unit tests here: 11 | // 1. Set your AccessKeyId and AccessKeySecret in env 12 | // simply use the command below: 13 | // "AccessKeyId=YourAccessKeyId AccessKeySecret=YourAccessKeySecret go test" 14 | // 15 | // 2. Replace "MY_ACCESS_KEY_ID" & "MY_ACCESS_KEY_SECRET" with your own access key & secret and run "go test" 16 | // 17 | 18 | var ( 19 | TestAccessKeyID = os.Getenv("AccessKeyId") 20 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 21 | TestSecurityToken = os.Getenv("SecurityToken") 22 | TestRegion = oss.Region(os.Getenv("RegionId")) 23 | 24 | TestServerSideEncryptionKeyID = os.Getenv("ServerSideEncryptionKeyId") 25 | ) 26 | -------------------------------------------------------------------------------- /oss/export.go: -------------------------------------------------------------------------------- 1 | package oss 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/util" 5 | ) 6 | 7 | var originalStrategy = attempts 8 | 9 | func SetAttemptStrategy(s *util.AttemptStrategy) { 10 | if s == nil { 11 | attempts = originalStrategy 12 | } else { 13 | attempts = *s 14 | } 15 | } 16 | 17 | func SetListPartsMax(n int) { 18 | listPartsMax = n 19 | } 20 | 21 | func SetListMultiMax(n int) { 22 | listMultiMax = n 23 | } 24 | -------------------------------------------------------------------------------- /oss/regions_test.go: -------------------------------------------------------------------------------- 1 | package oss_test 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/oss" 5 | 6 | "testing" 7 | ) 8 | 9 | func TestRegionEndpoint(t *testing.T) { 10 | t.Log(oss.Beijing.GetInternalEndpoint("test", false)) 11 | t.Log(oss.Beijing.GetVPCInternalEndpoint("test", true)) 12 | t.Log(oss.USEast1.GetVPCInternalEndpoint("test", true)) 13 | } 14 | -------------------------------------------------------------------------------- /push/README.md: -------------------------------------------------------------------------------- 1 | #ALI PUSH 2 | 3 | 阿里移动推送(Alibaba Cloud Mobile Push)是基于大数据的移动智能推送服务,帮助App快速集成移动推送的功能,在实现高效、精确、实时的移动推送的同时,极大地降低了开发成本。让开发者最有效地与用户保持连接,从而提高用户活跃度、提高应用的留存率。 4 | 5 | [Push](https://help.aliyun.com/document_detail/29414.html)文档 6 | 7 | ###2016.12.20 yarous224 8 | 9 | 写了SDK的这个部分 10 | 11 | ###2017.1.30 yarous224 12 | 13 | 更新API到2016-08-01。目前依然只支持高级推送,因为基本解决了所有问题。其它接口会陆续推出。 -------------------------------------------------------------------------------- /push/client.go: -------------------------------------------------------------------------------- 1 | package push 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | const ( 6 | PushEndPoint = "https://cloudpush.aliyuncs.com/" 7 | Push = "Push" 8 | PushAPIVersion = "2016-08-01" 9 | ) 10 | 11 | type Client struct { 12 | common.Client 13 | } 14 | 15 | func NewClient(accessKeyId, accessKeySecret string) *Client { 16 | client := new(Client) 17 | client.Init(PushEndPoint, PushAPIVersion, accessKeyId, accessKeySecret) 18 | return client 19 | } 20 | -------------------------------------------------------------------------------- /pvtz/changeLogs.go: -------------------------------------------------------------------------------- 1 | package pvtz 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | "github.com/denverdino/aliyungo/util" 6 | ) 7 | 8 | type DescribeChangeLogsArgs struct { 9 | StartTime int64 10 | EndTime int64 11 | EntityType string 12 | Keyword string 13 | Lang string 14 | UserClientIp string 15 | common.Pagination 16 | } 17 | 18 | // 19 | type ChangeLogType struct { 20 | OperTimestamp int64 21 | OperAction string 22 | OperObject string 23 | EntityId string 24 | EntityName string 25 | OperIp string 26 | OperTime util.ISO6801Time 27 | Id int64 28 | Content string 29 | IsPtr bool 30 | RecordCount int 31 | } 32 | 33 | type DescribeChangeLogsResponse struct { 34 | common.Response 35 | common.PaginationResult 36 | ChangeLogs struct { 37 | ChangeLog []ChangeLogType 38 | } 39 | } 40 | 41 | // DescribeChangeLogs describes change logs 42 | // 43 | // You can read doc at https://help.aliyun.com/document_detail/66253.html 44 | func (client *Client) DescribeChangeLogs(args *DescribeChangeLogsArgs) (logs []ChangeLogType, err error) { 45 | 46 | result := []ChangeLogType{} 47 | 48 | for { 49 | response := DescribeChangeLogsResponse{} 50 | err = client.Invoke("DescribeChangeLogs", args, &response) 51 | 52 | if err != nil { 53 | return result, err 54 | } 55 | 56 | result = append(result, response.ChangeLogs.ChangeLog...) 57 | 58 | nextPage := response.PaginationResult.NextPage() 59 | if nextPage == nil { 60 | break 61 | } 62 | args.Pagination = *nextPage 63 | } 64 | 65 | return result, nil 66 | } 67 | -------------------------------------------------------------------------------- /pvtz/config_test.go: -------------------------------------------------------------------------------- 1 | package pvtz 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | "os" 6 | ) 7 | 8 | //Modify with your Access Key Id and Access Key Secret 9 | 10 | var ( 11 | TestAccessKeyId = os.Getenv("AccessKeyId") 12 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 13 | TestVPCId = os.Getenv("VPCId") 14 | TestSecurityToken = os.Getenv("SecurityToken") 15 | TestRegionID = common.Region(os.Getenv("RegionId")) 16 | ) 17 | 18 | var testClient *Client 19 | 20 | func NewTestClient() *Client { 21 | if testClient == nil { 22 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 23 | } 24 | return testClient 25 | } 26 | 27 | var testDebugClient *Client 28 | 29 | func NewTestClientForDebug() *Client { 30 | if testDebugClient == nil { 31 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 32 | testDebugClient.SetDebug(true) 33 | } 34 | return testDebugClient 35 | } 36 | 37 | var testDebugLocationClient *Client 38 | 39 | func NewTestLocationClientForDebug() *Client { 40 | if testDebugLocationClient == nil { 41 | testDebugLocationClient = NewPVTZClientWithSecurityToken4RegionalDomain(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, TestRegionID) 42 | testDebugLocationClient.SetDebug(true) 43 | } 44 | return testDebugLocationClient 45 | } 46 | -------------------------------------------------------------------------------- /pvtz/regions.go: -------------------------------------------------------------------------------- 1 | package pvtz 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeRegionsArgs struct { 6 | } 7 | 8 | // 9 | type RegionType struct { 10 | RegionId common.Region 11 | RegionName string 12 | } 13 | 14 | type DescribeRegionsResponse struct { 15 | common.Response 16 | Regions struct { 17 | Region []RegionType 18 | } 19 | } 20 | 21 | // DescribeRegions describes regions 22 | // 23 | // You can read doc at https://help.aliyun.com/document_detail/66246.html 24 | func (client *Client) DescribeRegions() (regions []RegionType, err error) { 25 | response := DescribeRegionsResponse{} 26 | 27 | err = client.Invoke("DescribeRegions", &DescribeRegionsArgs{}, &response) 28 | 29 | if err != nil { 30 | return []RegionType{}, err 31 | } 32 | return response.Regions.Region, nil 33 | } 34 | -------------------------------------------------------------------------------- /ram/account.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | type UserRequest struct { 4 | User 5 | } 6 | 7 | type UserResponse struct { 8 | RamCommonResponse 9 | User User 10 | } 11 | 12 | type UpdateUserRequest struct { 13 | UserName string 14 | NewUserName string 15 | NewDisplayName string 16 | NewMobilePhone string 17 | NewEmail string 18 | NewComments string 19 | } 20 | 21 | type ListUserRequest struct { 22 | Marker string 23 | MaxItems int8 24 | } 25 | 26 | type ListUserResponse struct { 27 | RamCommonResponse 28 | IsTruncated bool 29 | Marker string 30 | Users struct { 31 | User []User 32 | } 33 | } 34 | 35 | func (client *RamClient) CreateUser(user UserRequest) (UserResponse, error) { 36 | var userResponse UserResponse 37 | err := client.Invoke("CreateUser", user, &userResponse) 38 | if err != nil { 39 | return UserResponse{}, err 40 | } 41 | return userResponse, nil 42 | } 43 | 44 | func (client *RamClient) GetUser(userQuery UserQueryRequest) (UserResponse, error) { 45 | var userResponse UserResponse 46 | err := client.Invoke("GetUser", userQuery, &userResponse) 47 | if err != nil { 48 | return UserResponse{}, nil 49 | } 50 | return userResponse, nil 51 | } 52 | 53 | func (client *RamClient) UpdateUser(newUser UpdateUserRequest) (UserResponse, error) { 54 | var userResponse UserResponse 55 | err := client.Invoke("UpdateUser", newUser, &userResponse) 56 | if err != nil { 57 | return UserResponse{}, err 58 | } 59 | return userResponse, nil 60 | } 61 | 62 | func (client *RamClient) DeleteUser(userQuery UserQueryRequest) (RamCommonResponse, error) { 63 | var commonResp RamCommonResponse 64 | err := client.Invoke("DeleteUser", userQuery, &commonResp) 65 | if err != nil { 66 | return RamCommonResponse{}, err 67 | } 68 | return commonResp, nil 69 | } 70 | 71 | func (client *RamClient) ListUsers(listParams ListUserRequest) (ListUserResponse, error) { 72 | var userList ListUserResponse 73 | err := client.Invoke("ListUsers", listParams, &userList) 74 | if err != nil { 75 | return ListUserResponse{}, err 76 | } 77 | return userList, nil 78 | } 79 | -------------------------------------------------------------------------------- /ram/account_test.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | import ( 4 | "strconv" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | var ( 10 | offset int64 = 100 11 | username = strconv.FormatInt(time.Now().Unix(), 10) 12 | user = UserRequest{ 13 | User: User{ 14 | UserName: username, 15 | DisplayName: "unit_test_account", 16 | MobilePhone: "13500000000", 17 | Email: "no-reply@alibaba-inc.com", 18 | Comments: "no any comments", 19 | }, 20 | } 21 | newUserName = strconv.FormatInt((time.Now().Unix() + offset), 10) 22 | NewUser = UpdateUserRequest{ 23 | UserName: username, 24 | NewUserName: newUserName, 25 | NewDisplayName: "unit_test_account_new", 26 | } 27 | listParams = ListUserRequest{} 28 | userQuery = UserQueryRequest{UserName: username} 29 | ) 30 | 31 | func TestCreateUser(t *testing.T) { 32 | client := NewTestClient() 33 | resp, err := client.CreateUser(user) 34 | if err != nil { 35 | t.Errorf("Failed to CreateUser %v", err) 36 | } 37 | t.Logf("pass CreateUser %v", resp) 38 | } 39 | 40 | func TestGetUser(t *testing.T) { 41 | client := NewTestClient() 42 | resp, err := client.GetUser(userQuery) 43 | if err != nil { 44 | t.Errorf("Failed to GetUser %v", err) 45 | } 46 | t.Logf("pass GetUser %v", resp) 47 | } 48 | 49 | func TestUpdateUsernewUser(t *testing.T) { 50 | client := NewTestClient() 51 | resp, err := client.UpdateUser(NewUser) 52 | if err != nil { 53 | t.Errorf("Failed to UpdateUser %v", err) 54 | } 55 | t.Logf("pass UpdateUser %v", resp) 56 | } 57 | 58 | func TestListUser(t *testing.T) { 59 | client := NewTestClient() 60 | resp, err := client.ListUsers(listParams) 61 | if err != nil { 62 | t.Errorf("Failed to ListUser %v", err) 63 | } 64 | t.Logf("pass ListUser %v", resp) 65 | } 66 | 67 | func TestDeleteUser(t *testing.T) { 68 | client := NewTestClient() 69 | userQuery.UserName = newUserName 70 | resp, err := client.DeleteUser(userQuery) 71 | if err != nil { 72 | t.Errorf("Failed to DeletUser %v", err) 73 | } 74 | t.Logf("pass DeletUser %v", resp) 75 | } 76 | -------------------------------------------------------------------------------- /ram/ak.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | /* 4 | CreateAccessKey() 5 | UpdateAccessKey() 6 | DeleteAccessKey() 7 | ListAccessKeys() 8 | */ 9 | type State string 10 | 11 | type AccessKeyResponse struct { 12 | RamCommonResponse 13 | AccessKey AccessKey 14 | } 15 | 16 | type UpdateAccessKeyRequest struct { 17 | UserAccessKeyId string 18 | Status State 19 | UserName string 20 | } 21 | 22 | type AccessKeyListResponse struct { 23 | RamCommonResponse 24 | AccessKeys struct { 25 | AccessKey []AccessKey 26 | } 27 | } 28 | 29 | func (client *RamClient) CreateAccessKey(userQuery UserQueryRequest) (AccessKeyResponse, error) { 30 | var accesskeyResp AccessKeyResponse 31 | err := client.Invoke("CreateAccessKey", userQuery, &accesskeyResp) 32 | if err != nil { 33 | return AccessKeyResponse{}, err 34 | } 35 | return accesskeyResp, nil 36 | } 37 | 38 | func (client *RamClient) UpdateAccessKey(accessKeyRequest UpdateAccessKeyRequest) (RamCommonResponse, error) { 39 | var commonResp RamCommonResponse 40 | err := client.Invoke("UpdateAccessKey", accessKeyRequest, &commonResp) 41 | if err != nil { 42 | return RamCommonResponse{}, err 43 | } 44 | return commonResp, nil 45 | } 46 | 47 | func (client *RamClient) DeleteAccessKey(accessKeyRequest UpdateAccessKeyRequest) (RamCommonResponse, error) { 48 | var commonResp RamCommonResponse 49 | err := client.Invoke("DeleteAccessKey", accessKeyRequest, &commonResp) 50 | if err != nil { 51 | return RamCommonResponse{}, err 52 | } 53 | return commonResp, nil 54 | } 55 | 56 | func (client *RamClient) ListAccessKeys(userQuery UserQueryRequest) (AccessKeyListResponse, error) { 57 | var accessKeyListResp AccessKeyListResponse 58 | err := client.Invoke("ListAccessKeys", userQuery, &accessKeyListResp) 59 | if err != nil { 60 | return AccessKeyListResponse{}, err 61 | } 62 | return accessKeyListResp, nil 63 | } 64 | -------------------------------------------------------------------------------- /ram/client.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | const ( 10 | // RAMDefaultEndpoint is the default API endpoint of RAM services 11 | RAMDefaultEndpoint = "https://ram.aliyuncs.com" 12 | RAMAPIVersion = "2015-05-01" 13 | ) 14 | 15 | type RamClient struct { 16 | common.Client 17 | } 18 | 19 | func NewClient(accessKeyId string, accessKeySecret string) RamClientInterface { 20 | return NewClientWithSecurityToken(accessKeyId, accessKeySecret, "") 21 | } 22 | 23 | func NewClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string) RamClientInterface { 24 | endpoint := os.Getenv("RAM_ENDPOINT") 25 | if endpoint == "" { 26 | endpoint = RAMDefaultEndpoint 27 | } 28 | 29 | return NewClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken) 30 | } 31 | 32 | func NewClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string) RamClientInterface { 33 | return NewClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, "") 34 | } 35 | 36 | func NewClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string) RamClientInterface { 37 | client := &RamClient{} 38 | client.WithEndpoint(endpoint). 39 | WithVersion(RAMAPIVersion). 40 | WithAccessKeyId(accessKeyId). 41 | WithAccessKeySecret(accessKeySecret). 42 | WithSecurityToken(securityToken). 43 | InitClient() 44 | return client 45 | } 46 | -------------------------------------------------------------------------------- /ram/client_test.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | /* 8 | Set your AccessKeyId and AccessKeySecret in env 9 | simply use the command below 10 | AccessKeyId=YourAccessKeyId AccessKeySecret=YourAccessKeySecret go test 11 | */ 12 | var ( 13 | AccessKeyId = os.Getenv("AccessKeyId") 14 | AccessKeySecret = os.Getenv("AccessKeySecret") 15 | ) 16 | 17 | func NewTestClient() RamClientInterface { 18 | client := NewClient(AccessKeyId, AccessKeySecret) 19 | return client 20 | } 21 | -------------------------------------------------------------------------------- /ram/error.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | //common errors 4 | var () 5 | -------------------------------------------------------------------------------- /ram/mfa.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | type MFARequest struct { 4 | VirtualMFADeviceName string 5 | } 6 | 7 | type MFADeleteRequest struct { 8 | MFADevice 9 | } 10 | 11 | type MFABindRequest struct { 12 | SerialNumber string 13 | UserName string 14 | AuthenticationCode1 string 15 | AuthenticationCode2 string 16 | } 17 | 18 | type MFAResponse struct { 19 | RamCommonResponse 20 | VirtualMFADevice VirtualMFADevice 21 | } 22 | 23 | type MFAListResponse struct { 24 | RamCommonResponse 25 | VirtualMFADevices struct { 26 | VirtualMFADevice []VirtualMFADevice 27 | } 28 | } 29 | 30 | type MFAUserResponse struct { 31 | RamCommonResponse 32 | MFADevice MFADevice 33 | } 34 | 35 | func (client *RamClient) CreateVirtualMFADevice(req MFARequest) (MFAResponse, error) { 36 | var resp MFAResponse 37 | err := client.Invoke("CreateVirtualMFADevice", req, &resp) 38 | if err != nil { 39 | return MFAResponse{}, err 40 | } 41 | return resp, nil 42 | } 43 | 44 | func (client *RamClient) ListVirtualMFADevices() (MFAListResponse, error) { 45 | var resp MFAListResponse 46 | err := client.Invoke("ListVirtualMFADevices", struct{}{}, &resp) 47 | if err != nil { 48 | return MFAListResponse{}, err 49 | } 50 | return resp, nil 51 | } 52 | 53 | func (client *RamClient) DeleteVirtualMFADevice(req MFADeleteRequest) (RamCommonResponse, error) { 54 | var resp RamCommonResponse 55 | err := client.Invoke("DeleteVirtualMFADevice", req, &resp) 56 | if err != nil { 57 | return RamCommonResponse{}, err 58 | } 59 | return resp, nil 60 | } 61 | 62 | func (client *RamClient) BindMFADevice(req MFABindRequest) (RamCommonResponse, error) { 63 | var resp RamCommonResponse 64 | err := client.Invoke("BindMFADevice", req, &resp) 65 | if err != nil { 66 | return RamCommonResponse{}, err 67 | } 68 | return resp, nil 69 | } 70 | 71 | func (client *RamClient) UnbindMFADevice(req UserQueryRequest) (MFAUserResponse, error) { 72 | var resp MFAUserResponse 73 | err := client.Invoke("UnbindMFADevice", req, &resp) 74 | if err != nil { 75 | return MFAUserResponse{}, err 76 | } 77 | return resp, nil 78 | } 79 | 80 | func (client *RamClient) GetUserMFAInfo(req UserQueryRequest) (MFAUserResponse, error) { 81 | var resp MFAUserResponse 82 | err := client.Invoke("GetUserMFAInfo", req, &resp) 83 | if err != nil { 84 | return MFAUserResponse{}, err 85 | } 86 | return resp, nil 87 | } 88 | -------------------------------------------------------------------------------- /ram/profile.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | /* 4 | CreateLoginProfile() 5 | GetLoginProfile() 6 | DeleteLoginProfile() 7 | UpdateLoginProfile() 8 | */ 9 | 10 | type ProfileRequest struct { 11 | UserName string 12 | Password string 13 | PasswordResetRequired bool 14 | MFABindRequired bool 15 | } 16 | 17 | type ProfileResponse struct { 18 | RamCommonResponse 19 | LoginProfile LoginProfile 20 | } 21 | 22 | func (client *RamClient) CreateLoginProfile(req ProfileRequest) (ProfileResponse, error) { 23 | var resp ProfileResponse 24 | err := client.Invoke("CreateLoginProfile", req, &resp) 25 | if err != nil { 26 | return ProfileResponse{}, err 27 | } 28 | return resp, nil 29 | } 30 | 31 | func (client *RamClient) GetLoginProfile(req UserQueryRequest) (ProfileResponse, error) { 32 | var resp ProfileResponse 33 | err := client.Invoke("GetLoginProfile", req, &resp) 34 | if err != nil { 35 | return ProfileResponse{}, err 36 | } 37 | return resp, nil 38 | } 39 | 40 | func (client *RamClient) DeleteLoginProfile(req UserQueryRequest) (RamCommonResponse, error) { 41 | var resp RamCommonResponse 42 | err := client.Invoke("DeleteLoginProfile", req, &resp) 43 | if err != nil { 44 | return RamCommonResponse{}, err 45 | } 46 | return resp, nil 47 | } 48 | 49 | func (client *RamClient) UpdateLoginProfile(req ProfileRequest) (ProfileResponse, error) { 50 | var resp ProfileResponse 51 | err := client.Invoke("UpdateLoginProfile", req, &resp) 52 | if err != nil { 53 | return ProfileResponse{}, err 54 | } 55 | return resp, nil 56 | } 57 | -------------------------------------------------------------------------------- /ram/profile_test.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var ( 8 | password = "hello&world" 9 | passwordNew = "hello&world&new" 10 | userName string 11 | ) 12 | 13 | func TestCreateLoginProfile(t *testing.T) { 14 | client := NewTestClient() 15 | listParams := ListUserRequest{} 16 | resp, err := client.ListUsers(listParams) 17 | if err != nil { 18 | t.Errorf("Failed to ListUser %v", err) 19 | return 20 | } 21 | userName = resp.Users.User[0].UserName 22 | profileRequest := ProfileRequest{ 23 | UserName: userName, 24 | Password: password, 25 | } 26 | response, err := client.CreateLoginProfile(profileRequest) 27 | if err != nil { 28 | t.Errorf("Failed to CreateLoginProfile %v", err) 29 | } 30 | t.Logf("pass CreateLoginProfile %v", response) 31 | } 32 | 33 | func TestGetLoginProfile(t *testing.T) { 34 | client := NewTestClient() 35 | resp, err := client.GetLoginProfile(UserQueryRequest{UserName: userName}) 36 | if err != nil { 37 | t.Errorf("Failed to GetLoginProfile %v", err) 38 | } 39 | t.Logf("pass GetLoginProfile %v", resp) 40 | } 41 | 42 | func TestUpdateLoginProfile(t *testing.T) { 43 | client := NewTestClient() 44 | profileRequest := ProfileRequest{ 45 | UserName: userName, 46 | Password: passwordNew, 47 | } 48 | resp, err := client.UpdateLoginProfile(profileRequest) 49 | if err != nil { 50 | t.Errorf("Failed to UpdateLoginProfile %v", err) 51 | } 52 | t.Logf("pass UpdateLoginProfile %v", resp) 53 | } 54 | 55 | func TestDeleteLoginProfile(t *testing.T) { 56 | client := NewTestClient() 57 | resp, err := client.DeleteLoginProfile(UserQueryRequest{UserName: userName}) 58 | if err != nil { 59 | t.Errorf("Failed to DeleteLoginProfile %v", err) 60 | } 61 | t.Logf("pass DeleteLoginProfile %v", resp) 62 | } 63 | -------------------------------------------------------------------------------- /ram/role.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | type RoleRequest struct { 4 | RoleName string 5 | AssumeRolePolicyDocument string 6 | Description string 7 | } 8 | 9 | type RoleResponse struct { 10 | RamCommonResponse 11 | Role Role 12 | } 13 | 14 | type RoleQueryRequest struct { 15 | RoleName string 16 | } 17 | 18 | type UpdateRoleRequest struct { 19 | RoleName string 20 | NewAssumeRolePolicyDocument string 21 | } 22 | 23 | type ListRoleResponse struct { 24 | RamCommonResponse 25 | Roles struct { 26 | Role []Role 27 | } 28 | } 29 | 30 | func (client *RamClient) CreateRole(role RoleRequest) (RoleResponse, error) { 31 | var roleResponse RoleResponse 32 | err := client.Invoke("CreateRole", role, &roleResponse) 33 | if err != nil { 34 | return RoleResponse{}, err 35 | } 36 | return roleResponse, nil 37 | } 38 | 39 | func (client *RamClient) GetRole(roleQuery RoleQueryRequest) (RoleResponse, error) { 40 | var roleResponse RoleResponse 41 | err := client.Invoke("GetRole", roleQuery, &roleResponse) 42 | if err != nil { 43 | return RoleResponse{}, nil 44 | } 45 | return roleResponse, nil 46 | } 47 | 48 | func (client *RamClient) UpdateRole(newRole UpdateRoleRequest) (RoleResponse, error) { 49 | var roleResponse RoleResponse 50 | err := client.Invoke("UpdateRole", newRole, &roleResponse) 51 | if err != nil { 52 | return RoleResponse{}, err 53 | } 54 | return roleResponse, nil 55 | } 56 | 57 | func (client *RamClient) ListRoles() (ListRoleResponse, error) { 58 | var roleList ListRoleResponse 59 | err := client.Invoke("ListRoles", struct{}{}, &roleList) 60 | if err != nil { 61 | return ListRoleResponse{}, err 62 | } 63 | return roleList, nil 64 | } 65 | 66 | func (client *RamClient) DeleteRole(roleQuery RoleQueryRequest) (RamCommonResponse, error) { 67 | var commonResp RamCommonResponse 68 | err := client.Invoke("DeleteRole", roleQuery, &commonResp) 69 | if err != nil { 70 | return RamCommonResponse{}, err 71 | } 72 | return commonResp, nil 73 | } 74 | -------------------------------------------------------------------------------- /ram/security.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | //TODO implement ram api about security 4 | /* 5 | SetAccountAlias() 6 | GetAccountAlias() 7 | ClearAccountAlias() 8 | SetPasswordPolicy() 9 | GetPasswordPolicy() 10 | */ 11 | type AccountAliasResponse struct { 12 | RamCommonResponse 13 | AccountAlias string 14 | } 15 | 16 | type PasswordPolicyResponse struct { 17 | RamCommonResponse 18 | PasswordPolicy 19 | } 20 | 21 | type PasswordPolicyRequest struct { 22 | PasswordPolicy 23 | } 24 | 25 | type AccountAliasRequest struct { 26 | AccountAlias string 27 | } 28 | 29 | func (client *RamClient) SetAccountAlias(accountalias AccountAliasRequest) (RamCommonResponse, error) { 30 | var resp RamCommonResponse 31 | err := client.Invoke("SetAccountAlias", accountalias, &resp) 32 | if err != nil { 33 | return RamCommonResponse{}, err 34 | } 35 | return resp, nil 36 | } 37 | 38 | func (client *RamClient) GetAccountAlias() (AccountAliasResponse, error) { 39 | var resp AccountAliasResponse 40 | err := client.Invoke("GetAccountAlias", struct{}{}, &resp) 41 | if err != nil { 42 | return AccountAliasResponse{}, err 43 | } 44 | return resp, nil 45 | } 46 | 47 | func (client *RamClient) ClearAccountAlias() (RamCommonResponse, error) { 48 | var resp RamCommonResponse 49 | err := client.Invoke("ClearAccountAlias", struct{}{}, &resp) 50 | if err != nil { 51 | return RamCommonResponse{}, err 52 | } 53 | return resp, nil 54 | } 55 | 56 | func (client *RamClient) SetPasswordPolicy(passwordPolicy PasswordPolicyRequest) (PasswordPolicyResponse, error) { 57 | var resp PasswordPolicyResponse 58 | err := client.Invoke("SetPasswordPolicy", passwordPolicy, &resp) 59 | if err != nil { 60 | return PasswordPolicyResponse{}, err 61 | } 62 | return resp, nil 63 | } 64 | 65 | func (client *RamClient) GetPasswordPolicy() (PasswordPolicyResponse, error) { 66 | var resp PasswordPolicyResponse 67 | err := client.Invoke("GetPasswordPolicy", struct{}{}, &resp) 68 | if err != nil { 69 | return PasswordPolicyResponse{}, err 70 | } 71 | return resp, nil 72 | } 73 | -------------------------------------------------------------------------------- /ram/security_test.go: -------------------------------------------------------------------------------- 1 | package ram 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var ( 8 | accountAliasRequest = AccountAliasRequest{AccountAlias: "hello"} 9 | passwordPolicy = PasswordPolicyRequest{ 10 | PasswordPolicy: PasswordPolicy{ 11 | MinimumPasswordLength: 10, 12 | RequireLowercaseCharacters: true, 13 | RequireUppercaseCharacters: true, 14 | RequireNumbers: true, 15 | RequireSymbols: true, 16 | }, 17 | } 18 | ) 19 | 20 | func TestSetAccountAlias(t *testing.T) { 21 | client := NewTestClient() 22 | resp, err := client.SetAccountAlias(accountAliasRequest) 23 | if err != nil { 24 | t.Errorf("Failed to SetAccountAlias %v", err) 25 | } 26 | t.Logf("pass SetAccountAlias %v", resp) 27 | } 28 | 29 | func TestGetAccountAlias(t *testing.T) { 30 | client := NewTestClient() 31 | resp, err := client.GetAccountAlias() 32 | if err != nil { 33 | t.Errorf("Failed to GetAccountAlias %v", err) 34 | } 35 | t.Logf("pass GetAccountAlias %v", resp) 36 | } 37 | 38 | func TestClearAccountAlias(t *testing.T) { 39 | client := NewTestClient() 40 | resp, err := client.ClearAccountAlias() 41 | if err != nil { 42 | t.Errorf("Failed to ClearAccountAlias %v", err) 43 | } 44 | t.Logf("pass ClearAccountAlias %v", resp) 45 | } 46 | 47 | func TestSetPasswordPolicy(t *testing.T) { 48 | client := NewTestClient() 49 | resp, err := client.SetPasswordPolicy(passwordPolicy) 50 | if err != nil { 51 | t.Errorf("Failed to pass SetPasswordPolicy %v", err) 52 | } 53 | t.Logf("pass SetPasswordPolicy %v", resp) 54 | } 55 | 56 | func TestGetPasswordPolicy(t *testing.T) { 57 | client := NewTestClient() 58 | resp, err := client.GetPasswordPolicy() 59 | if err != nil { 60 | t.Errorf("Failed to pass GetPasswordPolicy %v", err) 61 | } 62 | t.Logf("pass GetPasswordPolicy %v", resp) 63 | } 64 | -------------------------------------------------------------------------------- /rds/config_test.go: -------------------------------------------------------------------------------- 1 | package rds 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | //Modify with your Access Key Id and Access Key Secret 10 | 11 | var ( 12 | TestAccessKeyId = os.Getenv("AccessKeyId") 13 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 14 | TestSecurityToken = os.Getenv("SecurityToken") 15 | TestRegionID = common.Region(os.Getenv("RegionId")) 16 | 17 | ZoneId = "MY_TEST_ZONE_ID" 18 | VPCId = "MY_TEST_VPC_ID" 19 | VSwitchId = "MY_TEST_VSWITCH_ID" 20 | DBInstanceId = "MY_TEST_INSTANCE_ID" 21 | DBName = "MY_TEST_DB_NAME" 22 | AccountPassword = "MY_TEST_ACCOUNT_PWD" 23 | AccountName = "MY_TEST_ACCOUNT_NAME" 24 | EngineVersion = "MY_TEST_ENGINE_VERSION" 25 | DBInstanceClass = "MY_TEST_DB_CLASS" 26 | DBInstanceUpgradeId = "MY_TEST_INSTANCE_TO_UPGRADE" 27 | DBInstanceUpgradeClass = "MY_TEST_DB_CLASS_TO_UPGRADE" 28 | TestIAmRich = false 29 | ) 30 | 31 | var testClient *Client 32 | 33 | func NewTestClient() *Client { 34 | if testClient == nil { 35 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 36 | } 37 | return testClient 38 | } 39 | 40 | var testDebugClient *Client 41 | 42 | func NewTestClientForDebug() *Client { 43 | if testDebugClient == nil { 44 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 45 | testDebugClient.SetDebug(true) 46 | } 47 | return testDebugClient 48 | } 49 | -------------------------------------------------------------------------------- /rds/monitoring.go: -------------------------------------------------------------------------------- 1 | package rds 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | "github.com/denverdino/aliyungo/util" 6 | ) 7 | 8 | type DescribeDBInstancePerformanceArgs struct { 9 | DBInstanceId string 10 | Key string 11 | StartTime string 12 | EndTime string 13 | } 14 | 15 | type PerformanceValueType struct { 16 | Value string 17 | Date util.ISO6801Time 18 | } 19 | 20 | type PerformanceKeyType struct { 21 | Key string 22 | Unit string 23 | ValueFormat string 24 | Values struct { 25 | PerformanceValue []PerformanceValueType 26 | } 27 | } 28 | 29 | type DescribeDBInstancePerformanceResponse struct { 30 | common.Response 31 | DBInstanceId string 32 | Engine string 33 | StartTime util.ISO6801Time 34 | EndTime util.ISO6801Time 35 | PerformanceKeys struct { 36 | PerformanceKey []PerformanceKeyType 37 | } 38 | } 39 | 40 | func (client *DescribeDBInstancePerformanceArgs) Setkey(key string) { 41 | client.Key = key 42 | } 43 | 44 | func (client *Client) DescribeDBInstancePerformance(args *DescribeDBInstancePerformanceArgs) (resp DescribeDBInstancePerformanceResponse, err error) { 45 | 46 | response := DescribeDBInstancePerformanceResponse{} 47 | err = client.Invoke("DescribeDBInstancePerformance", args, &response) 48 | return response, err 49 | 50 | } 51 | -------------------------------------------------------------------------------- /ros/config_test.go: -------------------------------------------------------------------------------- 1 | package ros 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | //Modify with your Access Key Id and Access Key Secret 10 | 11 | var ( 12 | TestAccessKeyId = os.Getenv("AccessKeyId") 13 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 14 | TestSecurityToken = os.Getenv("SecurityToken") 15 | TestRegionID = common.Region(os.Getenv("RegionId")) 16 | 17 | debugClientForTestCase = NewTestClientForDebug() 18 | debugRpcClientForTestCase = NewTestRpcClientForDebug() 19 | ) 20 | 21 | var testClient *Client 22 | 23 | func NewTestClient() *Client { 24 | if testClient == nil { 25 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 26 | } 27 | testClient.SetSecurityToken(TestSecurityToken) 28 | return testClient 29 | } 30 | 31 | var testDebugClient *Client 32 | var testDebugRpcClient *RpcClient 33 | 34 | func NewTestClientForDebug() *Client { 35 | if testDebugClient == nil { 36 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 37 | testDebugClient.SetDebug(true) 38 | } 39 | testDebugClient.SetSecurityToken(TestSecurityToken) 40 | return testDebugClient 41 | } 42 | 43 | func NewTestRpcClientForDebug() *RpcClient { 44 | if testDebugRpcClient == nil { 45 | testDebugRpcClient = NewRpcClient(TestAccessKeyId, TestAccessKeySecret) 46 | testDebugRpcClient.SetDebug(true) 47 | } 48 | testDebugRpcClient.SetSecurityToken(TestSecurityToken) 49 | return testDebugRpcClient 50 | } 51 | -------------------------------------------------------------------------------- /ros/other.go: -------------------------------------------------------------------------------- 1 | package ros 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | 7 | "github.com/denverdino/aliyungo/common" 8 | "github.com/denverdino/aliyungo/util" 9 | ) 10 | 11 | //https://help.aliyun.com/document_detail/28925.html?spm=5176.doc28923.6.597.Wktzdg 12 | type DescribeEventsRequest struct { 13 | ResourceStatus string 14 | ResourceName string 15 | ResourceType string 16 | PageNumber int 17 | PageSize int 18 | } 19 | 20 | type Event struct { 21 | Status string 22 | ResourceStatus string 23 | ResourceName string 24 | StatusReason string 25 | Id string 26 | ResourceId string 27 | ResourceType string 28 | ResourcePhysicalId string 29 | Time string 30 | } 31 | 32 | type DescribeEventsResponse struct { 33 | common.Response 34 | TotalCount int 35 | PageNumber int 36 | PageSize int 37 | Events []Event 38 | } 39 | 40 | func (client *Client) DescribeEvents(stackId, stackName string, args *DescribeEventsRequest) (*DescribeEventsResponse, error) { 41 | response := &DescribeEventsResponse{} 42 | query := util.ConvertToQueryValues(args) 43 | err := client.Invoke("", http.MethodGet, fmt.Sprintf("/stacks/%s/%s/events", stackName, stackId), query, nil, response) 44 | if err != nil { 45 | return nil, err 46 | } 47 | 48 | return response, nil 49 | } 50 | 51 | //https://help.aliyun.com/document_detail/50086.html?spm=5176.doc28910.6.598.ngYYj6 52 | type Region struct { 53 | LocalName string 54 | RegionId string 55 | } 56 | 57 | type DescribeRegionsResponse struct { 58 | common.Response 59 | Regions []Region 60 | } 61 | 62 | func (client *Client) DescribeRegions() (*DescribeRegionsResponse, error) { 63 | response := &DescribeRegionsResponse{} 64 | err := client.Invoke("", http.MethodGet, "/regions", nil, nil, response) 65 | if err != nil { 66 | return nil, err 67 | } 68 | 69 | return response, nil 70 | } 71 | -------------------------------------------------------------------------------- /ros/other_test.go: -------------------------------------------------------------------------------- 1 | package ros 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | func TestClient_DescribeEvents(t *testing.T) { 9 | stackName := os.Getenv("StackName") 10 | stackId := os.Getenv("StackId") 11 | 12 | response, err := debugClientForTestCase.DescribeEvents(stackId, stackName, &DescribeEventsRequest{}) 13 | if err != nil { 14 | t.Fatalf("Failed to DescribeEvents %++v", err) 15 | } else { 16 | t.Logf("Resource = %++v", response) 17 | } 18 | } 19 | 20 | func TestClient_DescribeRegions(t *testing.T) { 21 | response, err := debugClientForTestCase.DescribeRegions() 22 | if err != nil { 23 | t.Fatalf("Failed to DescribeRegions %++v", err) 24 | } else { 25 | t.Logf("Regions = %++v", response) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ros/resource_test.go: -------------------------------------------------------------------------------- 1 | package ros 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | func TestClient_DescribeResources(t *testing.T) { 9 | stackName := os.Getenv("StackName") 10 | stackId := os.Getenv("StackId") 11 | 12 | response, err := debugClientForTestCase.DescribeResources(stackId, stackName) 13 | if err != nil { 14 | t.Fatalf("Failed to DescribeResources %++v", err) 15 | } else { 16 | for index, item := range response { 17 | t.Logf("item[%d] = %++v", index, item) 18 | } 19 | } 20 | } 21 | 22 | func TestClient_DescribeResource(t *testing.T) { 23 | stackName := os.Getenv("StackName") 24 | stackId := os.Getenv("StackId") 25 | resourceName := os.Getenv("ResourceName") 26 | 27 | response, err := debugClientForTestCase.DescribeResource(stackId, stackName, resourceName) 28 | if err != nil { 29 | t.Fatalf("Failed to DescribeResource %++v", err) 30 | } else { 31 | t.Logf("Resource = %++v", response) 32 | } 33 | } 34 | 35 | func TestClient_DescribeResoureTypes(t *testing.T) { 36 | 37 | response, err := debugClientForTestCase.DescribeResoureTypes("") 38 | if err != nil { 39 | t.Fatalf("Failed to DescribeResoureTypes %++v", err) 40 | } else { 41 | t.Logf("Resource = %++v", response) 42 | } 43 | } 44 | 45 | func TestClient_DescribeResoureType(t *testing.T) { 46 | resouceType := os.Getenv("ResourceType") 47 | response, err := debugClientForTestCase.DescribeResoureType(resouceType) 48 | if err != nil { 49 | t.Fatalf("Failed to DescribeResoureType %++v", err) 50 | } else { 51 | t.Logf("Resource = %++v", response) 52 | } 53 | } 54 | 55 | func TestClient_DescribeResoureTypeTemplate(t *testing.T) { 56 | resouceType := os.Getenv("ResourceType") 57 | response, err := debugClientForTestCase.DescribeResoureTypeTemplate(resouceType) 58 | if err != nil { 59 | t.Fatalf("Failed to DescribeResoureTypeTemplate %++v", err) 60 | } else { 61 | t.Logf("Resource = %++v", response) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ros/rpc_client.go: -------------------------------------------------------------------------------- 1 | package ros 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | "os" 6 | ) 7 | 8 | const ( 9 | ROS_RPC_APIVersion = "2019-09-10" 10 | ROSServiceCode = "ros" 11 | ) 12 | 13 | type RpcClient struct { 14 | common.Client 15 | } 16 | 17 | func NewRpcClient(accessKeyId, accessKeySecret string) *RpcClient { 18 | endpoint := os.Getenv("ROS_ENDPOINT") 19 | if endpoint == "" { 20 | endpoint = ROSDefaultEndpoint 21 | } 22 | return NewRpcClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) 23 | } 24 | 25 | func NewRpcClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string) *RpcClient { 26 | client := &RpcClient{} 27 | client.Init(endpoint, ROS_RPC_APIVersion, accessKeyId, accessKeySecret) 28 | return client 29 | } 30 | 31 | func NewRosRpcClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *RpcClient { 32 | endpoint := os.Getenv("ROS_ENDPOINT") 33 | if endpoint == "" { 34 | endpoint = ROSDefaultEndpoint 35 | } 36 | 37 | return NewRosRpcClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken, regionID) 38 | } 39 | 40 | func NewRosRpcClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string, regionID common.Region) *RpcClient { 41 | client := &RpcClient{} 42 | client.WithEndpoint(endpoint). 43 | WithVersion(ROS_RPC_APIVersion). 44 | WithAccessKeyId(accessKeyId). 45 | WithAccessKeySecret(accessKeySecret). 46 | WithSecurityToken(securityToken). 47 | WithServiceCode(ROSServiceCode). 48 | WithRegionID(regionID). 49 | InitClient() 50 | return client 51 | } 52 | -------------------------------------------------------------------------------- /ros/signature.go: -------------------------------------------------------------------------------- 1 | package ros 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "sort" 7 | "strings" 8 | 9 | "github.com/denverdino/aliyungo/util" 10 | ) 11 | 12 | func (client *Client) signRequest(request *http.Request) { 13 | 14 | headers := request.Header 15 | contentMd5 := headers.Get("Content-Md5") 16 | contentType := headers.Get("Content-Type") 17 | accept := headers.Get("Accept") 18 | date := headers.Get("Date") 19 | 20 | canonicalizedResource := request.URL.RequestURI() 21 | 22 | _, canonicalizedHeader := canonicalizeHeader(headers) 23 | 24 | stringToSign := request.Method + "\n" + accept + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedHeader + canonicalizedResource 25 | if client.debug { 26 | log.Println("stringToSign: ", stringToSign) 27 | } 28 | signature := util.CreateSignature(stringToSign, client.AccessKeySecret) 29 | headers.Set("Authorization", "acs "+client.AccessKeyId+":"+signature) 30 | } 31 | 32 | const headerOSSPrefix = "x-acs-" 33 | 34 | //Have to break the abstraction to append keys with lower case. 35 | func canonicalizeHeader(headers http.Header) (newHeaders http.Header, result string) { 36 | var canonicalizedHeaders []string 37 | newHeaders = http.Header{} 38 | 39 | for k, v := range headers { 40 | if lower := strings.ToLower(k); strings.HasPrefix(lower, headerOSSPrefix) { 41 | newHeaders[lower] = v 42 | canonicalizedHeaders = append(canonicalizedHeaders, lower) 43 | } else { 44 | newHeaders[k] = v 45 | } 46 | } 47 | 48 | sort.Strings(canonicalizedHeaders) 49 | 50 | var canonicalizedHeader string 51 | 52 | for _, k := range canonicalizedHeaders { 53 | v := "" 54 | if len(headers[k]) > 0 { 55 | v = headers[k][0] 56 | } 57 | canonicalizedHeader += k + ":" + v + "\n" 58 | } 59 | 60 | return newHeaders, canonicalizedHeader 61 | } 62 | -------------------------------------------------------------------------------- /ros/standard/client.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | 6 | "os" 7 | ) 8 | 9 | type Client struct { 10 | common.Client 11 | } 12 | 13 | const ( 14 | // ROSDefaultEndpoint is the default API endpoint of ESS services 15 | ROSDefaultEndpoint = "https://ros.aliyuncs.com" 16 | ROSAPIVersion = "2019-09-10" 17 | ROSServiceCode = "ros" 18 | ) 19 | 20 | // NewClient creates a new instance of RDS client 21 | func NewClient(accessKeyId, accessKeySecret string) *Client { 22 | endpoint := os.Getenv("ROS_ENDPOINT") 23 | if endpoint == "" { 24 | endpoint = ROSDefaultEndpoint 25 | } 26 | return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret) 27 | } 28 | 29 | func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client { 30 | client := &Client{} 31 | client.Init(endpoint, ROSAPIVersion, accessKeyId, accessKeySecret) 32 | return client 33 | } 34 | 35 | func NewROSClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client { 36 | endpoint := os.Getenv("ROS_ENDPOINT") 37 | if endpoint == "" { 38 | endpoint = ROSDefaultEndpoint 39 | } 40 | 41 | return NewClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID) 42 | } 43 | 44 | func NewClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client { 45 | client := &Client{} 46 | client.NewInit(endpoint, ROSAPIVersion, accessKeyId, accessKeySecret, ROSServiceCode, regionID) 47 | return client 48 | } 49 | -------------------------------------------------------------------------------- /ros/standard/client_test.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | import ( 4 | "fmt" 5 | "github.com/denverdino/aliyungo/common" 6 | "testing" 7 | ) 8 | 9 | const ( 10 | TestAccessKeyId = "" 11 | TestAccessKeySecret = "" 12 | Region = common.Shanghai 13 | StackID = "c7f1fed9-0104-4596-aae6-aa5215f5a793" 14 | ) 15 | 16 | func NewTestClient() *Client { 17 | return NewROSClient(TestAccessKeyId, TestAccessKeySecret, Region) 18 | } 19 | 20 | func TestGetStack(t *testing.T) { 21 | 22 | client := NewTestClient() 23 | req := GetStackRequest{ 24 | RegionId: Region, 25 | StackId: StackID, 26 | } 27 | res, err := client.GetStack(&req) 28 | if err != nil { 29 | t.Fail() 30 | } 31 | fmt.Printf("Response: %+v\n", res) 32 | } 33 | 34 | func TestListStack(t *testing.T) { 35 | client := NewTestClient() 36 | req := &ListStacksRequest{} 37 | res, err := client.ListStacks(req) 38 | if err != nil { 39 | t.Fail() 40 | } 41 | fmt.Printf("ListResponse: %+v\n", res) 42 | } 43 | 44 | func TestListStackEvent(t *testing.T) { 45 | client := NewTestClient() 46 | req := &ListStackEventsRequest{ 47 | StackId: StackID, 48 | } 49 | res, err := client.ListStackEvents(req) 50 | if err != nil { 51 | t.Fail() 52 | } 53 | fmt.Printf("ListEventResponse: %+v\n", res) 54 | } 55 | 56 | func TestCreateStack(t *testing.T) { 57 | client := NewTestClient() 58 | req := &CreateStackRequest{ 59 | StackName: "TDDDDDDD", 60 | TemplateBody: tpl, 61 | DisableRollback: true, 62 | TimeoutInMinutes: 60, 63 | Parameters: []Parameter{ 64 | {ParameterKey: "SystemDisk", ParameterValue: ""}, 65 | }, 66 | } 67 | res, err := client.CreateStack(req) 68 | if err != nil { 69 | t.Logf("create stack: %s", err.Error()) 70 | t.Fail() 71 | } 72 | fmt.Printf("ListEventResponse: %+v\n", res) 73 | } 74 | 75 | var tpl = ` 76 | 77 | ` 78 | -------------------------------------------------------------------------------- /ros/template.go: -------------------------------------------------------------------------------- 1 | package ros 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | 7 | "github.com/denverdino/aliyungo/common" 8 | ) 9 | 10 | //https://help.aliyun.com/document_detail/28922.html?spm=5176.doc28920.6.594.UI5p6A 11 | type DescribeTemplateResponse struct { 12 | common.Response 13 | ROSTemplateFormatVersion string 14 | Parameters interface{} 15 | Outputs interface{} 16 | Resources interface{} 17 | Description interface{} 18 | Conditions interface{} 19 | Mappings interface{} 20 | Metadata interface{} 21 | } 22 | 23 | func (client *Client) DescribeTemplate(stackId, stackName string) (*DescribeTemplateResponse, error) { 24 | response := &DescribeTemplateResponse{} 25 | err := client.Invoke("", http.MethodGet, fmt.Sprintf("/stacks/%s/%s/template", stackName, stackId), nil, nil, response) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | return response, nil 31 | } 32 | 33 | //https://help.aliyun.com/document_detail/28923.html?spm=5176.doc28922.6.595.uhWWET 34 | type ValidateTemplateRequest struct { 35 | Template string 36 | } 37 | 38 | type ValidateTemplateResponse struct { 39 | common.Response 40 | Parameters interface{} 41 | Description interface{} 42 | } 43 | 44 | func (client *Client) ValidateTemplate(args *ValidateTemplateRequest) (*ValidateTemplateResponse, error) { 45 | response := &ValidateTemplateResponse{} 46 | err := client.Invoke("", http.MethodPost, "/validate", nil, args, response) 47 | if err != nil { 48 | return nil, err 49 | } 50 | 51 | return response, nil 52 | } 53 | -------------------------------------------------------------------------------- /ros/template_test.go: -------------------------------------------------------------------------------- 1 | package ros 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | func TestClient_DescribeTemplate(t *testing.T) { 9 | stackName := os.Getenv("StackName") 10 | stackId := os.Getenv("StackId") 11 | 12 | response, err := debugClientForTestCase.DescribeTemplate(stackId, stackName) 13 | if err != nil { 14 | t.Fatalf("Failed to DescribeTemplate %++v", err) 15 | } else { 16 | t.Logf("Resource = %++v", response.Mappings) 17 | } 18 | } 19 | 20 | func TestClient_ValidateTemplate(t *testing.T) { 21 | args := &ValidateTemplateRequest{ 22 | Template: myTestTemplate, 23 | } 24 | response, err := debugClientForTestCase.ValidateTemplate(args) 25 | if err != nil { 26 | t.Fatalf("Failed to ValidateTemplate %++v", err) 27 | } else { 28 | t.Logf("Result = %++v", response) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /slb/config_test.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | //Modify with your Access Key Id and Access Key Secret 10 | 11 | var ( 12 | TestAccessKeyId = os.Getenv("AccessKeyId") 13 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 14 | TestSecurityToken = os.Getenv("SecurityToken") 15 | TestLoadBlancerID = "MY_LOADBALANCEID" 16 | TestVServerGroupID = "MY_VSERVER_GROUPID" 17 | TestListenerPort = 9000 18 | TestInstanceId = "MY_INSTANCE_ID" 19 | TestENIId = "MY_ENI_ID" 20 | TestRegionID = common.Region(os.Getenv("RegionId")) 21 | TestIAmRich = false 22 | TestQuick = false 23 | ) 24 | 25 | var testClient *Client 26 | 27 | func NewTestClient() *Client { 28 | if testClient == nil { 29 | testClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 30 | } 31 | return testClient 32 | } 33 | 34 | var testDebugClient *Client 35 | 36 | func NewTestClientForDebug() *Client { 37 | if testDebugClient == nil { 38 | testDebugClient = NewClient(TestAccessKeyId, TestAccessKeySecret) 39 | testDebugClient.SetDebug(true) 40 | } 41 | return testDebugClient 42 | } 43 | 44 | var testDebugNewSLBClient *Client 45 | 46 | func NewTestNewSLBClientForDebug() *Client { 47 | if testDebugNewSLBClient == nil { 48 | testDebugNewSLBClient = NewSLBClientWithSecurityToken4RegionalDomain(TestAccessKeyId, TestAccessKeySecret, TestSecurityToken, TestRegionID) 49 | testDebugNewSLBClient.SetDebug(true) 50 | } 51 | return testDebugNewSLBClient 52 | } 53 | -------------------------------------------------------------------------------- /slb/listerners_test.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | func testListeners(t *testing.T, client *Client, loadBalancerId string) { 11 | 12 | port := 1234 13 | 14 | creationArgs := CreateLoadBalancerTCPListenerArgs{ 15 | LoadBalancerId: loadBalancerId, 16 | ListenerPort: port, 17 | BackendServerPort: 1234, 18 | Bandwidth: -1, 19 | } 20 | 21 | err := client.CreateLoadBalancerTCPListener(&creationArgs) 22 | if err != nil { 23 | t.Errorf("Failed to CreateLoadBalancerTCPListener: %v", err) 24 | } 25 | 26 | response, err := client.DescribeLoadBalancerTCPListenerAttribute(loadBalancerId, port) 27 | if err != nil { 28 | t.Errorf("Failed to DescribeLoadBalancerTCPListenerAttribute: %v", err) 29 | } 30 | t.Logf("Listener: %++v", *response) 31 | 32 | err = client.StartLoadBalancerListener(loadBalancerId, port) 33 | if err != nil { 34 | t.Errorf("Failed to StartLoadBalancerListener: %v", err) 35 | } 36 | 37 | status, err := client.WaitForListener(loadBalancerId, port, TCP) 38 | if err != nil { 39 | t.Errorf("Failed to WaitForListener: %v", err) 40 | } 41 | t.Logf("Listener status: %s", status) 42 | 43 | response, err = client.DescribeLoadBalancerTCPListenerAttribute(loadBalancerId, port) 44 | if err != nil { 45 | t.Errorf("Failed to DescribeLoadBalancerTCPListenerAttribute: %v", err) 46 | } 47 | t.Logf("Listener: %++v", *response) 48 | } 49 | 50 | func TestDescribeListener(t *testing.T) { 51 | 52 | response, err := client.DescribeLoadBalancerTCPListenerAttribute(loadBalancerId, 22) 53 | if err != nil { 54 | t.Error(err) 55 | } else { 56 | fmt.Println(PrettyJson(response)) 57 | } 58 | } 59 | 60 | func TestDescribeSLB(t *testing.T) { 61 | 62 | response, err := client.DescribeLoadBalancerAttribute(loadBalancerId) 63 | if err != nil { 64 | t.Error(err) 65 | } else { 66 | fmt.Println(PrettyJson(response)) 67 | } 68 | } 69 | 70 | func PrettyJson(obj interface{}) string { 71 | pretty := bytes.Buffer{} 72 | data, err := json.Marshal(obj) 73 | if err != nil { 74 | return err.Error() 75 | } 76 | err = json.Indent(&pretty, data, "", " ") 77 | 78 | if err != nil { 79 | return err.Error() 80 | } 81 | 82 | return pretty.String() 83 | } 84 | -------------------------------------------------------------------------------- /slb/regions.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type DescribeRegionsArgs struct { 6 | } 7 | 8 | // 9 | // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype®iontype 10 | type RegionType struct { 11 | RegionId common.Region 12 | LocalName string 13 | } 14 | 15 | type DescribeRegionsResponse struct { 16 | common.Response 17 | Regions struct { 18 | Region []RegionType 19 | } 20 | } 21 | 22 | // DescribeRegions describes regions 23 | // 24 | // You can read doc at http://docs.aliyun.com/#/pub/slb/api-reference/api-related-loadbalancer&DescribeRegions 25 | func (client *Client) DescribeRegions() (regions []RegionType, err error) { 26 | response := DescribeRegionsResponse{} 27 | 28 | err = client.Invoke("DescribeRegions", &DescribeRegionsArgs{}, &response) 29 | 30 | if err != nil { 31 | return []RegionType{}, err 32 | } 33 | return response.Regions.Region, nil 34 | } 35 | -------------------------------------------------------------------------------- /slb/regions_test.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import "testing" 4 | 5 | func TestDescribeRegions(t *testing.T) { 6 | 7 | client := NewTestNewSLBClientForDebug() 8 | 9 | regions, err := client.DescribeRegions() 10 | 11 | if err == nil { 12 | t.Logf("regions: %v", regions) 13 | } else { 14 | t.Errorf("Failed to DescribeRegions: %v", err) 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /slb/servers_test.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import "testing" 4 | 5 | func testBackendServers(t *testing.T, client *Client, loadBalancerId string) { 6 | 7 | backendServers := []BackendServerType{ 8 | { 9 | ServerId: TestInstanceId, 10 | Weight: 100, 11 | Type: "ecs", 12 | }, 13 | //BackendServerType{ 14 | // ServerId: TestENIId, 15 | // Weight: 100, 16 | // Type: "eni", 17 | //}, 18 | } 19 | 20 | servers, err := client.AddBackendServers(loadBalancerId, backendServers) 21 | 22 | if err != nil { 23 | t.Errorf("Failed to AddBackendServers: %v", err) 24 | } 25 | 26 | t.Logf("Backend servers: %++v", servers) 27 | 28 | backendServers[0].Weight = 80 29 | 30 | servers, err = client.SetBackendServers(loadBalancerId, backendServers) 31 | 32 | if err != nil { 33 | t.Errorf("Failed to SetBackendServers: %v", err) 34 | } 35 | 36 | t.Logf("Backend servers: %++v", servers) 37 | 38 | servers, err = client.RemoveBackendServers(loadBalancerId, backendServers) 39 | if err != nil { 40 | t.Errorf("Failed to RemoveBackendServers: %v", err) 41 | } 42 | t.Logf("Backend servers: %++v", servers) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /slb/tags.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type TagItem struct { 6 | TagKey string 7 | TagValue string 8 | } 9 | 10 | type AddTagsArgs struct { 11 | RegionId common.Region 12 | LoadBalancerID string 13 | Tags string 14 | } 15 | 16 | type AddTagsResponse struct { 17 | common.Response 18 | } 19 | 20 | // AddTags Add tags to resource 21 | // 22 | // You can read doc at https://help.aliyun.com/document_detail/42871.html 23 | func (client *Client) AddTags(args *AddTagsArgs) error { 24 | response := AddTagsResponse{} 25 | err := client.Invoke("AddTags", args, &response) 26 | if err != nil { 27 | return err 28 | } 29 | return err 30 | } 31 | 32 | type RemoveTagsArgs struct { 33 | RegionId common.Region 34 | LoadBalancerID string 35 | Tags string 36 | } 37 | 38 | type RemoveTagsResponse struct { 39 | common.Response 40 | } 41 | 42 | // RemoveTags remove tags to resource 43 | // 44 | // You can read doc at https://help.aliyun.com/document_detail/42872.html 45 | func (client *Client) RemoveTags(args *RemoveTagsArgs) error { 46 | response := RemoveTagsResponse{} 47 | err := client.Invoke("RemoveTags", args, &response) 48 | if err != nil { 49 | return err 50 | } 51 | return err 52 | } 53 | 54 | type TagItemType struct { 55 | TagItem 56 | InstanceCount int 57 | } 58 | 59 | type DescribeTagsArgs struct { 60 | RegionId common.Region 61 | LoadBalancerID string 62 | Tags string 63 | common.Pagination 64 | } 65 | 66 | type DescribeTagsResponse struct { 67 | common.Response 68 | common.PaginationResult 69 | TagSets struct { 70 | TagSet []TagItemType 71 | } 72 | } 73 | 74 | // DescribeResourceByTags describe resource by tags 75 | // 76 | // You can read doc at https://help.aliyun.com/document_detail/42873.html?spm=5176.doc42872.6.267.CP1iWu 77 | func (client *Client) DescribeTags(args *DescribeTagsArgs) (tags []TagItemType, pagination *common.PaginationResult, err error) { 78 | args.Validate() 79 | response := DescribeTagsResponse{} 80 | err = client.Invoke("DescribeTags", args, &response) 81 | if err != nil { 82 | return nil, nil, err 83 | } 84 | return response.TagSets.TagSet, &response.PaginationResult, nil 85 | } 86 | -------------------------------------------------------------------------------- /slb/tags_test.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/denverdino/aliyungo/common" 8 | ) 9 | 10 | func TestAddTags(t *testing.T) { 11 | client := NewTestClientForDebug() 12 | 13 | tagItemArr := []TagItem{ 14 | {TagKey: "username", TagValue: "test"}, 15 | {TagKey: "birdthday", TagValue: "20170101"}, 16 | } 17 | tagItems, _ := json.Marshal(tagItemArr) 18 | 19 | args := &AddTagsArgs{ 20 | RegionId: common.Beijing, 21 | LoadBalancerID: TestLoadBlancerID, 22 | Tags: string(tagItems), 23 | } 24 | 25 | err := client.AddTags(args) 26 | if err != nil { 27 | t.Fatalf("Failed to add tags %++v", err) 28 | } 29 | 30 | t.Logf("Successfully to add tags") 31 | } 32 | 33 | func TestRemoveTags(t *testing.T) { 34 | client := NewTestClientForDebug() 35 | 36 | tagItemArr := []TagItem{ 37 | {TagKey: "username", TagValue: "test"}, 38 | {TagKey: "birdthday", TagValue: "20170101"}, 39 | } 40 | tagItems, _ := json.Marshal(tagItemArr) 41 | 42 | args := &RemoveTagsArgs{ 43 | RegionId: common.Beijing, 44 | LoadBalancerID: TestLoadBlancerID, 45 | Tags: string(tagItems), 46 | } 47 | 48 | err := client.RemoveTags(args) 49 | if err != nil { 50 | t.Fatalf("Failed to remove tags %++v", err) 51 | } 52 | 53 | t.Logf("Successfully to remove tags") 54 | } 55 | 56 | func TestDescribeTags(t *testing.T) { 57 | client := NewTestClientForDebug() 58 | 59 | args := &DescribeTagsArgs{ 60 | RegionId: common.Beijing, 61 | LoadBalancerID: TestLoadBlancerID, 62 | } 63 | 64 | tags, _, err := client.DescribeTags(args) 65 | if err != nil { 66 | t.Fatalf("Failed to describe tags %++v", err) 67 | } 68 | 69 | t.Logf("tags is %++v", tags) 70 | } 71 | -------------------------------------------------------------------------------- /slb/zones.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | ) 6 | 7 | type DescribeZonesArgs struct { 8 | RegionId common.Region 9 | } 10 | 11 | // 12 | // You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&zonetype 13 | type ZoneType struct { 14 | ZoneId string 15 | LocalName string 16 | SlaveZones struct { 17 | SlaveZone []ZoneType 18 | } 19 | } 20 | 21 | type DescribeZonesResponse struct { 22 | common.Response 23 | Zones struct { 24 | Zone []ZoneType 25 | } 26 | } 27 | 28 | // DescribeZones describes zones 29 | func (client *Client) DescribeZones(regionId common.Region) (zones []ZoneType, err error) { 30 | response, err := client.DescribeZonesWithRaw(regionId) 31 | if err == nil { 32 | return response.Zones.Zone, nil 33 | } 34 | 35 | return []ZoneType{}, err 36 | } 37 | 38 | func (client *Client) DescribeZonesWithRaw(regionId common.Region) (response *DescribeZonesResponse, err error) { 39 | args := DescribeZonesArgs{ 40 | RegionId: regionId, 41 | } 42 | response = &DescribeZonesResponse{} 43 | 44 | err = client.Invoke("DescribeZones", &args, response) 45 | 46 | if err == nil { 47 | return response, nil 48 | } 49 | 50 | return nil, err 51 | } 52 | -------------------------------------------------------------------------------- /slb/zones_test.go: -------------------------------------------------------------------------------- 1 | package slb 2 | 3 | import ( 4 | "github.com/denverdino/aliyungo/common" 5 | "testing" 6 | ) 7 | 8 | func TestDescribeZones(t *testing.T) { 9 | 10 | client := NewTestNewSLBClientForDebug() 11 | 12 | zones, err := client.DescribeZones(common.Hangzhou) 13 | 14 | if err == nil { 15 | t.Logf("regions: %v", zones) 16 | } else { 17 | t.Errorf("Failed to DescribeZones: %v", err) 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /sls/client_test.go: -------------------------------------------------------------------------------- 1 | package sls 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/denverdino/aliyungo/common" 8 | ) 9 | 10 | var ( 11 | TestAccessKeyId = os.Getenv("AccessKeyId") 12 | TestAccessKeySecret = os.Getenv("AccessKeySecret") 13 | TestSecurityToken = os.Getenv("SecurityToken") 14 | TestRegionID = common.Region(os.Getenv("RegionId")) 15 | TestMachineGroup = os.Getenv("MachineGroup") 16 | Region = common.Hangzhou 17 | TestProjectName = os.Getenv("ProjectName") 18 | TestLogstoreName = "test-logstore" 19 | ) 20 | 21 | func DefaultProject(t *testing.T) *Project { 22 | client := NewClient(Region, false, TestAccessKeyId, TestAccessKeySecret) 23 | err := client.CreateProject(TestProjectName, "description") 24 | if err != nil { 25 | if e, ok := err.(*Error); ok && e.Code != "ProjectAlreadyExist" { 26 | t.Fatalf("create project fail: %s", err.Error()) 27 | } 28 | } 29 | p, err := client.Project(TestProjectName) 30 | if err != nil { 31 | t.Fatalf("get project fail: %s", err.Error()) 32 | } 33 | //Create default logstore 34 | 35 | logstore := &Logstore{ 36 | TTL: 2, 37 | Shard: 3, 38 | Name: TestLogstoreName, 39 | } 40 | err = p.CreateLogstore(logstore) 41 | if err != nil { 42 | if e, ok := err.(*Error); ok && e.Code != "LogStoreAlreadyExist" { 43 | t.Fatalf("create logstore fail: %s", err.Error()) 44 | } 45 | } 46 | 47 | return p 48 | } 49 | 50 | var testDebugClient *Client 51 | 52 | func NewTestClientForDebug() *Client { 53 | if testDebugClient == nil { 54 | testDebugClient = NewClientForAssumeRole(TestRegionID, false, TestAccessKeyId, TestAccessKeySecret, TestSecurityToken) 55 | testDebugClient.SetDebug(true) 56 | } 57 | return testDebugClient 58 | } 59 | -------------------------------------------------------------------------------- /sls/index_test.go: -------------------------------------------------------------------------------- 1 | package sls 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestCreateIndex(t *testing.T) { 10 | p := DefaultProject(t) 11 | config := &IndexConfig{ 12 | TTL: 7, 13 | LineConfig: &IndexLineConfig{ 14 | TokenList: []string{",", "\t", "\n", " ", ";"}, 15 | CaseSensitive: false, 16 | }, 17 | } 18 | if err := p.CreateIndex(TestLogstoreName, config); err != nil { 19 | if e, ok := err.(*Error); ok && strings.Contains(e.Message, "already created") { 20 | //empty 21 | } else { 22 | t.Fatalf("fail create index: %s", err) 23 | } 24 | } 25 | 26 | i2, err := p.GetIndex(TestLogstoreName) 27 | if err != nil { 28 | t.Fatalf("fail get index: %s", err) 29 | } 30 | 31 | fmt.Println(i2) 32 | if i2.TTL != 7 { 33 | t.Fatalf("Expect ttl of index: %d, Actual %d", 7, i2.TTL) 34 | } 35 | 36 | if err := p.DeleteIndex(TestLogstoreName); err != nil { 37 | t.Fatalf("fail delete index: %s", err) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /sls/logstore_test.go: -------------------------------------------------------------------------------- 1 | package sls 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestShards(t *testing.T) { 9 | p := DefaultProject(t) 10 | shards, err := p.ListShards(TestLogstoreName) 11 | if err != nil { 12 | t.Fatalf("error find logstore %v", err) 13 | } 14 | 15 | fmt.Println(shards) 16 | } 17 | 18 | func TestLogstores(t *testing.T) { 19 | p := DefaultProject(t) 20 | list, err := p.ListLogstore() 21 | if err != nil { 22 | t.Fatalf("TestLogstores error: %v", err) 23 | } 24 | fmt.Println(list) 25 | } 26 | -------------------------------------------------------------------------------- /sls/logtail_test.go: -------------------------------------------------------------------------------- 1 | package sls 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLogtailConfigs(t *testing.T) { 8 | p := DefaultProject(t) 9 | _, err := p.ListConfig(0, 100) 10 | if err != nil { 11 | t.Fatalf("error list logtail configs: %v", err) 12 | } 13 | } 14 | 15 | func TestCreateLogtailConfig(t *testing.T) { 16 | p := DefaultProject(t) 17 | name := "logtail-test" 18 | logtailConfig := &LogtailConfig{ 19 | Name: name, 20 | InputType: "file", 21 | InputDetail: LogtailInput{ 22 | LogType: "common_reg_log", 23 | LogPath: "/abc", 24 | FilePattern: "*.log", 25 | LocalStorage: false, 26 | TimeFormat: "", 27 | LogBeginRegex: ".*", 28 | Regex: "(.*)", 29 | Key: []string{"content"}, 30 | FilterKey: []string{"content"}, 31 | FilterRegex: []string{".*"}, 32 | TopicFormat: "none", 33 | }, 34 | OutputType: "LogService", 35 | Sample: "sample", 36 | OutputDetail: LogtailOutput{ 37 | LogstoreName: TestLogstoreName, 38 | }, 39 | } 40 | 41 | _, err := p.GetConfig(logtailConfig.Name) 42 | if err != nil { 43 | if e, ok := err.(*Error); ok && e.Code == "ConfigNotExist" { 44 | if err := p.CreateConfig(logtailConfig); err != nil { 45 | t.Fatalf("error create logtail config: %v", err) 46 | } 47 | } else { 48 | t.Fatalf("Get config error: %v", err) 49 | } 50 | } 51 | 52 | if err := p.DeleteConfig(name); err != nil { 53 | t.Fatalf("error delete logtail config: %v", err) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sls/machine_group_test.go: -------------------------------------------------------------------------------- 1 | package sls 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestListMachineGroups(t *testing.T) { 9 | p := DefaultProject(t) 10 | groups, err := p.ListMachineGroup(0, 100) 11 | if err != nil { 12 | fmt.Printf("Error in list groups %s \n", err) 13 | t.FailNow() 14 | } 15 | 16 | fmt.Println(groups) 17 | } 18 | 19 | func TestCreateMachineGroup(t *testing.T) { 20 | p := DefaultProject(t) 21 | groupName := "testGroup" 22 | group := &MachineGroup{ 23 | Name: groupName, 24 | MachineIdentifyType: "ip", 25 | Attribute: &GroupAttribute{}, 26 | MachineList: []string{ 27 | "127.0.0.1", 28 | "127.0.0.2", 29 | }, 30 | } 31 | err := p.CreateMachineGroup(group) 32 | if err != nil { 33 | if e, ok := err.(*Error); ok && e.Code != "GroupAlreadyExist" { 34 | t.Fatalf("Create machine error: %v", err) 35 | } 36 | } 37 | 38 | mg, err := p.MachineGroup(groupName) 39 | if err != nil { 40 | t.Fatalf("Find machine error: %v", err) 41 | } 42 | 43 | _, err = p.ListMachines("testGroup", 0, 100) 44 | if err != nil { 45 | t.Fatalf("List machine error: %v", err) 46 | } 47 | 48 | //Update MachineGroup 49 | mg.MachineList = append(mg.MachineList, "127.0.0.3") 50 | if err = p.UpdateMachineGroup(mg); err != nil { 51 | t.Fatalf("Update machine error: %v", err) 52 | } 53 | 54 | if err = p.DeleteMachineGroup(groupName); err != nil { 55 | t.Fatalf("Delete machine error: %v", err) 56 | } 57 | } 58 | 59 | func TestClient_ListMachineGroups(t *testing.T) { 60 | client := NewTestClientForDebug() 61 | p, err := client.Project(TestProjectName) 62 | if err != nil { 63 | t.Fatalf("get project fail: %++v", err) 64 | } 65 | 66 | machines, err := p.ListMachines(TestMachineGroup, 0, 100) 67 | if err != nil { 68 | t.Fatalf("Error %++v", err) 69 | } else { 70 | for index, machine := range machines.Machines { 71 | t.Logf("Machines[%d] = %++v", index, machine) 72 | } 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sms/README.md: -------------------------------------------------------------------------------- 1 | #ALI SMS 2 | sms中包含了sms与dysms两套API。sms为早期的"邮件推送产品短信功能",dysms为"阿里云云通信产品"(包含原阿里大于用户)。 3 | 两套API互不相通,请根据自己的账户情况使用。 4 | 目前阿里已将短信业务集成至MNS中,推荐使用MNS来管理短信。 -------------------------------------------------------------------------------- /sms/client.go: -------------------------------------------------------------------------------- 1 | package sms 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | //dysms是阿里云通讯的短信服务,sms是旧版本邮件推送产品短信功能,两者互不相通,必须使用对应的API。 6 | //目前阿里已经把短信服务整合至MNS中,2017年6月22日以后开通的用户请使用MNS来发送短信。 7 | 8 | const ( 9 | DYSmsEndPoint = "https://dysmsapi.aliyuncs.com/" 10 | SendSms = "SendSms" 11 | QuerySms = "QuerySendDetails" 12 | DYSmsAPIVersion = "2017-05-25" 13 | 14 | SmsEndPoint = "https://sms.aliyuncs.com/" 15 | SingleSendSms = "SingleSendSms" 16 | SmsAPIVersion = "2016-09-27" 17 | ) 18 | 19 | type Client struct { 20 | common.Client 21 | } 22 | 23 | func NewClient(accessKeyId, accessKeySecret string) *Client { 24 | client := new(Client) 25 | client.Init(SmsEndPoint, SmsAPIVersion, accessKeyId, accessKeySecret) 26 | return client 27 | } 28 | 29 | type DYSmsClient struct { 30 | common.Client 31 | Region common.Region 32 | } 33 | 34 | func NewDYSmsClient(accessKeyId, accessKeySecret string) *DYSmsClient { 35 | client := new(DYSmsClient) 36 | client.Init(DYSmsEndPoint, DYSmsAPIVersion, accessKeyId, accessKeySecret) 37 | client.Region = common.Hangzhou 38 | return client 39 | } 40 | -------------------------------------------------------------------------------- /sms/dysms.go: -------------------------------------------------------------------------------- 1 | package sms 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | //阿里云通信 10 | type SendSmsArgs struct { 11 | PhoneNumbers string 12 | SignName string 13 | TemplateCode string 14 | TemplateParam string 15 | SmsUpExtendCode string `ArgName:"smsUpExtendCode"` 16 | OutId string 17 | } 18 | 19 | type QuerySmsArgs struct { 20 | PhoneNumber string 21 | BizId string 22 | SendDate string 23 | PageSize string 24 | CurrentPage string 25 | } 26 | 27 | type SendSmsResponse struct { 28 | common.Response 29 | Code string 30 | Message string 31 | BizId string 32 | } 33 | 34 | type QuerySmsResponse struct { 35 | common.Response 36 | Code string 37 | Message string 38 | TotalCount int 39 | TotalPage string 40 | SmsSendDetailDTOs struct { 41 | SmsSendDetailDTO []SmsSendDetailDTOsItem 42 | } 43 | } 44 | 45 | type SmsSendDetailDTOsItem struct { 46 | PhoneNum string 47 | SendStatus int 48 | ErrCode string 49 | TemplateCode string 50 | Content string 51 | SendDate string 52 | ReceiveDate string 53 | OutId string 54 | } 55 | 56 | func (this *DYSmsClient) SendSms(args *SendSmsArgs) (*SendSmsResponse, error) { 57 | resp := SendSmsResponse{} 58 | return &resp, this.InvokeByAnyMethod(http.MethodGet, SendSms, "", args, &resp) 59 | } 60 | 61 | func (this *DYSmsClient) QuerySms(args *QuerySmsArgs) (*QuerySmsResponse, error) { 62 | resp := QuerySmsResponse{} 63 | return &resp, this.InvokeByAnyMethod(http.MethodGet, QuerySms, "", args, &resp) 64 | } 65 | -------------------------------------------------------------------------------- /sms/sms.go: -------------------------------------------------------------------------------- 1 | package sms 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | //邮件推送产品短信功能 10 | type SingleSendSmsArgs struct { 11 | SignName string 12 | TemplateCode string 13 | RecNum string 14 | ParamString string 15 | } 16 | 17 | func (this *Client) SingleSendSms(args *SingleSendSmsArgs) error { 18 | return this.InvokeByAnyMethod(http.MethodPost, SingleSendSms, "", args, &common.Response{}) 19 | } 20 | -------------------------------------------------------------------------------- /sms/sms_test.go: -------------------------------------------------------------------------------- 1 | package sms 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | func TestSms(t *testing.T) { 9 | ID := os.Getenv("ALI_DM_ACCESS_KEY_ID") 10 | SECRET := os.Getenv("ALI_DM_ACCESS_KEY_SECRET") 11 | SIGNAME := os.Getenv("ALI_DM_SMS_SIGN_NAME") 12 | TEMPCODE := os.Getenv("ALI_DM_SMS_TEMPLATE_CODE") 13 | NUM := os.Getenv("ALI_DM_SMS_TEST_PHONE") 14 | client := NewDYSmsClient(ID, SECRET) 15 | client.SendSms(&SendSmsArgs{ 16 | SignName: SIGNAME, 17 | TemplateCode: TEMPCODE, 18 | PhoneNumbers: NUM, 19 | TemplateParam: `{"number": "123"}`, 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /sts/assume_role.go: -------------------------------------------------------------------------------- 1 | package sts 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type AssumeRoleRequest struct { 6 | RoleArn string 7 | RoleSessionName string 8 | DurationSeconds int 9 | Policy string 10 | } 11 | 12 | type AssumedRoleUser struct { 13 | AssumedRoleId string 14 | Arn string 15 | } 16 | 17 | type AssumedRoleUserCredentials struct { 18 | AccessKeySecret string 19 | AccessKeyId string 20 | Expiration string 21 | SecurityToken string 22 | } 23 | 24 | type AssumeRoleResponse struct { 25 | common.Response 26 | AssumedRoleUser AssumedRoleUser 27 | Credentials AssumedRoleUserCredentials 28 | } 29 | 30 | func (c *STSClient) AssumeRole(r AssumeRoleRequest) (AssumeRoleResponse, error) { 31 | resp := AssumeRoleResponse{} 32 | e := c.Invoke("AssumeRole", r, &resp) 33 | if e != nil { 34 | return AssumeRoleResponse{}, e 35 | } 36 | return resp, nil 37 | } 38 | -------------------------------------------------------------------------------- /sts/client.go: -------------------------------------------------------------------------------- 1 | package sts 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/common" 7 | ) 8 | 9 | const ( 10 | // STSDefaultEndpoint is the default API endpoint of STS services 11 | STSDefaultEndpoint = "https://sts.aliyuncs.com" 12 | STSAPIVersion = "2015-04-01" 13 | ) 14 | 15 | type STSClient struct { 16 | common.Client 17 | } 18 | 19 | func NewClient(accessKeyId string, accessKeySecret string) *STSClient { 20 | return NewClientWithSecurityToken(accessKeyId, accessKeySecret, "") 21 | } 22 | 23 | func NewClientWithSecurityToken(accessKeyId string, accessKeySecret string, securityToken string) *STSClient { 24 | endpoint := os.Getenv("STS_ENDPOINT") 25 | if endpoint == "" { 26 | endpoint = STSDefaultEndpoint 27 | } 28 | 29 | return NewClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, securityToken) 30 | } 31 | 32 | func NewClientWithEndpoint(endpoint string, accessKeyId string, accessKeySecret string) *STSClient { 33 | return NewClientWithEndpointAndSecurityToken(endpoint, accessKeyId, accessKeySecret, "") 34 | } 35 | 36 | func NewClientWithEndpointAndSecurityToken(endpoint string, accessKeyId string, accessKeySecret string, securityToken string) *STSClient { 37 | client := &STSClient{} 38 | client.WithEndpoint(endpoint). 39 | WithVersion(STSAPIVersion). 40 | WithAccessKeyId(accessKeyId). 41 | WithAccessKeySecret(accessKeySecret). 42 | WithSecurityToken(securityToken). 43 | InitClient() 44 | return client 45 | } 46 | -------------------------------------------------------------------------------- /sts/client_test.go: -------------------------------------------------------------------------------- 1 | package sts 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/denverdino/aliyungo/ram" 7 | ) 8 | 9 | /* 10 | Set your AccessKeyId and AccessKeySecret in env 11 | simply use the command below 12 | AccessKeyId=YourAccessKeyId AccessKeySecret=YourAccessKeySecret go test 13 | */ 14 | var ( 15 | AccessKeyId = os.Getenv("AccessKeyId") 16 | AccessKeySecret = os.Getenv("AccessKeySecret") 17 | ) 18 | 19 | func NewRAMTestClient() ram.RamClientInterface { 20 | client := ram.NewClient(AccessKeyId, AccessKeySecret) 21 | return client 22 | } 23 | 24 | func NewTestClient() *STSClient { 25 | client := NewClient(AccessKeyId, AccessKeySecret) 26 | client.SetDebug(true) 27 | return client 28 | } 29 | -------------------------------------------------------------------------------- /sts/get_caller_identity.go: -------------------------------------------------------------------------------- 1 | package sts 2 | 3 | import "github.com/denverdino/aliyungo/common" 4 | 5 | type GetCallerIdentityRequest struct { 6 | } 7 | 8 | type GetCallerIdentityResponse struct { 9 | common.Response 10 | AccountId string 11 | UserId string 12 | Arn string 13 | } 14 | 15 | func (c *STSClient) GetCallerIdentity() (*GetCallerIdentityResponse, error) { 16 | resp := &GetCallerIdentityResponse{} 17 | err := c.Invoke("GetCallerIdentity", &GetCallerIdentityRequest{}, resp) 18 | if err != nil { 19 | return resp, err 20 | } 21 | return resp, nil 22 | } 23 | -------------------------------------------------------------------------------- /sts/get_caller_identity_test.go: -------------------------------------------------------------------------------- 1 | package sts 2 | 3 | import "testing" 4 | 5 | func TestGetCallerIdentity(t *testing.T) { 6 | 7 | stsClient := NewTestClient() 8 | resp, err := stsClient.GetCallerIdentity() 9 | if err != nil { 10 | t.Errorf("Failed to GetCallerIdentity %v", err) 11 | return 12 | } 13 | 14 | t.Logf("pass GetCallerIdentity %v", resp) 15 | } 16 | -------------------------------------------------------------------------------- /util/attempt.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // AttemptStrategy is reused from the goamz package 8 | 9 | // AttemptStrategy represents a strategy for waiting for an action 10 | // to complete successfully. This is an internal type used by the 11 | // implementation of other packages. 12 | type AttemptStrategy struct { 13 | Total time.Duration // total duration of attempt. 14 | Delay time.Duration // interval between each try in the burst. 15 | Min int // minimum number of retries; overrides Total 16 | } 17 | 18 | type Attempt struct { 19 | strategy AttemptStrategy 20 | last time.Time 21 | end time.Time 22 | force bool 23 | count int 24 | } 25 | 26 | // Start begins a new sequence of attempts for the given strategy. 27 | func (s AttemptStrategy) Start() *Attempt { 28 | now := time.Now() 29 | return &Attempt{ 30 | strategy: s, 31 | last: now, 32 | end: now.Add(s.Total), 33 | force: true, 34 | } 35 | } 36 | 37 | // Next waits until it is time to perform the next attempt or returns 38 | // false if it is time to stop trying. 39 | func (a *Attempt) Next() bool { 40 | now := time.Now() 41 | sleep := a.nextSleep(now) 42 | if !a.force && !now.Add(sleep).Before(a.end) && a.strategy.Min <= a.count { 43 | return false 44 | } 45 | a.force = false 46 | if sleep > 0 && a.count > 0 { 47 | time.Sleep(sleep) 48 | now = time.Now() 49 | } 50 | a.count++ 51 | a.last = now 52 | return true 53 | } 54 | 55 | func (a *Attempt) nextSleep(now time.Time) time.Duration { 56 | sleep := a.strategy.Delay - now.Sub(a.last) 57 | if sleep < 0 { 58 | return 0 59 | } 60 | return sleep 61 | } 62 | 63 | // HasNext returns whether another attempt will be made if the current 64 | // one fails. If it returns true, the following call to Next is 65 | // guaranteed to return true. 66 | func (a *Attempt) HasNext() bool { 67 | if a.force || a.strategy.Min > a.count { 68 | return true 69 | } 70 | now := time.Now() 71 | if now.Add(a.nextSleep(now)).Before(a.end) { 72 | a.force = true 73 | return true 74 | } 75 | return false 76 | } 77 | -------------------------------------------------------------------------------- /util/attempt_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestAttemptTiming(t *testing.T) { 9 | testAttempt := AttemptStrategy{ 10 | Total: 0.25e9, 11 | Delay: 0.1e9, 12 | } 13 | want := []time.Duration{0, 0.1e9, 0.2e9, 0.2e9} 14 | got := make([]time.Duration, 0, len(want)) // avoid allocation when testing timing 15 | t0 := time.Now() 16 | for a := testAttempt.Start(); a.Next(); { 17 | got = append(got, time.Since(t0)) 18 | } 19 | got = append(got, time.Since(t0)) 20 | if len(got) != len(want) { 21 | t.Fatalf("Failed!") 22 | } 23 | const margin = 0.01e9 24 | for i, got := range want { 25 | lo := want[i] - margin 26 | hi := want[i] + margin 27 | if got < lo || got > hi { 28 | t.Errorf("attempt %d want %g got %g", i, want[i].Seconds(), got.Seconds()) 29 | } 30 | } 31 | } 32 | 33 | func TestAttemptNextHasNext(t *testing.T) { 34 | a := AttemptStrategy{}.Start() 35 | if !a.Next() { 36 | t.Fatalf("Failed!") 37 | } 38 | if a.Next() { 39 | t.Fatalf("Failed!") 40 | } 41 | 42 | a = AttemptStrategy{}.Start() 43 | if !a.Next() { 44 | t.Fatalf("Failed!") 45 | } 46 | if a.HasNext() { 47 | t.Fatalf("Failed!") 48 | } 49 | if a.Next() { 50 | t.Fatalf("Failed!") 51 | } 52 | a = AttemptStrategy{Total: 2e8}.Start() 53 | 54 | if !a.Next() { 55 | t.Fatalf("Failed!") 56 | } 57 | if !a.HasNext() { 58 | t.Fatalf("Failed!") 59 | } 60 | time.Sleep(2e8) 61 | 62 | if !a.HasNext() { 63 | t.Fatalf("Failed!") 64 | } 65 | if !a.Next() { 66 | t.Fatalf("Failed!") 67 | } 68 | if a.Next() { 69 | t.Fatalf("Failed!") 70 | } 71 | 72 | a = AttemptStrategy{Total: 1e8, Min: 2}.Start() 73 | time.Sleep(1e8) 74 | 75 | if !a.Next() { 76 | t.Fatalf("Failed!") 77 | } 78 | if !a.HasNext() { 79 | t.Fatalf("Failed!") 80 | } 81 | if !a.Next() { 82 | t.Fatalf("Failed!") 83 | } 84 | if a.HasNext() { 85 | t.Fatalf("Failed!") 86 | } 87 | if a.Next() { 88 | t.Fatalf("Failed!") 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /util/iso6801_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestISO8601Time(t *testing.T) { 10 | now := NewISO6801Time(time.Now().UTC()) 11 | 12 | data, err := json.Marshal(now) 13 | if err != nil { 14 | t.Fatal(err) 15 | } 16 | 17 | _, err = time.Parse(`"`+formatISO8601+`"`, string(data)) 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | 22 | var now2 ISO6801Time 23 | err = json.Unmarshal(data, &now2) 24 | if err != nil { 25 | t.Fatal(err) 26 | } 27 | 28 | if now != now2 { 29 | t.Errorf("Time %s does not equal expected %s", now2, now) 30 | } 31 | 32 | if now.String() != now2.String() { 33 | t.Fatalf("String format for %s does not equal expected %s", now2, now) 34 | } 35 | 36 | type TestTimeStruct struct { 37 | A int 38 | B *ISO6801Time 39 | } 40 | var testValue TestTimeStruct 41 | err = json.Unmarshal([]byte("{\"A\": 1, \"B\":\"\"}"), &testValue) 42 | if err != nil { 43 | t.Fatal(err) 44 | } 45 | t.Logf("%v", testValue) 46 | if !testValue.B.IsDefault() { 47 | t.Fatal("Invaid Unmarshal result for ISO6801Time from empty value") 48 | } 49 | t.Logf("ISO6801Time String(): %s", now2.String()) 50 | } 51 | 52 | func TestISO8601TimeWithoutSeconds(t *testing.T) { 53 | 54 | const dateStr = "\"2015-10-02T12:36Z\"" 55 | 56 | var date ISO6801Time 57 | 58 | err := json.Unmarshal([]byte(dateStr), &date) 59 | if err != nil { 60 | t.Fatal(err) 61 | } 62 | 63 | const dateStr2 = "\"2015-10-02T12:36:00Z\"" 64 | 65 | var date2 ISO6801Time 66 | 67 | err = json.Unmarshal([]byte(dateStr2), &date2) 68 | if err != nil { 69 | t.Fatal(err) 70 | } 71 | 72 | if date != date2 { 73 | t.Error("The two dates should be equal.") 74 | } 75 | 76 | } 77 | 78 | func TestISO8601TimeInt(t *testing.T) { 79 | 80 | const dateStr = "1405544146000" 81 | 82 | var date ISO6801Time 83 | 84 | err := json.Unmarshal([]byte(dateStr), &date) 85 | if err != nil { 86 | t.Fatal(err) 87 | } 88 | 89 | t.Logf("date: %s", date) 90 | 91 | } 92 | -------------------------------------------------------------------------------- /util/signature.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "crypto/hmac" 5 | "crypto/sha1" 6 | "encoding/base64" 7 | "net/url" 8 | "strings" 9 | ) 10 | 11 | //CreateSignature creates signature for string following Aliyun rules 12 | func CreateSignature(stringToSignature, accessKeySecret string) string { 13 | // Crypto by HMAC-SHA1 14 | hmacSha1 := hmac.New(sha1.New, []byte(accessKeySecret)) 15 | hmacSha1.Write([]byte(stringToSignature)) 16 | sign := hmacSha1.Sum(nil) 17 | 18 | // Encode to Base64 19 | base64Sign := base64.StdEncoding.EncodeToString(sign) 20 | 21 | return base64Sign 22 | } 23 | 24 | func percentReplace(str string) string { 25 | str = strings.Replace(str, "+", "%20", -1) 26 | str = strings.Replace(str, "*", "%2A", -1) 27 | str = strings.Replace(str, "%7E", "~", -1) 28 | 29 | return str 30 | } 31 | 32 | // CreateSignatureForRequest creates signature for query string values 33 | func CreateSignatureForRequest(method string, values *url.Values, accessKeySecret string) string { 34 | 35 | canonicalizedQueryString := percentReplace(values.Encode()) 36 | 37 | stringToSign := method + "&%2F&" + url.QueryEscape(canonicalizedQueryString) 38 | return CreateSignature(stringToSign, accessKeySecret) 39 | } 40 | -------------------------------------------------------------------------------- /util/signature_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateSignature(t *testing.T) { 8 | 9 | str := "GET&%2F&AccessKeyId%3Dtestid%26Action%3DDescribeRegions%26Format%3DXML%26RegionId%3Dregion1%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3DNwDAxvLU6tFE0DVb%26SignatureVersion%3D1.0%26TimeStamp%3D2012-12-26T10%253A33%253A56Z%26Version%3D2014-05-26" 10 | 11 | signature := CreateSignature(str, "testsecret") 12 | 13 | t.Log(signature) 14 | } 15 | -------------------------------------------------------------------------------- /util/util_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateRandomString(t *testing.T) { 8 | for i := 0; i < 10; i++ { 9 | s := CreateRandomString() 10 | t.Logf("Generated Random String: %s", s) 11 | } 12 | } 13 | 14 | func TestGenerateRandomECSPassword(t *testing.T) { 15 | for i := 0; i < 10; i++ { 16 | s := GenerateRandomECSPassword() 17 | 18 | if len(s) < 8 || len(s) > 30 { 19 | t.Errorf("Generated ECS password [%v]: bad len", s) 20 | } 21 | 22 | hasDigit := false 23 | hasLower := false 24 | hasUpper := false 25 | 26 | for j := range s { 27 | 28 | switch { 29 | case '0' <= s[j] && s[j] <= '9': 30 | hasDigit = true 31 | case 'a' <= s[j] && s[j] <= 'z': 32 | hasLower = true 33 | case 'A' <= s[j] && s[j] <= 'Z': 34 | hasUpper = true 35 | } 36 | } 37 | 38 | if !hasDigit { 39 | t.Errorf("Generated ECS password [%v]: no digit", s) 40 | } 41 | 42 | if !hasLower { 43 | t.Errorf("Generated ECS password [%v]: no lower letter ", s) 44 | } 45 | 46 | if !hasUpper { 47 | t.Errorf("Generated ECS password [%v]: no upper letter", s) 48 | } 49 | } 50 | } 51 | --------------------------------------------------------------------------------