github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/alicloud/connectivity/client.go (about) 1 package connectivity 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/url" 7 "os" 8 "regexp" 9 "strconv" 10 "strings" 11 "sync" 12 "time" 13 14 "github.com/aliyun/alibaba-cloud-sdk-go/sdk" 15 "github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints" 16 "github.com/aliyun/alibaba-cloud-sdk-go/services/alidns" 17 "github.com/aliyun/alibaba-cloud-sdk-go/services/ecs" 18 "github.com/aliyun/alibaba-cloud-sdk-go/services/pvtz" 19 "github.com/aliyun/alibaba-cloud-sdk-go/services/ram" 20 "github.com/aliyun/alibaba-cloud-sdk-go/services/rds" 21 "github.com/aliyun/alibaba-cloud-sdk-go/services/slb" 22 "github.com/aliyun/alibaba-cloud-sdk-go/services/vpc" 23 "github.com/aliyun/aliyun-tablestore-go-sdk/tablestore" 24 "github.com/denverdino/aliyungo/cs" 25 "github.com/hashicorp/terraform/terraform" 26 ) 27 28 // AliyunClient of aliyun 29 type AliyunClient struct { 30 Region Region 31 RegionID string 32 AccessKey string 33 SecretKey string 34 SecurityToken string 35 OtsInstanceName string 36 config *Config 37 accountID string 38 ecsconn *ecs.Client 39 rdsconn *rds.Client 40 vpcconn *vpc.Client 41 slbconn *slb.Client 42 dnsconn *alidns.Client 43 ramconn *ram.Client 44 pvtzconn *pvtz.Client 45 tablestoreconnByInstanceName map[string]*tablestore.TableStoreClient 46 csprojectconnByKey map[string]*cs.ProjectClient 47 } 48 49 type APIVersion string 50 51 const DefaultClientRetryCountSmall = 5 52 const Terraform = "HashiCorp-Terraform" 53 const Provider = "Terraform-Provider" 54 const Module = "Terraform-Module" 55 56 var goSdkMutex = sync.RWMutex{} // The Go SDK is not thread-safe 57 // The main version number that is being run at the moment. 58 var providerVersion = "1.57.1" 59 var terraformVersion = strings.TrimSuffix(terraform.VersionString(), "-dev") //nolint 60 61 // Client for AliyunClient 62 func (c *Config) Client() (*AliyunClient, error) { 63 // Get the auth and region. This can fail if keys/regions were not 64 // specified and we're attempting to use the environment. 65 if !c.SkipRegionValidation { 66 err := c.loadAndValidate() 67 if err != nil { 68 return nil, err 69 } 70 } 71 72 return &AliyunClient{ 73 config: c, 74 Region: c.Region, 75 RegionID: c.RegionID, 76 AccessKey: c.AccessKey, 77 SecretKey: c.SecretKey, 78 SecurityToken: c.SecurityToken, 79 OtsInstanceName: c.OtsInstanceName, 80 accountID: c.AccountID, 81 tablestoreconnByInstanceName: make(map[string]*tablestore.TableStoreClient), 82 csprojectconnByKey: make(map[string]*cs.ProjectClient), 83 }, nil 84 } 85 86 func (client *AliyunClient) WithEcsClient(do func(*ecs.Client) (interface{}, error)) (interface{}, error) { 87 goSdkMutex.Lock() 88 defer goSdkMutex.Unlock() 89 90 // Initialize the ECS client if necessary 91 if client.ecsconn == nil { 92 endpoint := client.config.EcsEndpoint 93 if endpoint == "" { 94 endpoint = loadEndpoint(client.config.RegionID, ECSCode) 95 } 96 97 if endpoint != "" { 98 err := endpoints.AddEndpointMapping(client.config.RegionID, string(ECSCode), endpoint) 99 if err != nil { 100 return nil, err 101 } 102 } 103 104 ecsconn, err := ecs.NewClientWithOptions(client.config.RegionID, client.getSdkConfig().WithTimeout(time.Duration(60)*time.Second), client.config.getAuthCredential()) 105 106 if err != nil { 107 return nil, fmt.Errorf("unable to initialize the ECS client: %#v", err) 108 } 109 110 if _, err := ecsconn.DescribeRegions(ecs.CreateDescribeRegionsRequest()); err != nil { 111 return nil, err 112 } 113 ecsconn.AppendUserAgent(Terraform, terraformVersion) 114 ecsconn.AppendUserAgent(Provider, providerVersion) 115 if client.config.ConfigurationSource != "" { 116 ecsconn.AppendUserAgent(Module, client.config.ConfigurationSource) 117 } 118 client.ecsconn = ecsconn 119 } 120 121 return do(client.ecsconn) 122 } 123 124 func (client *AliyunClient) WithRdsClient(do func(*rds.Client) (interface{}, error)) (interface{}, error) { 125 goSdkMutex.Lock() 126 defer goSdkMutex.Unlock() 127 128 // Initialize the RDS client if necessary 129 if client.rdsconn == nil { 130 endpoint := client.config.RdsEndpoint 131 if endpoint == "" { 132 endpoint = loadEndpoint(client.config.RegionID, RDSCode) 133 } 134 if endpoint != "" { 135 err := endpoints.AddEndpointMapping(client.config.RegionID, string(RDSCode), endpoint) 136 if err != nil { 137 return nil, err 138 } 139 } 140 rdsconn, err := rds.NewClientWithOptions(client.config.RegionID, client.getSdkConfig(), client.config.getAuthCredential()) 141 if err != nil { 142 return nil, fmt.Errorf("unable to initialize the RDS client: %#v", err) 143 } 144 145 rdsconn.AppendUserAgent(Terraform, terraformVersion) 146 rdsconn.AppendUserAgent(Provider, providerVersion) 147 if client.config.ConfigurationSource != "" { 148 rdsconn.AppendUserAgent(Module, client.config.ConfigurationSource) 149 } 150 client.rdsconn = rdsconn 151 } 152 153 return do(client.rdsconn) 154 } 155 156 func (client *AliyunClient) WithSlbClient(do func(*slb.Client) (interface{}, error)) (interface{}, error) { 157 goSdkMutex.Lock() 158 defer goSdkMutex.Unlock() 159 160 // Initialize the SLB client if necessary 161 if client.slbconn == nil { 162 endpoint := client.config.SlbEndpoint 163 if endpoint == "" { 164 endpoint = loadEndpoint(client.config.RegionID, SLBCode) 165 } 166 if endpoint != "" { 167 err := endpoints.AddEndpointMapping(client.config.RegionID, string(SLBCode), endpoint) 168 if err != nil { 169 return nil, err 170 } 171 } 172 slbconn, err := slb.NewClientWithOptions(client.config.RegionID, client.getSdkConfig(), client.config.getAuthCredential()) 173 if err != nil { 174 return nil, fmt.Errorf("unable to initialize the SLB client: %#v", err) 175 } 176 177 slbconn.AppendUserAgent(Terraform, terraformVersion) 178 slbconn.AppendUserAgent(Provider, providerVersion) 179 if client.config.ConfigurationSource != "" { 180 slbconn.AppendUserAgent(Module, client.config.ConfigurationSource) 181 } 182 client.slbconn = slbconn 183 } 184 185 return do(client.slbconn) 186 } 187 188 func (client *AliyunClient) WithVpcClient(do func(*vpc.Client) (interface{}, error)) (interface{}, error) { 189 goSdkMutex.Lock() 190 defer goSdkMutex.Unlock() 191 192 // Initialize the VPC client if necessary 193 if client.vpcconn == nil { 194 endpoint := client.config.VpcEndpoint 195 if endpoint == "" { 196 endpoint = loadEndpoint(client.config.RegionID, VPCCode) 197 } 198 if endpoint != "" { 199 err := endpoints.AddEndpointMapping(client.config.RegionID, string(VPCCode), endpoint) 200 if err != nil { 201 return nil, err 202 } 203 } 204 vpcconn, err := vpc.NewClientWithOptions(client.config.RegionID, client.getSdkConfig(), client.config.getAuthCredential()) 205 if err != nil { 206 return nil, fmt.Errorf("unable to initialize the VPC client: %#v", err) 207 } 208 209 vpcconn.AppendUserAgent(Terraform, terraformVersion) 210 vpcconn.AppendUserAgent(Provider, providerVersion) 211 if client.config.ConfigurationSource != "" { 212 vpcconn.AppendUserAgent(Module, client.config.ConfigurationSource) 213 } 214 client.vpcconn = vpcconn 215 } 216 217 return do(client.vpcconn) 218 } 219 220 func (client *AliyunClient) WithDNSClient(do func(*alidns.Client) (interface{}, error)) (interface{}, error) { 221 goSdkMutex.Lock() 222 defer goSdkMutex.Unlock() 223 224 // Initialize the DNS client if necessary 225 if client.dnsconn == nil { 226 endpoint := client.config.DNSEndpoint 227 if endpoint == "" { 228 endpoint = loadEndpoint(client.config.RegionID, DNSCode) 229 } 230 if endpoint != "" { 231 err := endpoints.AddEndpointMapping(client.config.RegionID, string(DNSCode), endpoint) 232 if err != nil { 233 return nil, err 234 } 235 } 236 237 dnsconn, err := alidns.NewClientWithOptions(client.config.RegionID, client.getSdkConfig(), client.config.getAuthCredential()) 238 if err != nil { 239 return nil, fmt.Errorf("unable to initialize the DNS client: %#v", err) 240 } 241 dnsconn.AppendUserAgent(Terraform, terraformVersion) 242 dnsconn.AppendUserAgent(Provider, providerVersion) 243 if client.config.ConfigurationSource != "" { 244 dnsconn.AppendUserAgent(Module, client.config.ConfigurationSource) 245 } 246 client.dnsconn = dnsconn 247 } 248 249 return do(client.dnsconn) 250 } 251 252 func (client *AliyunClient) WithRAMClient(do func(*ram.Client) (interface{}, error)) (interface{}, error) { 253 goSdkMutex.Lock() 254 defer goSdkMutex.Unlock() 255 256 // Initialize the RAM client if necessary 257 if client.ramconn == nil { 258 endpoint := client.config.RAMEndpoint 259 if endpoint == "" { 260 endpoint = loadEndpoint(client.config.RegionID, RAMCode) 261 } 262 if strings.HasPrefix(endpoint, "http") { 263 endpoint = fmt.Sprintf("https://%s", strings.TrimPrefix(endpoint, "http://")) 264 } 265 if endpoint != "" { 266 err := endpoints.AddEndpointMapping(client.config.RegionID, string(RAMCode), endpoint) 267 if err != nil { 268 return nil, err 269 } 270 } 271 272 ramconn, err := ram.NewClientWithOptions(client.config.RegionID, client.getSdkConfig(), client.config.getAuthCredential()) 273 if err != nil { 274 return nil, fmt.Errorf("unable to initialize the RAM client: %#v", err) 275 } 276 ramconn.AppendUserAgent(Terraform, terraformVersion) 277 ramconn.AppendUserAgent(Provider, providerVersion) 278 if client.config.ConfigurationSource != "" { 279 ramconn.AppendUserAgent(Module, client.config.ConfigurationSource) 280 } 281 client.ramconn = ramconn 282 } 283 284 return do(client.ramconn) 285 } 286 287 func (client *AliyunClient) WithPvtzClient(do func(*pvtz.Client) (interface{}, error)) (interface{}, error) { 288 goSdkMutex.Lock() 289 defer goSdkMutex.Unlock() 290 291 // Initialize the PVTZ client if necessary 292 if client.pvtzconn == nil { 293 endpoint := client.config.PvtzEndpoint 294 if endpoint == "" { 295 endpoint = loadEndpoint(client.config.RegionID, PVTZCode) 296 } 297 if endpoint != "" { 298 err := endpoints.AddEndpointMapping(client.config.RegionID, string(PVTZCode), endpoint) 299 if err != nil { 300 return nil, err 301 } 302 } else { 303 err := endpoints.AddEndpointMapping(client.config.RegionID, string(PVTZCode), "pvtz.aliyuncs.com") 304 if err != nil { 305 return nil, err 306 } 307 } 308 pvtzconn, err := pvtz.NewClientWithOptions(client.config.RegionID, client.getSdkConfig(), client.config.getAuthCredential()) 309 if err != nil { 310 return nil, fmt.Errorf("unable to initialize the PVTZ client: %#v", err) 311 } 312 313 pvtzconn.AppendUserAgent(Terraform, terraformVersion) 314 pvtzconn.AppendUserAgent(Provider, providerVersion) 315 if client.config.ConfigurationSource != "" { 316 pvtzconn.AppendUserAgent(Module, client.config.ConfigurationSource) 317 } 318 client.pvtzconn = pvtzconn 319 } 320 321 return do(client.pvtzconn) 322 } 323 324 func (client *AliyunClient) getSdkConfig() *sdk.Config { 325 return sdk.NewConfig(). 326 WithMaxRetryTime(DefaultClientRetryCountSmall). 327 WithTimeout(time.Duration(30) * time.Second). 328 WithGoRoutinePoolSize(10). 329 WithDebug(false). 330 WithHttpTransport(client.getTransport()). 331 WithScheme("HTTPS") 332 } 333 334 func (client *AliyunClient) getTransport() *http.Transport { 335 handshakeTimeout, err := strconv.Atoi(os.Getenv("TLSHandshakeTimeout")) 336 if err != nil { 337 handshakeTimeout = 120 338 } 339 transport := &http.Transport{} 340 transport.TLSHandshakeTimeout = time.Duration(handshakeTimeout) * time.Second 341 342 // After building a new transport and it need to set http proxy to support proxy. 343 proxyURL := client.getHTTPProxyURL() 344 if proxyURL != nil { 345 transport.Proxy = http.ProxyURL(proxyURL) 346 } 347 return transport 348 } 349 350 func (client *AliyunClient) getHTTPProxyURL() *url.URL { 351 for _, v := range []string{"HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"} { 352 value := strings.Trim(os.Getenv(v), " ") 353 if value != "" { 354 if !regexp.MustCompile(`^http(s)?://`).MatchString(value) { 355 value = fmt.Sprintf("https://%s", value) 356 } 357 proxyURL, err := url.Parse(value) 358 if err == nil { 359 return proxyURL 360 } 361 break 362 } 363 } 364 return nil 365 }