alicloud/connectivity/client.go (1,882 lines of code) (raw):

package connectivity import ( "fmt" "log" "net/http" "net/url" "os" "regexp" "strconv" "strings" "sync" "time" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" util "github.com/alibabacloud-go/tea-utils/service" utilV2 "github.com/alibabacloud-go/tea-utils/v2/service" ossclient "github.com/alibabacloud-go/alibabacloud-gateway-oss/client" gatewayclient "github.com/alibabacloud-go/alibabacloud-gateway-sls/client" roaCS "github.com/alibabacloud-go/cs-20151215/v5/client" openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" roa "github.com/alibabacloud-go/tea-roa/client" rpc "github.com/alibabacloud-go/tea-rpc/client" "github.com/alibabacloud-go/tea/tea" "github.com/aliyun/alibaba-cloud-sdk-go/sdk" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints" "github.com/aliyun/alibaba-cloud-sdk-go/services/adb" "github.com/aliyun/alibaba-cloud-sdk-go/services/alidns" "github.com/aliyun/alibaba-cloud-sdk-go/services/alikafka" "github.com/aliyun/alibaba-cloud-sdk-go/services/bssopenapi" "github.com/aliyun/alibaba-cloud-sdk-go/services/cbn" cdn_new "github.com/aliyun/alibaba-cloud-sdk-go/services/cdn" "github.com/aliyun/alibaba-cloud-sdk-go/services/cloudapi" "github.com/aliyun/alibaba-cloud-sdk-go/services/cms" "github.com/aliyun/alibaba-cloud-sdk-go/services/cr" "github.com/aliyun/alibaba-cloud-sdk-go/services/cr_ee" officalCS "github.com/aliyun/alibaba-cloud-sdk-go/services/cs" "github.com/aliyun/alibaba-cloud-sdk-go/services/ddosbgp" "github.com/aliyun/alibaba-cloud-sdk-go/services/ddoscoo" "github.com/aliyun/alibaba-cloud-sdk-go/services/dds" "github.com/aliyun/alibaba-cloud-sdk-go/services/drds" "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs" "github.com/aliyun/alibaba-cloud-sdk-go/services/edas" "github.com/aliyun/alibaba-cloud-sdk-go/services/elasticsearch" "github.com/aliyun/alibaba-cloud-sdk-go/services/emr" "github.com/aliyun/alibaba-cloud-sdk-go/services/ess" "github.com/aliyun/alibaba-cloud-sdk-go/services/gpdb" "github.com/aliyun/alibaba-cloud-sdk-go/services/hbase" "github.com/aliyun/alibaba-cloud-sdk-go/services/market" "github.com/aliyun/alibaba-cloud-sdk-go/services/maxcompute" "github.com/aliyun/alibaba-cloud-sdk-go/services/ots" "github.com/aliyun/alibaba-cloud-sdk-go/services/polardb" r_kvstore "github.com/aliyun/alibaba-cloud-sdk-go/services/r-kvstore" "github.com/aliyun/alibaba-cloud-sdk-go/services/ram" "github.com/aliyun/alibaba-cloud-sdk-go/services/slb" slsPop "github.com/aliyun/alibaba-cloud-sdk-go/services/sls" "github.com/aliyun/alibaba-cloud-sdk-go/services/smartag" "github.com/aliyun/alibaba-cloud-sdk-go/services/sts" "github.com/aliyun/alibaba-cloud-sdk-go/services/vpc" "github.com/aliyun/alibaba-cloud-sdk-go/services/yundun_dbaudit" "github.com/aliyun/aliyun-datahub-sdk-go/datahub" sls "github.com/aliyun/aliyun-log-go-sdk" ali_mns "github.com/aliyun/aliyun-mns-go-sdk" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore" otsTunnel "github.com/aliyun/aliyun-tablestore-go-sdk/tunnel" "github.com/aliyun/fc-go-sdk" "github.com/denverdino/aliyungo/cdn" "github.com/denverdino/aliyungo/cs" "github.com/aliyun/alibaba-cloud-sdk-go/services/cassandra" "github.com/aliyun/alibaba-cloud-sdk-go/services/dcdn" "github.com/aliyun/alibaba-cloud-sdk-go/services/eci" ) type AliyunClient struct { Region Region RegionId string SourceIp string SecureTransport string skipRegionValidation bool //In order to build ots table client, add accesskey and secretkey in aliyunclient temporarily. AccessKey string SecretKey string SecurityToken string OtsInstanceName string accountIdMutex sync.RWMutex config *Config teaSdkConfig rpc.Config teaRoaSdkConfig roa.Config teaRpcOpenapiConfig openapi.Config teaRoaOpenapiConfig openapi.Config accountId string ecsconn *ecs.Client essconn *ess.Client vpcconn *vpc.Client slbconn *slb.Client alikafkaconn *alikafka.Client ossconn *oss.Client dnsconn *alidns.Client ramconn *ram.Client csconn *cs.Client officalCSConn *officalCS.Client roaCSConn *roaCS.Client cdnconn_new *cdn_new.Client crconn *cr.Client creeconn *cr_ee.Client cdnconn *cdn.CdnClient otsconn *ots.Client cmsconn *cms.Client logconn *sls.Client fcconn *fc.Client cenconn *cbn.Client logpopconn *slsPop.Client ddsconn *dds.Client gpdbconn *gpdb.Client stsconn *sts.Client rkvconn *r_kvstore.Client polarDBconn *polardb.Client dhconn datahub.DataHubApi mnsconn *ali_mns.MNSClient cloudapiconn *cloudapi.Client teaConn *rpc.Client tablestoreconnByInstanceName map[string]*tablestore.TableStoreClient otsTunnelConnByInstanceName map[string]otsTunnel.TunnelClient csprojectconnByKey map[string]*cs.ProjectClient drdsconn *drds.Client elasticsearchconn *elasticsearch.Client ddoscooconn *ddoscoo.Client ddosbgpconn *ddosbgp.Client bssopenapiconn *bssopenapi.Client emrconn *emr.Client sagconn *smartag.Client dbauditconn *yundun_dbaudit.Client marketconn *market.Client hbaseconn *hbase.Client adbconn *adb.Client cbnConn *cbn.Client maxcomputeconn *maxcompute.Client dnsConn *alidns.Client edasconn *edas.Client bssopenapiConn *bssopenapi.Client alidnsConn *alidns.Client ddoscooConn *ddoscoo.Client cassandraConn *cassandra.Client eciConn *eci.Client ecsConn *ecs.Client dcdnConn *dcdn.Client cmsConn *cms.Client r_kvstoreConn *r_kvstore.Client maxcomputeConn *maxcompute.Client } type ApiVersion string const ( ApiVersion20140526 = ApiVersion("2014-05-26") ApiVersion20160815 = ApiVersion("2016-08-15") ApiVersion20140515 = ApiVersion("2014-05-15") ) const businessInfoKey = "Terraform" const DefaultClientRetryCountSmall = 5 const DefaultClientRetryCountMedium = 10 const DefaultClientRetryCountLarge = 15 const Terraform = "HashiCorp-Terraform" const Provider = "Terraform-Provider" const Module = "Terraform-Module" const TerraformTraceId = "TerraformTraceId" var goSdkMutex = sync.RWMutex{} // The Go SDK is not thread-safe var loadSdkfromRemoteMutex = sync.Mutex{} var loadSdkEndpointMutex = sync.Mutex{} // The main version number that is being run at the moment. var providerVersion = "1.249.0" // Temporarily maintain map for old ecs client methods and store special endpoint information var EndpointMap = map[string]string{ "cn-shenzhen-su18-b01": "ecs.aliyuncs.com", "cn-beijing": "ecs.aliyuncs.com", "cn-shenzhen-st4-d01": "ecs.aliyuncs.com", "cn-haidian-cm12-c01": "ecs.aliyuncs.com", "cn-hangzhou-internal-prod-1": "ecs.aliyuncs.com", "cn-qingdao": "ecs.aliyuncs.com", "cn-shanghai": "ecs.aliyuncs.com", "cn-shanghai-finance-1": "ecs.aliyuncs.com", "cn-hongkong": "ecs.aliyuncs.com", "us-west-1": "ecs.aliyuncs.com", "cn-shenzhen": "ecs.aliyuncs.com", "cn-shanghai-et15-b01": "ecs.aliyuncs.com", "cn-hangzhou-bj-b01": "ecs.aliyuncs.com", "cn-zhangbei-na61-b01": "ecs.aliyuncs.com", "cn-shenzhen-finance-1": "ecs.aliyuncs.com", "cn-shanghai-et2-b01": "ecs.aliyuncs.com", "ap-southeast-1": "ecs.aliyuncs.com", "cn-beijing-nu16-b01": "ecs.aliyuncs.com", "us-east-1": "ecs.aliyuncs.com", "cn-fujian": "ecs.aliyuncs.com", "cn-hangzhou": "ecs.aliyuncs.com", } // Client for AliyunClient func (c *Config) Client() (*AliyunClient, error) { // Get the auth and region. This can fail if keys/regions were not // specified and we're attempting to use the environment. if !c.SkipRegionValidation { err := c.loadAndValidate() if err != nil { return nil, err } } loadLocalEndpoint = hasLocalEndpoint() if hasLocalEndpoint() { if err := c.loadEndpointFromLocal(); err != nil { return nil, err } } teaSdkConfig, err := c.getTeaDslSdkConfig(true) if err != nil { return nil, err } teaRoaSdkConfig, err := c.getTeaRoaDslSdkConfig(true) if err != nil { return nil, err } teaRpcOpenapiConfig, err := c.getTeaRpcOpenapiConfig(true) if err != nil { return nil, err } teaRoaOpenapiConfig, err := c.getTeaRoaOpenapiConfig(true) if err != nil { return nil, err } client := &AliyunClient{ config: c, teaSdkConfig: teaSdkConfig, teaRoaSdkConfig: teaRoaSdkConfig, teaRpcOpenapiConfig: teaRpcOpenapiConfig, teaRoaOpenapiConfig: teaRoaOpenapiConfig, SourceIp: c.SourceIp, Region: c.Region, RegionId: c.RegionId, AccessKey: c.AccessKey, SecretKey: c.SecretKey, SecurityToken: c.SecurityToken, OtsInstanceName: c.OtsInstanceName, accountId: c.AccountId, tablestoreconnByInstanceName: make(map[string]*tablestore.TableStoreClient), otsTunnelConnByInstanceName: make(map[string]otsTunnel.TunnelClient), csprojectconnByKey: make(map[string]*cs.ProjectClient), skipRegionValidation: c.SkipRegionValidation, } if c.AccountType == "" { c.AccountType = client.getAccountType() client.config = c } log.Printf("[INFO] caller identity's account type is %s.", client.config.AccountType) return client, nil } func (client *AliyunClient) WithEcsClient(do func(*ecs.Client) (interface{}, error)) (interface{}, error) { if client.ecsconn != nil && !client.config.needRefreshCredential() { return do(client.ecsconn) } product := "ecs" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } ecsconn, err := ecs.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(time.Duration(60)*time.Second), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the ECS client: %#v", err) } ecs.SetClientProperty(ecsconn, "EndpointMap", map[string]string{ client.RegionId: endpoint, }) ecs.SetEndpointDataToClient(ecsconn) ecsconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) ecsconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) ecsconn.SourceIp = client.config.SourceIp ecsconn.SecureTransport = client.config.SecureTransport client.ecsconn = ecsconn return do(client.ecsconn) } func (client *AliyunClient) WithOfficalCSClient(do func(*officalCS.Client) (interface{}, error)) (interface{}, error) { if client.officalCSConn != nil && !client.config.needRefreshCredential() { return do(client.officalCSConn) } product := "cs" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } csconn, err := officalCS.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the CS client: %#v", err) } csconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) csconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) csconn.SourceIp = client.config.SourceIp csconn.SecureTransport = client.config.SecureTransport client.officalCSConn = csconn return do(client.officalCSConn) } func (client *AliyunClient) WithPolarDBClient(do func(*polardb.Client) (interface{}, error)) (interface{}, error) { if client.polarDBconn != nil && !client.config.needRefreshCredential() { return do(client.polarDBconn) } product := "polardb" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } polarDBconn, err := polardb.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the PolarDB client: %#v", err) } polarDBconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) polarDBconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) polarDBconn.SourceIp = client.config.SourceIp polarDBconn.SecureTransport = client.config.SecureTransport client.polarDBconn = polarDBconn return do(client.polarDBconn) } func (client *AliyunClient) WithSlbClient(do func(*slb.Client) (interface{}, error)) (interface{}, error) { if client.slbconn != nil && !client.config.needRefreshCredential() { return do(client.slbconn) } product := "slb" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } slbconn, err := slb.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the SLB client: %#v", err) } slbconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) slbconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) slbconn.SourceIp = client.config.SourceIp slbconn.SecureTransport = client.config.SecureTransport client.slbconn = slbconn return do(client.slbconn) } func (client *AliyunClient) WithVpcClient(do func(*vpc.Client) (interface{}, error)) (interface{}, error) { if client.vpcconn != nil && !client.config.needRefreshCredential() { return do(client.vpcconn) } product := "vpc" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } vpcconn, err := vpc.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(time.Duration(60)*time.Second), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the VPC client: %#v", err) } vpcconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) vpcconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) vpcconn.SourceIp = client.config.SourceIp vpcconn.SecureTransport = client.config.SecureTransport client.vpcconn = vpcconn return do(client.vpcconn) } func (client *AliyunClient) WithEssClient(do func(*ess.Client) (interface{}, error)) (interface{}, error) { if client.essconn != nil && !client.config.needRefreshCredential() { return do(client.essconn) } product := "ess" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } essconn, err := ess.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the ESS client: %#v", err) } essconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) essconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) essconn.SourceIp = client.config.SourceIp essconn.SecureTransport = client.config.SecureTransport client.essconn = essconn return do(client.essconn) } func (client *AliyunClient) WithOssClient(do func(*oss.Client) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() if client.ossconn != nil && !client.config.needRefreshCredential() { return do(client.ossconn) } product := "oss" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } schma := strings.ToLower(client.config.Protocol) if !strings.HasPrefix(endpoint, "http") { endpoint = fmt.Sprintf("%s://%s", schma, endpoint) } clientOptions := []oss.ClientOption{oss.UserAgent(client.config.getUserAgent())} proxy, err := client.getHttpProxy() if proxy != nil { skip, err := client.skipProxy(endpoint) if err != nil { return nil, err } if !skip { clientOptions = append(clientOptions, oss.Proxy(proxy.String())) } } clientOptions = append(clientOptions, oss.SetCredentialsProvider(&ossCredentialsProvider{client: client})) // region clientOptions = append(clientOptions, oss.Region(client.config.RegionId)) // SignVersion if ossV, ok := client.config.SignVersion.Load("oss"); ok { clientOptions = append(clientOptions, oss.AuthVersion(func(v any) oss.AuthVersionType { switch fmt.Sprintf("%v", v) { case "v4": return oss.AuthV4 case "v2": return oss.AuthV2 } //default is v1 return oss.AuthV1 }(ossV))) } ossconn, err := oss.New(endpoint, "", "", clientOptions...) if err != nil { return nil, fmt.Errorf("unable to initialize the OSS client: %#v", err) } client.ossconn = ossconn return do(client.ossconn) } func (client *AliyunClient) WithOssBucketByName(bucketName string, do func(*oss.Bucket) (interface{}, error)) (interface{}, error) { return client.WithOssClient(func(ossClient *oss.Client) (interface{}, error) { bucket, err := client.ossconn.Bucket(bucketName) if err != nil { return nil, fmt.Errorf("unable to get the bucket %s: %#v", bucketName, err) } return do(bucket) }) } func (client *AliyunClient) WithDnsClient(do func(*alidns.Client) (interface{}, error)) (interface{}, error) { if client.dnsconn != nil && !client.config.needRefreshCredential() { return do(client.dnsconn) } product := "alidns" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, string(DNSCode), endpoint) } dnsconn, err := alidns.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the DNS client: %#v", err) } dnsconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) dnsconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) dnsconn.SourceIp = client.config.SourceIp dnsconn.SecureTransport = client.config.SecureTransport client.dnsconn = dnsconn return do(client.dnsconn) } func (client *AliyunClient) WithRamClient(do func(*ram.Client) (interface{}, error)) (interface{}, error) { if client.ramconn != nil && !client.config.needRefreshCredential() { return do(client.ramconn) } product := "ram" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } ramconn, err := ram.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the RAM client: %#v", err) } ramconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) ramconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) ramconn.SourceIp = client.config.SourceIp ramconn.SecureTransport = client.config.SecureTransport client.ramconn = ramconn return do(client.ramconn) } func (client *AliyunClient) WithCsClient(do func(*cs.Client) (interface{}, error)) (interface{}, error) { if client.csconn != nil && !client.config.needRefreshCredential() { return do(client.csconn) } product := "cs" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } endpoint = fmt.Sprintf("https://%s", endpoint) accessKey, secretKey, stsToken := client.config.AccessKey, client.config.SecretKey, client.config.SecurityToken credential, err := client.config.Credential.GetCredential() if err != nil || credential == nil { log.Printf("[WARN] get credential failed. Error: %#v", err) } else { accessKey, secretKey, stsToken = *credential.AccessKeyId, *credential.AccessKeySecret, *credential.SecurityToken } csconn := cs.NewClientForAussumeRole(accessKey, secretKey, stsToken) csconn.SetUserAgent(client.config.getUserAgent()) csconn.SetEndpoint(endpoint) csconn.SetSourceIp(client.config.SourceIp) csconn.SetSecureTransport(client.config.SecureTransport) client.csconn = csconn return do(client.csconn) } func (client *AliyunClient) NewRoaCsClient() (*roaCS.Client, error) { product := "cs" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } accessKey, secretKey, stsToken := client.config.AccessKey, client.config.SecretKey, client.config.SecurityToken credential, err := client.config.Credential.GetCredential() if err != nil || credential == nil { log.Printf("[WARN] get credential failed. Error: %#v", err) } else { accessKey, secretKey, stsToken = *credential.AccessKeyId, *credential.AccessKeySecret, *credential.SecurityToken } header := map[string]*string{ "x-acs-source-ip": tea.String(client.config.SourceIp), "x-acs-secure-transport": tea.String(client.config.SecureTransport), } param := &openapi.GlobalParameters{Headers: header} // Initialize the CS client if necessary roaCSConn, err := roaCS.NewClient(&openapi.Config{ AccessKeyId: tea.String(accessKey), AccessKeySecret: tea.String(secretKey), SecurityToken: tea.String(stsToken), RegionId: tea.String(client.config.RegionId), UserAgent: tea.String(client.config.getUserAgent()), Endpoint: tea.String(endpoint), ReadTimeout: tea.Int(client.config.ClientReadTimeout), ConnectTimeout: tea.Int(client.config.ClientConnectTimeout), GlobalParameters: param, }) if err != nil { return nil, err } return roaCSConn, nil } func (client *AliyunClient) WithCrClient(do func(*cr.Client) (interface{}, error)) (interface{}, error) { if client.crconn != nil && !client.config.needRefreshCredential() { return do(client.crconn) } product := "cr" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, string(CRCode), endpoint) } crconn, err := cr.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the CR client: %#v", err) } crconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) crconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) crconn.SourceIp = client.config.SourceIp crconn.SecureTransport = client.config.SecureTransport client.crconn = crconn return do(client.crconn) } func (client *AliyunClient) WithCrEEClient(do func(*cr_ee.Client) (interface{}, error)) (interface{}, error) { if client.creeconn != nil && !client.config.needRefreshCredential() { return do(client.creeconn) } product := "cr" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, string(CRCode), endpoint) } creeconn, err := cr_ee.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the CR EE client: %#v", err) } creeconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) creeconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) creeconn.SourceIp = client.config.SourceIp creeconn.SecureTransport = client.config.SecureTransport client.creeconn = creeconn return do(client.creeconn) } func (client *AliyunClient) WithCdnClient(do func(*cdn.CdnClient) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() // Initialize the CDN client if necessary if client.cdnconn == nil { cdnconn := cdn.NewClient(client.config.AccessKey, client.config.SecretKey) cdnconn.SetBusinessInfo(businessInfoKey) cdnconn.SetUserAgent(client.getUserAgent()) cdnconn.SetSecurityToken(client.config.SecurityToken) endpoint := client.config.CdnEndpoint if endpoint == "" { endpoint = loadEndpoint(client.config.RegionId, CDNCode) } if endpoint != "" && !strings.HasPrefix(endpoint, "http") { cdnconn.SetEndpoint(fmt.Sprintf("https://%s", strings.TrimPrefix(endpoint, "://"))) } client.cdnconn = cdnconn } return do(client.cdnconn) } func (client *AliyunClient) WithCdnClient_new(do func(*cdn_new.Client) (interface{}, error)) (interface{}, error) { if client.cdnconn_new != nil && !client.config.needRefreshCredential() { return do(client.cdnconn_new) } product := "cdn" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, string(CDNCode), endpoint) } cdnconn, err := cdn_new.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the CDN client: %#v", err) } cdnconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) cdnconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) cdnconn.SourceIp = client.config.SourceIp cdnconn.SecureTransport = client.config.SecureTransport client.cdnconn_new = cdnconn return do(client.cdnconn_new) } // WithOtsClient init ots openapi publish sdk client(if necessary), and exec do func by client func (client *AliyunClient) WithOtsClient(do func(*ots.Client) (interface{}, error)) (interface{}, error) { if client.otsconn != nil && !client.config.needRefreshCredential() { return do(client.otsconn) } product := "ots" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } otsconn, err := ots.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the OTS client: %#v", err) } otsconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) otsconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) otsconn.SourceIp = client.config.SourceIp otsconn.SecureTransport = client.config.SecureTransport client.otsconn = otsconn return do(client.otsconn) } // NewOtsRoaClient rpc client for common sdk func (client *AliyunClient) NewOtsRoaClient(productCode string) (*roa.Client, error) { // first, load endpoint by user setting if v, ok := client.config.Endpoints.Load(productCode); !ok || v.(string) == "" { // second, load endpoint by serverside rule if err := client.loadEndpoint(productCode); err != nil { return nil, err } } // set endpoint endpoint := "" if v, ok := client.config.Endpoints.Load(productCode); ok && v.(string) != "" { endpoint = v.(string) } if endpoint == "" { return nil, fmt.Errorf("[ERROR] missing the product %s endpoint", productCode) } sdkConfig := client.teaRoaSdkConfig sdkConfig.SetEndpoint(endpoint) accessKey, secretKey, securityToken := client.config.GetRefreshCredential() sdkConfig.SetAccessKeyId(accessKey) sdkConfig.SetAccessKeySecret(secretKey) sdkConfig.SetSecurityToken(securityToken) conn, err := roa.NewClient(&sdkConfig) if err != nil { return nil, fmt.Errorf("unable to initialize the %s client: %#v", productCode, err) } return conn, nil } func (client *AliyunClient) WithCmsClient(do func(*cms.Client) (interface{}, error)) (interface{}, error) { if client.cmsconn != nil && !client.config.needRefreshCredential() { return do(client.cmsconn) } product := "cms" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } cmsconn, err := cms.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the CMS client: %#v", err) } cmsconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) cmsconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) cmsconn.SourceIp = client.config.SourceIp cmsconn.SecureTransport = client.config.SecureTransport client.cmsconn = cmsconn return do(client.cmsconn) } func (client *AliyunClient) WithLogPopClient(do func(*slsPop.Client) (interface{}, error)) (interface{}, error) { if client.logpopconn != nil && !client.config.needRefreshCredential() { return do(client.logpopconn) } product := "sls" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } logpopconn, err := slsPop.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the sls client: %#v", err) } logpopconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) logpopconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) logpopconn.SourceIp = client.config.SourceIp logpopconn.SecureTransport = client.config.SecureTransport endpoint = strings.TrimPrefix(strings.TrimPrefix(endpoint, "https://"), "http://") logpopconn.Domain = endpoint + "/open-api" client.logpopconn = logpopconn return do(client.logpopconn) } func (client *AliyunClient) WithLogClient(do func(*sls.Client) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() if client.logconn != nil && !client.config.needRefreshCredential() { return do(client.logconn) } product := "sls" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if !strings.HasPrefix(endpoint, "http") { endpoint = fmt.Sprintf("https://%s", strings.TrimPrefix(endpoint, "://")) } accessKey, secretKey, securityToken := client.config.GetRefreshCredential() client.logconn = &sls.Client{ AccessKeyID: accessKey, AccessKeySecret: secretKey, Endpoint: endpoint, SecurityToken: securityToken, UserAgent: client.getUserAgent(), } return do(client.logconn) } func (client *AliyunClient) WithDrdsClient(do func(*drds.Client) (interface{}, error)) (interface{}, error) { if client.drdsconn != nil && !client.config.needRefreshCredential() { return do(client.drdsconn) } product := "drds" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } drdsconn, err := drds.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the DRDS client: %#v", err) } drdsconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) drdsconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) drdsconn.SourceIp = client.config.SourceIp drdsconn.SecureTransport = client.config.SecureTransport client.drdsconn = drdsconn return do(client.drdsconn) } func (client *AliyunClient) WithDdsClient(do func(*dds.Client) (interface{}, error)) (interface{}, error) { if client.ddsconn != nil && !client.config.needRefreshCredential() { return do(client.ddsconn) } product := "dds" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } ddsconn, err := dds.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the mongoDB client: %#v", err) } ddsconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) ddsconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) ddsconn.SourceIp = client.config.SourceIp ddsconn.SecureTransport = client.config.SecureTransport client.ddsconn = ddsconn return do(client.ddsconn) } func (client *AliyunClient) WithGpdbClient(do func(*gpdb.Client) (interface{}, error)) (interface{}, error) { if client.gpdbconn != nil && !client.config.needRefreshCredential() { return do(client.gpdbconn) } product := "gpdb" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } gpdbconn, err := gpdb.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the GPDB client: %#v", err) } gpdbconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) gpdbconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) gpdbconn.SourceIp = client.config.SourceIp gpdbconn.SecureTransport = client.config.SecureTransport client.gpdbconn = gpdbconn return do(client.gpdbconn) } func (client *AliyunClient) WithFcClient(do func(*fc.Client) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() if client.fcconn != nil && !client.config.needRefreshCredential() { return do(client.fcconn) } product := "fc" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if strings.HasPrefix(endpoint, "http") { endpoint = strings.TrimPrefix(strings.TrimPrefix(endpoint, "http://"), "https://") } config := client.getSdkConfig(0) transport := config.HttpTransport // Receiving proxy config from environment transport.Proxy = http.ProxyFromEnvironment clientOptions := []fc.ClientOption{fc.WithSecurityToken(client.config.SecurityToken), fc.WithTransport(transport), fc.WithTimeout(30), fc.WithRetryCount(DefaultClientRetryCountSmall)} accessKey, secretKey, secretToken := client.config.GetRefreshCredential() fcconn, err := fc.NewClient(fmt.Sprintf("https://%s", endpoint), string(ApiVersion20160815), accessKey, secretKey, clientOptions...) if err != nil { return nil, fmt.Errorf("unable to initialize the FC client: %#v", err) } fcconn.Config.UserAgent = client.config.getUserAgent() fcconn.Config.SecurityToken = secretToken client.fcconn = fcconn return do(client.fcconn) } func (client *AliyunClient) WithCloudApiClient(do func(*cloudapi.Client) (interface{}, error)) (interface{}, error) { if client.cloudapiconn != nil && !client.config.needRefreshCredential() { return do(client.cloudapiconn) } product := "cloudapi" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.RegionId, product, endpoint) } cloudapiconn, err := cloudapi.NewClientWithOptions(client.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the CloudAPI client: %#v", err) } cloudapiconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) cloudapiconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) cloudapiconn.SourceIp = client.config.SourceIp cloudapiconn.SecureTransport = client.config.SecureTransport client.cloudapiconn = cloudapiconn return do(client.cloudapiconn) } func (client *AliyunClient) NewTeaCommonClient(endpoint string) (*rpc.Client, error) { sdkConfig := client.teaSdkConfig sdkConfig.SetEndpoint(endpoint) credential, err := client.config.Credential.GetCredential() if err == nil && credential != nil { sdkConfig.SetAccessKeyId(*credential.AccessKeyId) sdkConfig.SetAccessKeySecret(*credential.AccessKeySecret) sdkConfig.SetSecurityToken(client.config.SecurityToken) } else { log.Printf("get credential error: %#v", err) } conn, err := rpc.NewClient(&sdkConfig) if err != nil { return nil, fmt.Errorf("unable to initialize the tea client: %#v", err) } return conn, nil } func (client *AliyunClient) NewTeaRoaCommonClient(endpoint string) (*roa.Client, error) { sdkConfig := client.teaRoaSdkConfig sdkConfig.SetEndpoint(endpoint) credential, err := client.config.Credential.GetCredential() if err == nil && credential != nil { sdkConfig.SetAccessKeyId(*credential.AccessKeyId) sdkConfig.SetAccessKeySecret(*credential.AccessKeySecret) sdkConfig.SetSecurityToken(client.config.SecurityToken) } else { log.Printf("get credential error: %#v", err) } conn, err := roa.NewClient(&sdkConfig) if err != nil { return nil, fmt.Errorf("unable to initialize the tea roa client: %#v", err) } return conn, nil } func (client *AliyunClient) WithDataHubClient(do func(api datahub.DataHubApi) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() // Initialize the DataHub client if necessary if client.dhconn == nil { endpoint := client.config.DatahubEndpoint if endpoint == "" { endpoint = loadEndpoint(client.RegionId, DATAHUBCode) } if endpoint == "" { if client.RegionId == string(APSouthEast1) { endpoint = "dh-singapore.aliyuncs.com" } else { endpoint = fmt.Sprintf("dh-%s.aliyuncs.com", client.RegionId) } } if !strings.HasPrefix(endpoint, "http") { endpoint = fmt.Sprintf("https://%s", endpoint) } account := datahub.NewStsCredential(client.config.AccessKey, client.config.SecretKey, client.config.SecurityToken) config := &datahub.Config{ UserAgent: client.getUserAgent(), } client.dhconn = datahub.NewClientWithConfig(endpoint, config, account) } return do(client.dhconn) } func (client *AliyunClient) WithElasticsearchClient(do func(*elasticsearch.Client) (interface{}, error)) (interface{}, error) { if client.elasticsearchconn != nil && !client.config.needRefreshCredential() { return do(client.elasticsearchconn) } product := "elasticsearch" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } elasticsearchconn, err := elasticsearch.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the Elasticsearch client: %#v", err) } elasticsearchconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) elasticsearchconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) elasticsearchconn.SourceIp = client.config.SourceIp elasticsearchconn.SecureTransport = client.config.SecureTransport client.elasticsearchconn = elasticsearchconn return do(client.elasticsearchconn) } func (client *AliyunClient) WithMnsClient(do func(*ali_mns.MNSClient) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() // Initialize the MNS client if necessary if client.mnsconn == nil { endpoint := client.config.MnsEndpoint if endpoint == "" { endpoint = loadEndpoint(client.config.RegionId, MNSCode) if endpoint == "" { endpoint = fmt.Sprintf("%s.aliyuncs.com", client.config.RegionId) } } accountId, err := client.AccountId() if err != nil { return nil, err } if strings.HasPrefix(endpoint, "http") { endpoint = strings.TrimPrefix(strings.TrimPrefix(endpoint, "http://"), "https://") } mnsUrl := fmt.Sprintf("https://%s.mns.%s", accountId, endpoint) accessKey, secretKey, token := client.config.GetRefreshCredential() mnsClient := ali_mns.NewAliMNSClientWithToken(mnsUrl, accessKey, secretKey, token) proxy, err := client.getHttpProxy() if proxy != nil { skip, err := client.skipProxy(endpoint) if err != nil { return nil, err } if !skip { mnsClient.SetProxy(proxy.String()) } } client.mnsconn = &mnsClient } return do(client.mnsconn) } func (client *AliyunClient) WithMnsQueueManager(do func(ali_mns.AliQueueManager) (interface{}, error)) (interface{}, error) { return client.WithMnsClient(func(mnsClient *ali_mns.MNSClient) (interface{}, error) { queueManager := ali_mns.NewMNSQueueManager(*mnsClient) return do(queueManager) }) } func (client *AliyunClient) WithMnsTopicManager(do func(ali_mns.AliTopicManager) (interface{}, error)) (interface{}, error) { return client.WithMnsClient(func(mnsClient *ali_mns.MNSClient) (interface{}, error) { topicManager := ali_mns.NewMNSTopicManager(*mnsClient) return do(topicManager) }) } func (client *AliyunClient) WithMnsSubscriptionManagerByTopicName(topicName string, do func(ali_mns.AliMNSTopic) (interface{}, error)) (interface{}, error) { return client.WithMnsClient(func(mnsClient *ali_mns.MNSClient) (interface{}, error) { subscriptionManager := ali_mns.NewMNSTopic(topicName, *mnsClient) return do(subscriptionManager) }) } func (client *AliyunClient) WithTableStoreClient(instanceName string, do func(*tablestore.TableStoreClient) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() // Initialize the TABLESTORE client if necessary tableStoreClient, ok := client.tablestoreconnByInstanceName[instanceName] if ok && !client.config.needRefreshCredential() { return do(tableStoreClient) } endpoint := client.config.OtsEndpoint if endpoint == "" { endpoint = loadEndpoint(client.RegionId, OTSCode) } if endpoint == "" { endpoint = fmt.Sprintf("%s.%s.ots.aliyuncs.com", instanceName, client.RegionId) } if !strings.HasPrefix(endpoint, "https") && !strings.HasPrefix(endpoint, "http") { endpoint = fmt.Sprintf("https://%s", endpoint) } externalHeaders := make(map[string]string) if client.config.SecureTransport == "false" || client.config.SecureTransport == "true" { externalHeaders["x-ots-issecuretransport"] = client.config.SecureTransport } if client.config.SourceIp != "" { externalHeaders["x-ots-sourceip"] = client.config.SourceIp } accessKey, secretKey, token := client.config.GetRefreshCredential() tableStoreClient = tablestore.NewClientWithExternalHeader(endpoint, instanceName, accessKey, secretKey, token, tablestore.NewDefaultTableStoreConfig(), externalHeaders) client.tablestoreconnByInstanceName[instanceName] = tableStoreClient return do(tableStoreClient) } func (client *AliyunClient) WithTableStoreTunnelClient(instanceName string, do func(otsTunnel.TunnelClient) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() // Initialize the TABLESTORE tunnel client if necessary tunnelClient, ok := client.otsTunnelConnByInstanceName[instanceName] if ok && !client.config.needRefreshCredential() { return do(tunnelClient) } endpoint := client.config.OtsEndpoint if endpoint == "" { endpoint = loadEndpoint(client.RegionId, OTSCode) } if endpoint == "" { endpoint = fmt.Sprintf("%s.%s.ots.aliyuncs.com", instanceName, client.RegionId) } if !strings.HasPrefix(endpoint, "https") && !strings.HasPrefix(endpoint, "http") { endpoint = fmt.Sprintf("https://%s", endpoint) } externalHeaders := make(map[string]string) if client.config.SecureTransport == "false" || client.config.SecureTransport == "true" { externalHeaders["x-ots-issecuretransport"] = client.config.SecureTransport } if client.config.SourceIp != "" { externalHeaders["x-ots-sourceip"] = client.config.SourceIp } accessKey, secretKey, token := client.config.GetRefreshCredential() tunnelClient = otsTunnel.NewTunnelClientWithConfigAndExternalHeader(endpoint, instanceName, accessKey, secretKey, token, otsTunnel.DefaultTunnelConfig, externalHeaders) client.otsTunnelConnByInstanceName[instanceName] = tunnelClient return do(tunnelClient) } func (client *AliyunClient) WithCsProjectClient(clusterId, endpoint string, clusterCerts cs.ClusterCerts, do func(*cs.ProjectClient) (interface{}, error)) (interface{}, error) { goSdkMutex.Lock() defer goSdkMutex.Unlock() // Initialize the PROJECT client if necessary key := fmt.Sprintf("%s|%s|%s|%s|%s", clusterId, endpoint, clusterCerts.CA, clusterCerts.Cert, clusterCerts.Key) csProjectClient, ok := client.csprojectconnByKey[key] if !ok { var err error csProjectClient, err = cs.NewProjectClient(clusterId, endpoint, clusterCerts) if err != nil { return nil, fmt.Errorf("Getting Application Client failed by cluster id %s: %#v.", clusterCerts, err) } csProjectClient.SetDebug(false) csProjectClient.SetUserAgent(client.config.getUserAgent()) client.csprojectconnByKey[key] = csProjectClient } return do(csProjectClient) } func (client *AliyunClient) NewCommonRequest(product, serviceCode, schema string, apiVersion ApiVersion) (*requests.CommonRequest, error) { endpoint := "" product = strings.ToLower(product) if _, exist := client.config.Endpoints.Load(product); !exist { if err := client.loadEndpoint(product); err != nil { return nil, err } } if v, exist := client.config.Endpoints.Load(product); exist && v.(string) != "" { endpoint = v.(string) } request := requests.NewCommonRequest() // Use product code to find product domain if endpoint != "" { request.Domain = endpoint } else { // When getting endpoint failed by location, using custom endpoint instead request.Domain = fmt.Sprintf("%s.%s.aliyuncs.com", strings.ToLower(serviceCode), client.RegionId) } request.Version = string(apiVersion) request.RegionId = client.RegionId request.Product = product request.Scheme = schema request.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) request.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) request.AppendUserAgent(Terraform, client.config.TerraformVersion) request.AppendUserAgent(Provider, providerVersion) request.AppendUserAgent(Module, client.config.ConfigurationSource) request.AppendUserAgent(TerraformTraceId, client.config.TerraformTraceId) return request, nil } func (client *AliyunClient) AccountId() (string, error) { if client.accountId != "" { return client.accountId, nil } client.accountIdMutex.Lock() defer client.accountIdMutex.Unlock() log.Printf("[DEBUG] account_id not provided, attempting to retrieve it automatically...") identity, err := client.GetCallerIdentity() if err != nil { return "", err } if identity.AccountId == "" { return "", fmt.Errorf("caller identity doesn't contain any AccountId") } client.accountId = identity.AccountId return client.accountId, nil } // getAccountType determines and returns the account type (Domestic or International) based on the client's configuration and API endpoint. // This function first checks if the AccountType is already set in the client configuration. If so, it returns that value directly. // Otherwise, it defaults the account type to "Domestic" and initializes a request to query available instances through the BssOpenApi API. // It then determines whether the account is domestic or international based on the API specific errors. // If there is a specific error, the account type should be updates, and meantime corrects the BssOpenApi endpoint. func (client *AliyunClient) getAccountType() string { if client.config.AccountType != "" { return client.config.AccountType } // Default to Domestic accountType := "Domestic" productCode := strings.ToLower("BssOpenApi") request := map[string]interface{}{ "PageSize": "50", "PageNum": 1, "ProductCode": "vipcloudfw", "ProductType": "vipcloudfw", "SubscriptionType": "Subscription", } endpoint, err := client.loadApiEndpoint(productCode) if err != nil { log.Printf("[WARN] getting BssOpenApi endpoint failed. Error: %v", err) } else if endpoint == BssOpenAPIEndpointInternational { request["ProductCode"] = "cfw" request["ProductType"] = "cfw_pre_intl" accountType = "International" } wait := incrementalWait(1*time.Second, 0*time.Second) resource.Retry(30*time.Second, func() *resource.RetryError { _, err := client.RpcPost("BssOpenApi", "2017-12-14", "QueryAvailableInstances", nil, request, true) log.Printf("[WARN] checking caller identity's account type by invoking BssOpenApi QueryAvailableInstances failed. Error: %v", err) if err != nil { if needRetry(err) { wait() return resource.RetryableError(err) } if isExpectedErrors(err, []string{"NotApplicable", "not found article by given param"}) { if request["ProductType"] == "vipcloudfw" { accountType = "International" client.config.Endpoints.Store(productCode, BssOpenAPIEndpointInternational) } else { accountType = "Domestic" client.config.Endpoints.Store(productCode, BssOpenAPIEndpointDomestic) } } else { accountType = "" } } return nil }) return accountType } func (client *AliyunClient) IsInternationalAccount() bool { return client.config.AccountType == "International" } func (client *AliyunClient) isInternationalRegion() bool { if client.config.RegionId == "cn-hongkong" { return true } return !strings.HasPrefix(client.config.RegionId, "cn-") } func (client *AliyunClient) getSdkConfig(timeout time.Duration) *sdk.Config { if timeout == 0 { timeout = time.Duration(30) * time.Second } // WithUserAgent will add a prefix Extra/ for user agent value return sdk.NewConfig(). WithMaxRetryTime(DefaultClientRetryCountSmall). WithTimeout(timeout). WithEnableAsync(false). WithGoRoutinePoolSize(100). WithMaxTaskQueueSize(10000). WithDebug(false). WithHttpTransport(client.getTransport()). WithScheme(client.config.Protocol). WithUserAgent(fmt.Sprintf("Terraform %s", client.config.getUserAgent())) } func (client *AliyunClient) getUserAgent() string { return fmt.Sprintf("%s/%s %s/%s %s/%s", Terraform, client.config.TerraformVersion, Provider, providerVersion, Module, client.config.ConfigurationSource) } func (client *AliyunClient) getTransport() *http.Transport { handshakeTimeout, err := strconv.Atoi(os.Getenv("TLSHandshakeTimeout")) if err != nil { handshakeTimeout = 120 } transport := &http.Transport{} transport.TLSHandshakeTimeout = time.Duration(handshakeTimeout) * time.Second return transport } func (client *AliyunClient) getHttpProxy() (proxy *url.URL, err error) { if client.config.Protocol == "HTTPS" { if rawurl := os.Getenv("HTTPS_PROXY"); rawurl != "" { proxy, err = url.Parse(rawurl) } else if rawurl := os.Getenv("https_proxy"); rawurl != "" { proxy, err = url.Parse(rawurl) } } else { if rawurl := os.Getenv("HTTP_PROXY"); rawurl != "" { proxy, err = url.Parse(rawurl) } else if rawurl := os.Getenv("http_proxy"); rawurl != "" { proxy, err = url.Parse(rawurl) } } return proxy, err } func (client *AliyunClient) skipProxy(endpoint string) (bool, error) { var urls []string if rawurl := os.Getenv("NO_PROXY"); rawurl != "" { urls = strings.Split(rawurl, ",") } else if rawurl := os.Getenv("no_proxy"); rawurl != "" { urls = strings.Split(rawurl, ",") } for _, value := range urls { if strings.HasPrefix(value, "*") { value = fmt.Sprintf(".%s", value) } noProxyReg, err := regexp.Compile(value) if err != nil { return false, err } if noProxyReg.MatchString(endpoint) { return true, nil } } return false, nil } func (client *AliyunClient) GetCallerIdentity() (*sts.GetCallerIdentityResponse, error) { args := sts.CreateGetCallerIdentityRequest() endpoint := client.config.StsEndpoint if endpoint == "" { endpoint = loadEndpoint(client.config.RegionId, STSCode) } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, string(STSCode), endpoint) } stsClient, err := sts.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the STS client: %#v", err) } stsClient.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) stsClient.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) stsClient.SourceIp = client.config.SourceIp stsClient.SecureTransport = client.config.SecureTransport identity, err := stsClient.GetCallerIdentity(args) if err != nil { return nil, err } if identity == nil { return nil, fmt.Errorf("caller identity not found") } return identity, err } func (client *AliyunClient) WithDdosbgpClient(do func(*ddosbgp.Client) (interface{}, error)) (interface{}, error) { if client.ddosbgpconn != nil && !client.config.needRefreshCredential() { return do(client.ddosbgpconn) } product := "ddosbgp" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } ddosbgpconn, err := ddosbgp.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the DDOSBGP client: %#v", err) } ddosbgpconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) ddosbgpconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) ddosbgpconn.SourceIp = client.config.SourceIp ddosbgpconn.SecureTransport = client.config.SecureTransport client.ddosbgpconn = ddosbgpconn return do(client.ddosbgpconn) } func (client *AliyunClient) WithAlikafkaClient(do func(*alikafka.Client) (interface{}, error)) (interface{}, error) { if client.alikafkaconn != nil && !client.config.needRefreshCredential() { return do(client.alikafkaconn) } product := "alikafka" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } alikafkaconn, err := alikafka.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the ALIKAFKA client: %#v", err) } alikafkaconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) alikafkaconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) alikafkaconn.SourceIp = client.config.SourceIp alikafkaconn.SecureTransport = client.config.SecureTransport client.alikafkaconn = alikafkaconn return do(client.alikafkaconn) } func (client *AliyunClient) WithEmrClient(do func(*emr.Client) (interface{}, error)) (interface{}, error) { if client.emrconn != nil && !client.config.needRefreshCredential() { return do(client.emrconn) } product := "emr" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } emrConn, err := emr.NewClientWithOptions(client.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the E-MapReduce client: %#v", err) } emrConn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) emrConn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) emrConn.SourceIp = client.config.SourceIp emrConn.SecureTransport = client.config.SecureTransport client.emrconn = emrConn return do(client.emrconn) } func (client *AliyunClient) WithSagClient(do func(*smartag.Client) (interface{}, error)) (interface{}, error) { if client.sagconn != nil && !client.config.needRefreshCredential() { return do(client.sagconn) } product := "smartag" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } sagconn, err := smartag.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the SAG client: %#v", err) } sagconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) sagconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) sagconn.SourceIp = client.config.SourceIp sagconn.SecureTransport = client.config.SecureTransport client.sagconn = sagconn return do(client.sagconn) } func (client *AliyunClient) WithDbauditClient(do func(*yundun_dbaudit.Client) (interface{}, error)) (interface{}, error) { if client.dbauditconn != nil && !client.config.needRefreshCredential() { return do(client.dbauditconn) } product := "yundun_dbaudit" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } dbauditconn, err := yundun_dbaudit.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the DBAUDIT client: %#v", err) } dbauditconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) dbauditconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) dbauditconn.SourceIp = client.config.SourceIp dbauditconn.SecureTransport = client.config.SecureTransport client.dbauditconn = dbauditconn return do(client.dbauditconn) } func (client *AliyunClient) WithMarketClient(do func(*market.Client) (interface{}, error)) (interface{}, error) { if client.marketconn != nil && !client.config.needRefreshCredential() { return do(client.marketconn) } product := "market" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } marketconn, err := market.NewClientWithOptions(client.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the Market client: %#v", err) } marketconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) marketconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) marketconn.SourceIp = client.config.SourceIp marketconn.SecureTransport = client.config.SecureTransport client.marketconn = marketconn return do(client.marketconn) } func (client *AliyunClient) WithHbaseClient(do func(*hbase.Client) (interface{}, error)) (interface{}, error) { if client.hbaseconn != nil && !client.config.needRefreshCredential() { return do(client.hbaseconn) } product := "hbase" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } hbaseconn, err := hbase.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the hbase client: %#v", err) } hbaseconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) hbaseconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) hbaseconn.SourceIp = client.config.SourceIp hbaseconn.SecureTransport = client.config.SecureTransport client.hbaseconn = hbaseconn return do(client.hbaseconn) } func (client *AliyunClient) WithAdbClient(do func(*adb.Client) (interface{}, error)) (interface{}, error) { if client.adbconn != nil && !client.config.needRefreshCredential() { return do(client.adbconn) } product := "adb" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } adbconn, err := adb.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the adb client: %#v", err) } adbconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) adbconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) adbconn.SourceIp = client.config.SourceIp adbconn.SecureTransport = client.config.SecureTransport client.adbconn = adbconn return do(client.adbconn) } func (client *AliyunClient) WithCbnClient(do func(*cbn.Client) (interface{}, error)) (interface{}, error) { if client.cbnConn != nil && !client.config.needRefreshCredential() { return do(client.cbnConn) } product := "cbn" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } cbnConn, err := cbn.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the Cbnclient: %#v", err) } cbnConn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) cbnConn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) cbnConn.SourceIp = client.config.SourceIp cbnConn.SecureTransport = client.config.SecureTransport client.cbnConn = cbnConn return do(client.cbnConn) } func (client *AliyunClient) WithEdasClient(do func(*edas.Client) (interface{}, error)) (interface{}, error) { if client.edasconn != nil && !client.config.needRefreshCredential() { return do(client.edasconn) } product := "edas" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } edasconn, err := edas.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(time.Duration(60)*time.Second), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the EDAS client: %#v", err) } edasconn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) edasconn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) edasconn.SourceIp = client.config.SourceIp edasconn.SecureTransport = client.config.SecureTransport client.edasconn = edasconn return do(client.edasconn) } func (client *AliyunClient) WithAlidnsClient(do func(*alidns.Client) (interface{}, error)) (interface{}, error) { if client.alidnsConn != nil && !client.config.needRefreshCredential() { return do(client.alidnsConn) } product := "alidns" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } alidnsConn, err := alidns.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the Alidnsclient: %#v", err) } alidnsConn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) alidnsConn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) alidnsConn.SourceIp = client.config.SourceIp alidnsConn.SecureTransport = client.config.SecureTransport client.alidnsConn = alidnsConn return do(client.alidnsConn) } func (client *AliyunClient) WithCassandraClient(do func(*cassandra.Client) (interface{}, error)) (interface{}, error) { if client.cassandraConn != nil && !client.config.needRefreshCredential() { return do(client.cassandraConn) } product := "cassandra" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, product, endpoint) } cassandraConn, err := cassandra.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the Cassandraclient: %#v", err) } cassandraConn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) cassandraConn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) cassandraConn.SourceIp = client.config.SourceIp cassandraConn.SecureTransport = client.config.SecureTransport client.cassandraConn = cassandraConn return do(client.cassandraConn) } func (client *AliyunClient) WithEciClient(do func(*eci.Client) (interface{}, error)) (interface{}, error) { if client.eciConn != nil && !client.config.needRefreshCredential() { return do(client.eciConn) } product := "eci" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, string(EciCode), endpoint) } eciConn, err := eci.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the Eciclient: %#v", err) } eciConn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) eciConn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) eciConn.SourceIp = client.config.SourceIp eciConn.SecureTransport = client.config.SecureTransport client.eciConn = eciConn return do(client.eciConn) } func (client *AliyunClient) WithRKvstoreClient(do func(*r_kvstore.Client) (interface{}, error)) (interface{}, error) { if client.r_kvstoreConn != nil && !client.config.needRefreshCredential() { return do(client.r_kvstoreConn) } product := "r_kvstore" endpoint, err := client.loadApiEndpoint(product) if err != nil { return nil, err } if endpoint != "" { endpoints.AddEndpointMapping(client.config.RegionId, "r-kvstore", endpoint) } r_kvstoreConn, err := r_kvstore.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(0), client.config.getAuthCredential(true)) if err != nil { return nil, fmt.Errorf("unable to initialize the RKvstoreclient: %#v", err) } r_kvstoreConn.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond) r_kvstoreConn.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond) r_kvstoreConn.SourceIp = client.config.SourceIp r_kvstoreConn.SecureTransport = client.config.SecureTransport client.r_kvstoreConn = r_kvstoreConn return do(client.r_kvstoreConn) } func (client *AliyunClient) NewQuotasClientV2() (*openapi.Client, error) { productCode := "quotas" endpoint := "" if v, ok := client.config.Endpoints.Load(productCode); !ok || v.(string) == "" { if err := client.loadEndpoint(productCode); err != nil { endpoint = "quotas.aliyuncs.com" client.config.Endpoints.Store(productCode, endpoint) log.Printf("[ERROR] loading %s endpoint got an error: %#v. Using the central endpoint %s instead.", productCode, err, endpoint) } } if v, ok := client.config.Endpoints.Load(productCode); ok && v.(string) != "" { endpoint = v.(string) } if endpoint == "" { return nil, fmt.Errorf("[ERROR] missing the product %s endpoint.", productCode) } openapiConfig := client.teaRpcOpenapiConfig openapiConfig.Endpoint = tea.String(endpoint) openapiConfig.Protocol = client.teaRpcOpenapiConfig.Protocol result, err := openapi.NewClient(&openapiConfig) if err != nil { return nil, fmt.Errorf("unable to initialize the %s client: %#v", productCode, err) } return result, nil } func (client *AliyunClient) loadApiEndpoint(productCode string) (string, error) { if v, ok := client.config.Endpoints.Load(productCode); !ok || v.(string) == "" { if err := client.loadEndpoint(productCode); err != nil { return "", fmt.Errorf("[ERROR] loading %s endpoint got an error: %#v.", productCode, err) } } else { return client.formatEndpointWithAccountID(productCode, v.(string)) } if v, ok := client.config.Endpoints.Load(productCode); ok && v.(string) != "" { return client.formatEndpointWithAccountID(productCode, v.(string)) } return "", fmt.Errorf("[ERROR] missing the product %s endpoint.", productCode) } // RpcPost invoking RPC API request with POST method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // apiName - API Name // query - API parameters in query // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RpcPost(apiProductCode string, apiVersion string, apiName string, query map[string]interface{}, body map[string]interface{}, autoRetry bool) (map[string]interface{}, error) { return client.rpcRequest("POST", apiProductCode, apiVersion, apiName, query, body, autoRetry, "") } // RpcPostWithEndpoint invoking RPC API request with POST method and specified endpoint // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // apiName - API Name // query - API parameters in query // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error // endpoint - The domain of invoking api func (client *AliyunClient) RpcPostWithEndpoint(apiProductCode string, apiVersion string, apiName string, query map[string]interface{}, body map[string]interface{}, autoRetry bool, endpoint string) (map[string]interface{}, error) { return client.rpcRequest("POST", apiProductCode, apiVersion, apiName, query, body, autoRetry, endpoint) } // RpcGet invoking RPC API request with GET method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // apiName - API Name // query - API parameters in query // body - API parameters in body func (client *AliyunClient) RpcGet(apiProductCode string, apiVersion string, apiName string, query map[string]interface{}, body map[string]interface{}) (map[string]interface{}, error) { return client.rpcRequest("GET", apiProductCode, apiVersion, apiName, query, body, true, "") } func (client *AliyunClient) rpcRequest(method string, apiProductCode string, apiVersion string, apiName string, query map[string]interface{}, body map[string]interface{}, autoRetry bool, endpoint string) (map[string]interface{}, error) { var err error if endpoint == "" { apiProductCode = strings.ToLower(ConvertKebabToSnake(apiProductCode)) endpoint, err = client.loadApiEndpoint(apiProductCode) if err != nil { return nil, err } } sdkConfig := client.teaSdkConfig sdkConfig.SetEndpoint(endpoint) credential, err := client.config.Credential.GetCredential() if err != nil || credential == nil { return nil, fmt.Errorf("get credential failed. Error: %#v", err) } sdkConfig.SetAccessKeyId(*credential.AccessKeyId) sdkConfig.SetAccessKeySecret(*credential.AccessKeySecret) sdkConfig.SetSecurityToken(*credential.SecurityToken) conn, err := rpc.NewClient(&sdkConfig) if err != nil { return nil, fmt.Errorf("unable to initialize the %s api client: %#v", apiProductCode, err) } runtime := &util.RuntimeOptions{} runtime.SetAutoretry(autoRetry) response, err := conn.DoRequest(tea.String(apiName), nil, tea.String(method), tea.String(apiVersion), tea.String("AK"), query, body, runtime) return response, formatError(response, err) } // RoaPost invoking ROA API request with POST method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RoaPost(apiProductCode string, apiVersion string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { return client.roaRequest("POST", apiProductCode, apiVersion, "", pathName, query, headers, body, autoRetry) } // RoaPut invoking ROA API request with PUT method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RoaPut(apiProductCode string, apiVersion string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { return client.roaRequest("PUT", apiProductCode, apiVersion, "", pathName, query, headers, body, autoRetry) } // RoaGet invoking ROA API request with GET method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body func (client *AliyunClient) RoaGet(apiProductCode string, apiVersion string, pathName string, query map[string]*string, headers map[string]*string, body interface{}) (map[string]interface{}, error) { return client.roaRequest("GET", apiProductCode, apiVersion, "", pathName, query, headers, body, true) } // RoaDelete invoking ROA API request with DELETE method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RoaDelete(apiProductCode string, apiVersion string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { return client.roaRequest("DELETE", apiProductCode, apiVersion, "", pathName, query, headers, body, autoRetry) } // RoaPatch invoking ROA API request with PATCH method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RoaPatch(apiProductCode string, apiVersion string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { return client.roaRequest("PATCH", apiProductCode, apiVersion, "", pathName, query, headers, body, autoRetry) } // RoaPostWithApiName invoking ROA API request with POST method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // apiName - Request path name // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RoaPostWithApiName(apiProductCode string, apiVersion string, apiName string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { return client.roaRequest("POST", apiProductCode, apiVersion, apiName, pathName, query, headers, body, autoRetry) } // RoaPutWithApiName invoking ROA API request with PUT method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // apiName - Request path name // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RoaPutWithApiName(apiProductCode string, apiVersion string, apiName string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { return client.roaRequest("PUT", apiProductCode, apiVersion, apiName, pathName, query, headers, body, autoRetry) } // RoaGetWithApiName invoking ROA API request with GET method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // apiName - Request path name // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body func (client *AliyunClient) RoaGetWithApiName(apiProductCode string, apiVersion string, apiName string, pathName string, query map[string]*string, headers map[string]*string, body interface{}) (map[string]interface{}, error) { return client.roaRequest("GET", apiProductCode, apiVersion, apiName, pathName, query, headers, body, true) } // RoaDeleteWithApiName invoking ROA API request with DELETE method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // apiName - Request path name // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RoaDeleteWithApiName(apiProductCode string, apiVersion string, apiName string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { return client.roaRequest("DELETE", apiProductCode, apiVersion, apiName, pathName, query, headers, body, autoRetry) } // RoaPatchWithApiName invoking ROA API request with PATCH method // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiVersion - API version // apiName - Request path name // pathName - Request path name // query - API parameters in query // headers - API parameters in headers // body - API parameters in body // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) RoaPatchWithApiName(apiProductCode string, apiVersion string, apiName string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { return client.roaRequest("PATCH", apiProductCode, apiVersion, apiName, pathName, query, headers, body, autoRetry) } func (client *AliyunClient) roaRequest(method string, apiProductCode string, apiVersion string, apiName string, pathName string, query map[string]*string, headers map[string]*string, body interface{}, autoRetry bool) (map[string]interface{}, error) { apiProductCode = strings.ToLower(ConvertKebabToSnake(apiProductCode)) endpoint, err := client.loadApiEndpoint(apiProductCode) if err != nil { return nil, err } sdkConfig := client.teaRoaSdkConfig sdkConfig.SetEndpoint(endpoint) credential, err := client.config.Credential.GetCredential() if err != nil || credential == nil { return nil, fmt.Errorf("get credential failed. Error: %#v", err) } sdkConfig.SetAccessKeyId(*credential.AccessKeyId) sdkConfig.SetAccessKeySecret(*credential.AccessKeySecret) sdkConfig.SetSecurityToken(*credential.SecurityToken) conn, err := roa.NewClient(&sdkConfig) if err != nil { return nil, fmt.Errorf("unable to initialize the %s api client: %#v", apiProductCode, err) } var response map[string]interface{} runtime := &util.RuntimeOptions{} runtime.SetAutoretry(autoRetry) if apiName != "" { response, err = conn.DoRequestWithAction(tea.String(apiName), tea.String(apiVersion), nil, tea.String(method), tea.String("AK"), tea.String(pathName), query, headers, body, runtime) } else { response, err = conn.DoRequest(tea.String(apiVersion), nil, tea.String(method), tea.String("AK"), tea.String(pathName), query, headers, body, runtime) } if respBody, isExist := response["body"]; isExist && respBody != nil { response = respBody.(map[string]interface{}) } return response, formatError(response, err) } // Do invoking API request with SDK v2 // parameters: // // apiProductCode: API Product code, its value equals to the gateway code of the API // apiParams - API params // query - API parameters in query // body - API parameters in body // headers - API parameters in headers // hostMap - API parameters in hostMap // autoRetry - whether to auto retry while the runtime has a 5xx error func (client *AliyunClient) Do(apiProductCode string, apiParams *openapi.Params, query map[string]*string, body interface{}, headers map[string]*string, hostMap map[string]*string, autoRetry bool) (map[string]interface{}, error) { apiProductCode = strings.ToLower(ConvertKebabToSnake(apiProductCode)) endpoint, err := client.loadApiEndpoint(apiProductCode) if err != nil { return nil, err } sdkConfig := client.teaRoaOpenapiConfig if apiParams.Style != nil && *apiParams.Style == "RPC" { sdkConfig = client.teaRpcOpenapiConfig } if apiProductCode == "sls" { sdkConfig = openapi.Config{} } if apiParams.Protocol == nil || *apiParams.Protocol == "" { apiParams.Protocol = tea.String(client.config.Protocol) } sdkConfig.SetEndpoint(endpoint) credential, err := client.config.Credential.GetCredential() if err != nil || credential == nil { return nil, fmt.Errorf("get credential failed. Error: %#v", err) } sdkConfig.SetAccessKeyId(*credential.AccessKeyId) sdkConfig.SetAccessKeySecret(*credential.AccessKeySecret) sdkConfig.SetSecurityToken(*credential.SecurityToken) sdkConfig.SetUserAgent(client.config.getUserAgent()) openapiClient, err := openapi.NewClient(&sdkConfig) if err != nil { return nil, fmt.Errorf("unable to initialize the %s api client: %#v", apiProductCode, err) } if apiProductCode == "oss" { openapiClient.Spi, err = ossclient.NewClient() if err != nil { return nil, fmt.Errorf("unable to initialize the %s api client: %#v", apiProductCode, err) } // SignVersion if ossV, ok := client.config.SignVersion.Load("oss"); ok { openapiClient.SignatureVersion = tea.String(ossV.(string)) } } if apiProductCode == "sls" { openapiClient.Spi, err = gatewayclient.NewClient() if err != nil { return nil, fmt.Errorf("unable to initialize the %s api client: %#v", apiProductCode, err) } openapiClient.Protocol = tea.String(client.config.Protocol) } var response map[string]interface{} runtime := &utilV2.RuntimeOptions{} runtime.SetAutoretry(autoRetry) if apiParams.Style != nil && *apiParams.Style == "RPC" { response, err = openapiClient.CallApi(apiParams, &openapi.OpenApiRequest{Query: query, Body: body, Headers: headers, HostMap: hostMap}, runtime) } else { response, err = openapiClient.Execute(apiParams, &openapi.OpenApiRequest{Query: query, Body: body, Headers: headers, HostMap: hostMap}, runtime) } if respBody, isExist := response["body"]; isExist && respBody != nil { if v, ok := respBody.(map[string]interface{}); ok { response = v } } return response, formatError(response, err) } func formatError(response map[string]interface{}, err error) error { if err != nil { return err } code, ok1 := response["Code"] if !ok1 { code, ok1 = response["code"] } // There is a design in some product api that the response has code with a map type, like FC if ok1 && !(isString(code) || isInteger(code)) { return err } // There is a design in some product api that the request is success but its message is empty and the code is 0 or other string // like ENS, eflo, apig and so on. if ok1 && (strings.ToLower(fmt.Sprint(code)) == "success" || strings.ToLower(fmt.Sprint(code)) == "ok" || fmt.Sprint(code) == "200" || fmt.Sprint(code) == "0") { return err } success, ok2 := response["Success"] if !ok2 { success, ok2 = response["success"] } if ok2 && fmt.Sprint(success) == "true" { return err } message, ok3 := response["Message"] if !ok3 { message, ok3 = response["message"] } if ok3 && (message == nil || fmt.Sprint(message) == "") { return err } if ok1 || ok2 { statusCode := 200 if v, ok := response["StatusCode"]; ok { statusCode = tea.IntValue(v.(*int)) } return tea.NewSDKError(map[string]interface{}{ "statusCode": statusCode, "code": tea.ToString(code), "message": tea.ToString(message), "data": response, }) } return err } func (client *AliyunClient) formatEndpointWithAccountID(productCode string, endpoint string) (string, error) { if endpoint == "" { return endpoint, nil } switch productCode { case "fc_open", "fc": accountId, err := client.AccountId() if err != nil { return endpoint, err } if strings.HasPrefix(endpoint, accountId) { return endpoint, nil } return fmt.Sprintf("%s.%s", accountId, endpoint), nil } return endpoint, nil } type ossCredentials struct { client *AliyunClient } func (defCre *ossCredentials) GetAccessKeyID() string { value, _, _ := defCre.client.config.GetRefreshCredential() return value } func (defCre *ossCredentials) GetAccessKeySecret() string { _, value, _ := defCre.client.config.GetRefreshCredential() return value } func (defCre *ossCredentials) GetSecurityToken() string { _, _, value := defCre.client.config.GetRefreshCredential() return value } type ossCredentialsProvider struct { client *AliyunClient } func (defBuild *ossCredentialsProvider) GetCredentials() oss.Credentials { return &ossCredentials{client: defBuild.client} } func (client *AliyunClient) GetRetryTimeout(defaultTimeout time.Duration) time.Duration { maxRetryTimeout := client.config.MaxRetryTimeout if maxRetryTimeout != 0 { return time.Duration(maxRetryTimeout) * time.Second } return defaultTimeout }