alicloud/connectivity/endpoint.go (622 lines of code) (raw):
package connectivity
import (
"encoding/xml"
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
"strings"
"time"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/aliyun/alibaba-cloud-sdk-go/services/location"
)
// ServiceCode Load endpoints from endpoints.xml or environment variables to meet specified application scenario, like private cloud.
type ServiceCode string
const (
MaxcomputeCode = ServiceCode("MAXCOMPUTE")
CmsCode = ServiceCode("CMS")
RKvstoreCode = ServiceCode("RKVSTORE")
OnsCode = ServiceCode("ONS")
DcdnCode = ServiceCode("DCDN")
MseCode = ServiceCode("MSE")
ActiontrailCode = ServiceCode("ACTIONTRAIL")
OosCode = ServiceCode("OOS")
EcsCode = ServiceCode("ECS")
NasCode = ServiceCode("NAS")
EciCode = ServiceCode("ECI")
DdoscooCode = ServiceCode("DDOSCOO")
BssopenapiCode = ServiceCode("BSSOPENAPI")
AlidnsCode = ServiceCode("ALIDNS")
ResourcemanagerCode = ServiceCode("RESOURCEMANAGER")
WafOpenapiCode = ServiceCode("WAFOPENAPI")
DmsEnterpriseCode = ServiceCode("DMSENTERPRISE")
DnsCode = ServiceCode("DNS")
KmsCode = ServiceCode("KMS")
CbnCode = ServiceCode("CBN")
ECSCode = ServiceCode("ECS")
ESSCode = ServiceCode("ESS")
RAMCode = ServiceCode("RAM")
VPCCode = ServiceCode("VPC")
SLBCode = ServiceCode("SLB")
RDSCode = ServiceCode("RDS")
OSSCode = ServiceCode("OSS")
ONSCode = ServiceCode("ONS")
ALIKAFKACode = ServiceCode("ALIKAFKA")
CONTAINCode = ServiceCode("CS")
CRCode = ServiceCode("CR")
CDNCode = ServiceCode("CDN")
CMSCode = ServiceCode("CMS")
KMSCode = ServiceCode("KMS")
OTSCode = ServiceCode("OTS")
DNSCode = ServiceCode("DNS")
PVTZCode = ServiceCode("PVTZ")
LOGCode = ServiceCode("LOG")
FCCode = ServiceCode("FC")
DDSCode = ServiceCode("DDS")
GPDBCode = ServiceCode("GPDB")
STSCode = ServiceCode("STS")
KVSTORECode = ServiceCode("KVSTORE")
POLARDBCode = ServiceCode("POLARDB")
DATAHUBCode = ServiceCode("DATAHUB")
MNSCode = ServiceCode("MNS")
CLOUDAPICode = ServiceCode("APIGATEWAY")
DRDSCode = ServiceCode("DRDS")
LOCATIONCode = ServiceCode("LOCATION")
ELASTICSEARCHCode = ServiceCode("ELASTICSEARCH")
BSSOPENAPICode = ServiceCode("BSSOPENAPI")
DDOSCOOCode = ServiceCode("DDOSCOO")
DDOSBGPCode = ServiceCode("DDOSBGP")
SAGCode = ServiceCode("SAG")
EMRCode = ServiceCode("EMR")
CasCode = ServiceCode("CAS")
YUNDUNDBAUDITCode = ServiceCode("YUNDUNDBAUDIT")
MARKETCode = ServiceCode("MARKET")
HBASECode = ServiceCode("HBASE")
ADBCode = ServiceCode("ADB")
MAXCOMPUTECode = ServiceCode("MAXCOMPUTE")
EDASCode = ServiceCode("EDAS")
CassandraCode = ServiceCode("CASSANDRA")
)
type Endpoints struct {
Endpoint []Endpoint `xml:"Endpoint"`
}
type Endpoint struct {
Name string `xml:"name,attr"`
RegionIds RegionIds `xml:"RegionIds"`
Products Products `xml:"Products"`
}
type RegionIds struct {
RegionId string `xml:"RegionId"`
}
type Products struct {
Product []Product `xml:"Product"`
}
type Product struct {
ProductName string `xml:"ProductName"`
DomainName string `xml:"DomainName"`
}
var localEndpointPath = "./endpoints.xml"
var localEndpointPathEnv = "TF_ENDPOINT_PATH"
var loadLocalEndpoint = false
func hasLocalEndpoint() bool {
data, err := ioutil.ReadFile(localEndpointPath)
if err != nil || len(data) <= 0 {
d, e := ioutil.ReadFile(os.Getenv(localEndpointPathEnv))
if e != nil {
return false
}
data = d
}
return len(data) > 0
}
func LoadRegionalEndpoint(region string, serviceCode string) string {
if region == "" || serviceCode == "" {
return ""
}
return fmt.Sprintf("%s.%s.aliyuncs.com", serviceCode, region)
}
func loadEndpoint(region string, serviceCode ServiceCode) string {
endpoint := strings.TrimSpace(os.Getenv(fmt.Sprintf("%s_ENDPOINT", string(serviceCode))))
if endpoint != "" {
return endpoint
}
// Load current path endpoint file endpoints.xml, if failed, it will load from environment variables TF_ENDPOINT_PATH
if !loadLocalEndpoint {
return ""
}
data, err := ioutil.ReadFile(localEndpointPath)
if err != nil || len(data) <= 0 {
d, e := ioutil.ReadFile(os.Getenv(localEndpointPathEnv))
if e != nil {
return ""
}
data = d
}
var endpoints Endpoints
err = xml.Unmarshal(data, &endpoints)
if err != nil {
return ""
}
for _, endpoint := range endpoints.Endpoint {
if endpoint.RegionIds.RegionId == string(region) {
for _, product := range endpoint.Products.Product {
if strings.ToLower(product.ProductName) == strings.ToLower(string(serviceCode)) {
return strings.TrimSpace(product.DomainName)
}
}
}
}
return ""
}
// productCodeToLocationCode records all products' code mapping to location
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: location code
var productCodeToLocationCode = map[string]string{
"ecs": "ecs", // ECS
"adb": "ads", //ADB
"ess": "ess", //AutoScaling
"cs": "cs", // ACK
"polardb": "polardb", // PolarDB
"cr": "acr", // CR
"dds": "dds", //MongoDB
"gpdb": "gpdb", //GPDB
"fc_open": "fc", // FC, FCV2
"fc": "fc", // FCV3
"cloudapi": "apigateway",
"apig": "nativeapigw", // APIG
"datahub": "datahub", // DataHub
"mns_open": "mns", // MessageService
"elasticsearch": "elasticsearch", // Elasticsearch
"ddoscoo": "ddoscoo", // DdosCoo
"ddosbgp": "ddosbgp", // DdosBgp
"antiddos_public": "ddosbasic", // DdosBasic
"bssopenapi": "bssopenapi", //BssOpenApi
"alikafka": "alikafka", //AliKafka
"emr": "emr", //EMR
"smartag": "smartag", // Smartag
"yundun_dbaudit": "dbaudit", //DBAudit
"yundun_bastionhost": "bastionhost", //Bastionhost
"hbase": "hbase", //HBase
"edas": "edas", // EDAS
"alidns": "alidns", //Alidns
"cassandra": "cds", //Cassandra
"eci": "eci", // ECI
"dcdn": "dcdn", // DCDN
"r_kvstore": "redisa", // Redis
"ons": "ons", //Ons
"config": "config", //Config
"fnf": "fnf", // FnF
"ros": "ros", // ROS
"mse": "mse", // MSE
"pvtz": "pvtz", //PrivateZone
"privatelink": "privatelink", // PrivateLink
"maxcompute": "odps", //MaxCompute
"resourcesharing": "ressharing", // ResourceManager
"ga": "gaplus", // Ga
"actiontrail": "actiontrail", //ActionTrail
"hitsdb": "hitsdb", //Lindorm
"brain_industrial": "aistudio", //BrainIndustrial
"eipanycast": "eipanycast", // Eipanycast
"oos": "oos", // OOS
"ims": "ims", //IMS
"resourcemanager": "resourcemanager", // ResourceManager
"nas": "nas", //NAS
"dms_enterprise": "dmsenterprise", //DMSEnterprise
"sgw": "hcs_sgw", // CloudStorageGateway
"slb": "slb", // SLB
"kms": "kms", //KMS
"dm": "dm", //DirectMail
"eventbridge": "eventbridge", // EventBridge
"hbr": "hbr", //HBR
"cas": "cas", //SSLCertificatesService
"arms": "arms", // ARMS
"cloudfw": "cloudfirewall", //CloudFirewall
"sae": "serverless", //SAE
"alb": "alb", // ALB
"ecd": "gwsecd", // ECD
"cloudphone": "cloudphone", // ECP
"scdn": "scdn", //SCDN
"dataworks_public": "dide", //DataWorks
"cdn": "cdn", // CDN
"cddc": "cddc", // CDDC
"mscopensubscription": "mscsub", //MscSub
"sddp": "sddp", // SDDP
"sas": "sas", // ThreatDetection
"ehpc": "ehs", // Ehpc
"ens": "ens", // ENS
"iot": "iot", // Iot
"imm": "imm", // IMM
"clickhouse": "clickhouse", // ClickHouse
"selectdb": "selectdb", //SelectDB
"dts": "dts", // DTS
"dg": "dg", // DatabaseGateway
"cloudsso": "cloudsso", // CloudSSO
"swas_open": "swas", // SimpleApplicationServer
"vs": "vs", // VideoSurveillanceSystem
"quickbi_public": "quickbi", // QuickBI
"devops_rdc": "rdcdevops", // RDC
"vod": "vod", // VOD
"opensearch": "opensearch", // OpenSearch
"gdb": "gds", // GraphDatabase
"dbfs": "dbfs", // DBFS
"eais": "eais", // EAIS
"cloudauth": "cloudauth", // Cloudauth
"imp": "imp", // IMP
"mhub": "emas", // MHUB
"servicemesh": "servicemesh", // ServiceMesh
"eds_user": "edsuser", // ECD
"tag": "tag", // Tag
"schedulerx2": "edasschedulerx", // Schedulerx
"dysmsapi": "dysms", // SMS
"vpcpeer": "vpcpeer", // VpcPeer
"dbs": "cbs", // DBS
"nlb": "nlb", // NLB
"ebs": "ebs", // EBS
"bpstudio": "bpstudio", // BPStudio
"das": "hdm", // DAS
"servicecatalog": "srvcatalog", // ServiceCatalog
"eflo": "eflo", //Eflo
"oceanbasepro": "oceanbase", // OceanBase
"chatbot": "beebot", // Chatbot
"computenest": "computenest", // ComputeNest
"drds": "drds", // DRDS
"polardbx": "polardbx", // DRDS
"adcp": "adcp", // AckOne
"sls": "sls", // SLS
"rocketmq": "rmq", // RocketMQ
"resourcecenter": "", // ResourceManager
"hologram": "hologram", // Hologram
"foasconsole": "foasconsole", // RealtimeCompute
"vpc": "vpc", // VPC, VPNGateway,ExpressConnect, CBWP, EIP
"oss": "oss", // OSS
"cms": "cms", // CloudMonitorService
"waf_openapi": "waf", //WAFV3,WAF
"dfs": "alidfs", //DFS
"amqp": "onsproxy", // Amqp
"amqp_open": "onsproxy", // Amqp
"cbn": "cbn", // CEN
"expressconnectrouter": "ecr", // ExpressConnectRouter
"green": "green", // Aligreen
"governance": "governance", // Governance
"ots": "ots", // OTS
"tablestore": "ots", // OTS
"ram": "ram", //RAM
"quotas": "quotas", //Quotas
"market": "market", //Market
"aiworkspace": "paiworkspace", //PAIWorkspace
"vpcipam": "vpcipam", //VpcIpam
"gwlb": "gwlb", // GWLB
"esa": "dcdnservices", // ESA
"live": "live", // Live
"eds_aic": "wycloudphone", // CloudPhone
"cloudcontrol": "cloudcontrol", // CloudControl
"eflo_controller": "efloctrl", // Eflo
"eflo_cnp": "eflocnp", // Eflo-CNP
}
// irregularProductEndpoint specially records those product codes that
// cannot be parsed out by the location service.
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: product endpoint
// The priority of this configuration is higher than location service, lower than user environment variable configuration
var irregularProductEndpoint = map[string]string{
"tablestore": "tablestore.%s.aliyuncs.com",
//"ots": "tablestore.%s.aliyuncs.com", // the old endpoint ots.%s.aliyuncs.com has been deprecated
"ram": "ram.aliyuncs.com",
"brain_industrial": "brain-industrial.cn-hangzhou.aliyuncs.com",
"cassandra": "cassandra.aliyuncs.com",
"cloudfw": "cloudfw.aliyuncs.com",
"scdn": "scdn.aliyuncs.com",
"vpcpeer": "vpcpeer.aliyuncs.com",
"resourcecenter": "resourcecenter.aliyuncs.com",
"market": "market.aliyuncs.com",
"bssopenapi": BssOpenAPIEndpointDomestic,
"esa": "esa.cn-hangzhou.aliyuncs.com",
"cas": "cas.aliyuncs.com",
"sas": "tds.aliyuncs.com",
"ros": "ros.aliyuncs.com",
"eds_aic": "eds-aic.cn-shanghai.aliyuncs.com",
}
// irregularProductEndpointForIntlRegion specially records those product codes that
// cannot be parsed out by the location service and sensitive to region.
// These products adapt to international region, and conflict with irregularProductEndpointForIntlAccount
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: product endpoint
// The priority of this configuration is higher than location service, lower than user environment variable configuration
var irregularProductEndpointForIntlRegion = map[string]string{
"sas": SaSOpenAPIEndpointInternational,
}
// irregularProductEndpointForIntlAccount specially records those product codes that
// cannot be parsed out by the location service and sensitive to account type.
// These products adapt to international account.
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: product endpoint
// The priority of this configuration is higher than location service, lower than user environment variable configuration
var irregularProductEndpointForIntlAccount = map[string]string{
"cloudfw": "cloudfw.ap-southeast-1.aliyuncs.com",
"resourcecenter": "resourcecenter-intl.aliyuncs.com",
"bssopenapi": BssOpenAPIEndpointInternational,
"esa": "esa.ap-southeast-1.aliyuncs.com",
"eds_aic": "eds-aic.ap-southeast-1.aliyuncs.com",
"ros": "ros-intl.aliyuncs.com",
}
// irregularProductEndpointForIntlAccountIntlRegion specially records those product codes that
// cannot be parsed out by the location service and sensitive to account type and region.
// These products adapt to international account.
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: product endpoint
// The priority of this configuration is higher than location service, lower than user environment variable configuration
var irregularProductEndpointForIntlAccountIntlRegion = map[string]string{
"cas": "cas.ap-southeast-1.aliyuncs.com",
}
// regularProductEndpoint specially records those product codes that have been confirmed to be
// regional or central endpoints.
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: product endpoint
// The priority of this configuration is lower than location service, and as a backup endpoint
var regularProductEndpoint = map[string]string{
"ecs": "ecs.%s.aliyuncs.com",
"mse": "mse.%s.aliyuncs.com",
"vpc": "vpc.%s.aliyuncs.com",
"oss": "oss-%s.aliyuncs.com",
"cr": "cr.%s.aliyuncs.com",
"cms": "metrics.%s.aliyuncs.com",
"sls": "%s.log.aliyuncs.com",
"drds": "drds.%s.aliyuncs.com",
"polardbx": "polardbx.%s.aliyuncs.com",
"fc_open": "%s.fc.aliyuncs.com",
"fc": "%s.fc.aliyuncs.com",
"cloudapi": "apigateway.%s.aliyuncs.com",
"mns_open": "mns-open.%s.aliyuncs.com",
"elasticsearch": "elasticsearch.%s.aliyuncs.com",
"alikafka": "alikafka.%s.aliyuncs.com",
"emr": "emr.%s.aliyuncs.com",
"smartag": "smartag.%s.aliyuncs.com",
"alidns": "alidns.%s.aliyuncs.com",
"eci": "eci.%s.aliyuncs.com",
"ons": "ons.%s.aliyuncs.com",
"pvtz": "pvtz.aliyuncs.com",
"privatelink": "privatelink.%s.aliyuncs.com",
"maxcompute": "maxcompute.%s.aliyuncs.com",
"resourcesharing": "resourcesharing.%s.aliyuncs.com",
"actiontrail": "actiontrail.%s.aliyuncs.com",
"hitsdb": "hitsdb.%s.aliyuncs.com",
"oos": "oos.%s.aliyuncs.com",
"nas": "nas.%s.aliyuncs.com",
"dms_enterprise": "dms-enterprise.%s.aliyuncs.com",
"kms": "kms.%s.aliyuncs.com",
"eventbridge": "eventbridge-console.%s.aliyuncs.com",
"hbr": "hbr.%s.aliyuncs.com",
"arms": "arms.%s.aliyuncs.com",
"sae": "sae.%s.aliyuncs.com",
"alb": "alb.%s.aliyuncs.com",
"ecd": "ecd.%s.aliyuncs.com",
"cloudphone": "cloudphone.%s.aliyuncs.com",
"dataworks_public": "dataworks.%s.aliyuncs.com",
"ehpc": "ehpc.%s.aliyuncs.com",
"ens": "ens.aliyuncs.com",
"iot": "iot.%s.aliyuncs.com",
"imm": "imm.%s.aliyuncs.com",
"swas_open": "swas.%s.aliyuncs.com",
"vs": "vs.%s.aliyuncs.com",
"vod": "vod.%s.aliyuncs.com",
"opensearch": "opensearch.%s.aliyuncs.com",
"dbfs": "dbfs.%s.aliyuncs.com",
"eais": "eais.%s.aliyuncs.com",
"servicemesh": "servicemesh.aliyuncs.com",
"tag": "tag.%s.aliyuncs.com",
"schedulerx2": "schedulerx.%s.aliyuncs.com",
"dbs": "dbs-api.%s.aliyuncs.com",
"nlb": "nlb.%s.aliyuncs.com",
"ebs": "ebs.%s.aliyuncs.com",
"eflo": "eflo.%s.aliyuncs.com",
"oceanbasepro": "oceanbasepro.%s.aliyuncs.com",
"adcp": "adcp.%s.aliyuncs.com",
"rocketmq": "rocketmq.%s.aliyuncs.com",
"hologram": "hologram.%s.aliyuncs.com",
"foasconsole": "foasconsole.aliyuncs.com",
"cs": "cs.%s.aliyuncs.com",
"waf_openapi": "wafopenapi.cn-hangzhou.aliyuncs.com",
"dfs": "dfs.%s.aliyuncs.com",
"amqp": "amqp-open.%s.aliyuncs.com",
"amqp_open": "amqp-open.%s.aliyuncs.com",
"cbn": "cbn.aliyuncs.com",
"expressconnectrouter": "expressconnectrouter.cn-shanghai.aliyuncs.com",
"green": "green.%s.aliyuncs.com",
"governance": "governance.cn-hangzhou.aliyuncs.com",
"dysmsapi": "dysmsapi.aliyuncs.com",
"sddp": "sddp.cn-zhangjiakou.aliyuncs.com",
"ddoscoo": "ddoscoo.cn-hangzhou.aliyuncs.com",
"config": "config.cn-shanghai.aliyuncs.com",
"ga": "ga.cn-hangzhou.aliyuncs.com",
"dcdn": "dcdn.aliyuncs.com",
"cdn": "cdn.aliyuncs.com",
"cloudauth": "cloudauth.aliyuncs.com",
"ims": "ims.aliyuncs.com",
"mhub": "mhub.cn-shanghai.aliyuncs.com",
"eds_user": "eds-user.cn-shanghai.aliyuncs.com",
"eipanycast": "eipanycast.cn-hangzhou.aliyuncs.com",
"mscopensubscription": "mscopensubscription.aliyuncs.com",
"resourcemanager": "resourcemanager.aliyuncs.com",
"quotas": "quotas.aliyuncs.com",
"imp": "imp.aliyuncs.com",
"das": "das.cn-shanghai.aliyuncs.com",
"servicecatalog": "servicecatalog.cn-hangzhou.aliyuncs.com",
"chatbot": "chatbot.cn-shanghai.aliyuncs.com",
"computenest": "computenest.cn-hangzhou.aliyuncs.com",
"aiworkspace": "aiworkspace.%s.aliyuncs.com",
"vpcipam": "vpcipam.%s.aliyuncs.com",
"gwlb": "gwlb.%s.aliyuncs.com",
"live": "live.aliyuncs.com",
"dts": "dts.%s.aliyuncs.com",
"dg": "dg.%s.aliyuncs.com",
"cloudsso": "cloudsso.%s.aliyuncs.com",
"quickbi_public": "quickbi.%s.aliyuncs.com",
"ddosbgp": "ddosbgp.%s.aliyuncs.com",
"apig": "apig.%s.aliyuncs.com",
"dds": "mongodb.%s.aliyuncs.com",
"cloudcontrol": "cloudcontrol.aliyuncs.com",
"bpstudio": "bpstudio.cn-hangzhou.aliyuncs.com",
}
// regularProductEndpointForIntlRegion specially records those product codes that have been confirmed to be
// regional or central endpoints. But the endpoints are sensitive to region.
// These products adapt to international region, and conflict with regularProductEndpointForIntlAccount
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: product endpoint
// The priority of this configuration is lower than location service, and as a backup endpoint
var regularProductEndpointForIntlRegion = map[string]string{
"ddoscoo": "ddoscoo.ap-southeast-1.aliyuncs.com",
"eds_user": "eds-user.ap-southeast-1.aliyuncs.com",
"dysmsapi": "dysmsapi.ap-southeast-1.aliyuncs.com",
"sddp": "sddp.ap-southeast-1.aliyuncs.com",
"governance": "governance.ap-southeast-1.aliyuncs.com",
"waf_openapi": "wafopenapi.ap-southeast-1.aliyuncs.com",
"cloudcontrol": "cloudcontrol.ap-southeast-1.aliyuncs.com",
"bpstudio": "bpstudio.ap-southeast-1.aliyuncs.com",
}
// regularProductEndpointForIntlAccount specially records those product codes that have been confirmed to be
// regional or central endpoints. But the endpoints are sensitive to account type.
// These products adapt to international account.
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: product endpoint
// The priority of this configuration is lower than location service, and as a backup endpoint
var regularProductEndpointForIntlAccount = map[string]string{
"config": "config.ap-southeast-1.aliyuncs.com",
"mscopensubscription": "mscopensubscription.ap-southeast-1.aliyuncs.com",
}
// regularProductEndpointForIntlAccountIntlRegion specially records those product codes that have been confirmed to be
// regional or central endpoints. But the endpoints are sensitive to account type and region.
// These products adapt to international account.
// Key: product code, its value equals to the gateway code of the API after converting it to lowercase and using underscores
// Value: product endpoint
// The priority of this configuration is lower than location service, and as a backup endpoint
var regularProductEndpointForIntlAccountIntlRegion = map[string]string{}
// regularProductEndpointReplace specially records some endpoints need to be replaced results from different reasons.
// Key: source endpoint
// Value: replaced endpoint
// The priority of this configuration is lower than other endpoints mapping rules, and as a backup endpoint
var regularProductEndpointReplace = map[string]string{
// ecs, ecs.aliyuncs.com has more higher speed
"ecs-cn-hangzhou.aliyuncs.com": "ecs.aliyuncs.com",
}
// NOTE: The productCode must be lowed.
func (client *AliyunClient) loadEndpoint(productCode string) error {
// Firstly, load endpoint from environment variables
endpoint := strings.TrimSpace(os.Getenv(fmt.Sprintf("ALIBABA_CLOUD_ENDPOINT_%s", strings.ToUpper(productCode))))
if endpoint == "" {
// Compatible with the previous implementation method
endpoint = strings.TrimSpace(os.Getenv(fmt.Sprintf("%s_ENDPOINT", strings.ToUpper(productCode))))
}
if endpoint != "" {
client.config.Endpoints.Store(productCode, endpoint)
return nil
}
// Secondly, load endpoint from known rules
if endpointFmt, ok := irregularProductEndpoint[productCode]; ok {
if v, ok := irregularProductEndpointForIntlRegion[productCode]; ok && client.isInternationalRegion() {
endpointFmt = v
}
if v, ok := irregularProductEndpointForIntlAccount[productCode]; ok && client.IsInternationalAccount() {
endpointFmt = v
}
if v, ok := irregularProductEndpointForIntlAccountIntlRegion[productCode]; ok && client.IsInternationalAccount() && client.isInternationalRegion() {
endpointFmt = v
}
if strings.Contains(endpointFmt, "%s") {
endpointFmt = fmt.Sprintf(endpointFmt, client.RegionId)
}
client.config.Endpoints.Store(productCode, endpointFmt)
return nil
}
// Thirdly, load endpoint from location
endpoint, err := client.describeEndpointForService(productCode)
if err == nil {
if v, ok := regularProductEndpointForIntlAccount[productCode]; ok && client.IsInternationalAccount() {
endpoint = v
}
if v, ok := regularProductEndpointReplace[endpoint]; ok {
endpoint = v
}
client.config.Endpoints.Store(strings.ToLower(productCode), endpoint)
} else if endpointFmt, ok := regularProductEndpoint[productCode]; ok {
if v, ok := regularProductEndpointForIntlRegion[productCode]; ok && client.isInternationalRegion() {
endpointFmt = v
}
if v, ok := regularProductEndpointForIntlAccount[productCode]; ok && client.IsInternationalAccount() {
endpointFmt = v
}
if v, ok := regularProductEndpointForIntlAccountIntlRegion[productCode]; ok && client.IsInternationalAccount() && client.isInternationalRegion() {
endpointFmt = v
}
if strings.Contains(endpointFmt, "%s") {
endpointFmt = fmt.Sprintf(endpointFmt, client.RegionId)
}
if v, ok := regularProductEndpointReplace[endpointFmt]; ok {
endpointFmt = v
}
client.config.Endpoints.Store(productCode, endpointFmt)
log.Printf("[WARN] loading %s endpoint got an error: %#v. Using the endpoint %s instead.", productCode, err, endpointFmt)
return nil
}
return err
}
// Load current path endpoint file endpoints.xml, if failed, it will load from environment variables TF_ENDPOINT_PATH
func (config *Config) loadEndpointFromLocal() error {
data, err := ioutil.ReadFile(localEndpointPath)
if err != nil || len(data) <= 0 {
d, e := ioutil.ReadFile(os.Getenv(localEndpointPathEnv))
if e != nil {
return e
}
data = d
}
var endpoints Endpoints
err = xml.Unmarshal(data, &endpoints)
if err != nil {
return err
}
for _, endpoint := range endpoints.Endpoint {
if endpoint.RegionIds.RegionId == string(config.RegionId) {
for _, product := range endpoint.Products.Product {
config.Endpoints.Store(strings.ToLower(product.ProductName), strings.TrimSpace(product.DomainName))
}
}
}
return nil
}
func incrementalWait(firstDuration time.Duration, increaseDuration time.Duration) func() {
retryCount := 1
return func() {
var waitTime time.Duration
if retryCount == 1 {
waitTime = firstDuration
} else if retryCount > 1 {
waitTime += increaseDuration
}
time.Sleep(waitTime)
retryCount++
}
}
func (client *AliyunClient) describeEndpointForService(productCode string) (string, error) {
locationCode := productCodeToLocationCode[productCode]
if locationCode == "" {
locationCode = productCode
}
args := location.CreateDescribeEndpointsRequest()
args.ServiceCode = locationCode
args.Id = client.config.RegionId
args.Domain = client.config.LocationEndpoint
if args.Domain == "" {
args.Domain = loadEndpoint(client.RegionId, LOCATIONCode)
}
if args.Domain == "" {
args.Domain = "location.aliyuncs.com"
}
locationClient, err := location.NewClientWithOptions(client.config.RegionId, client.getSdkConfig(time.Duration(60)*time.Second), client.config.getAuthCredential(true))
if err != nil {
return "", fmt.Errorf("unable to initialize the location client: %#v", err)
}
locationClient.SetReadTimeout(time.Duration(client.config.ClientReadTimeout) * time.Millisecond)
locationClient.SetConnectTimeout(time.Duration(client.config.ClientConnectTimeout) * time.Millisecond)
locationClient.SourceIp = client.config.SourceIp
locationClient.SecureTransport = client.config.SecureTransport
defer locationClient.Shutdown()
wait := incrementalWait(3*time.Second, 5*time.Second)
var endpointResult string
err = resource.Retry(2*time.Minute, func() *resource.RetryError {
endpointsResponse, err := locationClient.DescribeEndpoints(args)
if err != nil {
re := regexp.MustCompile("^Post [\"]*https://.*")
if err.Error() != "" && re.MatchString(err.Error()) {
wait()
args.Domain = "location-readonly.aliyuncs.com"
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
if endpointsResponse != nil && len(endpointsResponse.Endpoints.Endpoint) > 0 {
for _, e := range endpointsResponse.Endpoints.Endpoint {
if e.Type == "openAPI" {
endpointResult = e.Endpoint
return nil
}
}
}
return nil
})
if err != nil {
return "", fmt.Errorf("Describe %s endpoint using region: %#v got an error: %#v.", productCode, client.RegionId, err)
}
if endpointResult == "" {
return "", fmt.Errorf("There is no any available endpoint for %s in region %s.", productCode, client.RegionId)
}
return endpointResult, nil
}
const (
OpenApiGatewayService = "apigateway.cn-hangzhou.aliyuncs.com"
OpenOtsService = "ots.cn-hangzhou.aliyuncs.com"
OpenOssService = "oss-admin.aliyuncs.com"
OpenNasService = "nas.cn-hangzhou.aliyuncs.com"
OpenCdnService = "cdn.aliyuncs.com"
OpenKmsService = "kms.cn-hangzhou.aliyuncs.com"
OpenSaeService = "sae.cn-hangzhou.aliyuncs.com"
OpenCmsService = "metrics.cn-hangzhou.aliyuncs.com"
OpenDatahubService = "datahub.aliyuncs.com"
OpenOnsService = "ons.cn-hangzhou.aliyuncs.com"
OpenDcdnService = "dcdn.aliyuncs.com"
OpenFcService = "fc-open.cn-hangzhou.aliyuncs.com"
OpenAckService = "cs.aliyuncs.com"
OpenPrivateLinkService = "privatelink.cn-hangzhou.aliyuncs.com"
OpenBrainIndustrialService = "brain-industrial.cn-hangzhou.aliyuncs.com"
OpenIotService = "iot.aliyuncs.com"
OpenVsService = "vs.cn-shanghai.aliyuncs.com"
OpenCrService = "cr.cn-hangzhou.aliyuncs.com"
OpenMaxcomputeService = "maxcompute.aliyuncs.com"
OpenCloudStorageGatewayService = "sgw.cn-shanghai.aliyuncs.com"
DataWorksService = "dataworks.aliyuncs.com"
OpenHbrService = "hbr.aliyuncs.com"
)
const (
BssOpenAPIEndpointDomestic = "business.aliyuncs.com"
BssOpenAPIEndpointInternational = "business.ap-southeast-1.aliyuncs.com"
EcdOpenAPIEndpointUser = "eds-user.ap-southeast-1.aliyuncs.com"
CloudFirewallOpenAPIEndpointControlPolicy = "cloudfw.ap-southeast-1.aliyuncs.com"
SaSOpenAPIEndpointInternational = "tds.ap-southeast-1.aliyuncs.com"
)