github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/alicloud/connectivity/config.go (about) 1 package connectivity 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "log" 7 "net/http" 8 "strings" 9 10 "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" 11 "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" 12 "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" 13 "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" 14 "github.com/jmespath/go-jmespath" 15 ) 16 17 var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/" 18 19 // Config of aliyun 20 type Config struct { 21 AccessKey string 22 SecretKey string 23 EcsRoleName string 24 Region Region 25 RegionID string 26 SecurityToken string 27 OtsInstanceName string 28 AccountID string 29 RAMRoleArn string 30 RAMRoleSessionName string 31 RAMRolePolicy string 32 RAMRoleSessionExpiration int 33 EcsEndpoint string 34 RdsEndpoint string 35 SlbEndpoint string 36 VpcEndpoint string 37 CenEndpoint string 38 EssEndpoint string 39 OssEndpoint string 40 OnsEndpoint string 41 AlikafkaEndpoint string 42 DNSEndpoint string 43 RAMEndpoint string 44 CsEndpoint string 45 CrEndpoint string 46 CdnEndpoint string 47 KmsEndpoint string 48 OtsEndpoint string 49 CmsEndpoint string 50 PvtzEndpoint string 51 StsEndpoint string 52 LogEndpoint string 53 DrdsEndpoint string 54 DdsEndpoint string 55 GpdbEnpoint string 56 KVStoreEndpoint string 57 FcEndpoint string 58 ApigatewayEndpoint string 59 DatahubEndpoint string 60 MnsEndpoint string 61 LocationEndpoint string 62 ElasticsearchEndpoint string 63 NasEndpoint string 64 ActionTrailEndpoint string 65 BssOpenAPIEndpoint string 66 DdoscooEndpoint string 67 DdosbgpEndpoint string 68 69 SkipRegionValidation bool 70 ConfigurationSource string 71 } 72 73 func (c *Config) loadAndValidate() error { 74 err := c.validateRegion() 75 if err != nil { 76 return err 77 } 78 79 return nil 80 } 81 82 func (c *Config) validateRegion() error { 83 for _, valid := range ValidRegions { 84 if c.Region == valid { 85 return nil 86 } 87 } 88 89 return fmt.Errorf("Invalid Alibaba Cloud region: %s", c.RegionID) 90 } 91 92 func (c *Config) getAuthCredential() auth.Credential { 93 if c.AccessKey != "" && c.SecretKey != "" { 94 if c.SecurityToken != "" { 95 return credentials.NewStsTokenCredential(c.AccessKey, c.SecretKey, c.SecurityToken) 96 } 97 if c.RAMRoleArn != "" { 98 log.Printf("[INFO] Assume RAM Role specified in provider block assume_role { ... }") 99 return credentials.NewRamRoleArnWithPolicyCredential( 100 c.AccessKey, c.SecretKey, c.RAMRoleArn, 101 c.RAMRoleSessionName, c.RAMRolePolicy, c.RAMRoleSessionExpiration) 102 } 103 return credentials.NewAccessKeyCredential(c.AccessKey, c.SecretKey) 104 } 105 if c.EcsRoleName != "" { 106 return credentials.NewEcsRamRoleCredential(c.EcsRoleName) 107 } 108 109 return credentials.NewAccessKeyCredential(c.AccessKey, c.SecretKey) 110 } 111 112 // getAuthCredentialByEcsRoleName aims to access meta to get sts credential 113 // Actually, the job should be done by sdk, but currently not all resources and products support alibaba-cloud-sdk-go, 114 // and their go sdk does support ecs role name. 115 // This method is a temporary solution and it should be removed after all go sdk support ecs role name 116 // The related PR: https://github.com/terraform-providers/terraform-provider-alicloud/pull/731 117 func (c *Config) getAuthCredentialByEcsRoleName() (accessKey, secretKey, token string, err error) { 118 if c.AccessKey != "" { 119 return c.AccessKey, c.SecretKey, c.SecurityToken, nil 120 } 121 if c.EcsRoleName == "" { 122 return 123 } 124 requestURL := securityCredURL + c.EcsRoleName 125 httpRequest, err := http.NewRequest(requests.GET, requestURL, strings.NewReader("")) 126 if err != nil { 127 err = fmt.Errorf("build sts requests err: %s", err.Error()) 128 return 129 } 130 httpClient := &http.Client{} 131 httpResponse, err := httpClient.Do(httpRequest) 132 if err != nil { 133 err = fmt.Errorf("get Ecs sts token err : %s", err.Error()) 134 return 135 } 136 137 response := responses.NewCommonResponse() 138 err = responses.Unmarshal(response, httpResponse, "") 139 if err != nil { 140 err = fmt.Errorf("Unmarshal Ecs sts token response err : %s", err.Error()) 141 return 142 } 143 144 if response.GetHttpStatus() != http.StatusOK { 145 err = fmt.Errorf("get Ecs sts token err, httpStatus: %d, message = %s", response.GetHttpStatus(), response.GetHttpContentString()) 146 return 147 } 148 var data interface{} 149 err = json.Unmarshal(response.GetHttpContentBytes(), &data) 150 if err != nil { 151 err = fmt.Errorf("refresh Ecs sts token err, json.Unmarshal fail: %s", err.Error()) 152 return 153 } 154 code, err := jmespath.Search("Code", data) 155 if err != nil { 156 err = fmt.Errorf("refresh Ecs sts token err, fail to get Code: %s", err.Error()) 157 return 158 } 159 if code.(string) != "Success" { 160 err = fmt.Errorf("refresh Ecs sts token err, Code is not Success") 161 return 162 } 163 accessKeyID, err := jmespath.Search("AccessKeyId", data) 164 if err != nil { 165 err = fmt.Errorf("refresh Ecs sts token err, fail to get AccessKeyId: %s", err.Error()) 166 return 167 } 168 accessKeySecret, err := jmespath.Search("AccessKeySecret", data) 169 if err != nil { 170 err = fmt.Errorf("refresh Ecs sts token err, fail to get AccessKeySecret: %s", err.Error()) 171 return 172 } 173 securityToken, err := jmespath.Search("SecurityToken", data) 174 if err != nil { 175 err = fmt.Errorf("refresh Ecs sts token err, fail to get SecurityToken: %s", err.Error()) 176 return 177 } 178 179 if accessKeyID == nil || accessKeySecret == nil || securityToken == nil { 180 err = fmt.Errorf("there is no any available accesskey, secret and security token for Ecs role %s", c.EcsRoleName) 181 return 182 } 183 184 return accessKeyID.(string), accessKeySecret.(string), securityToken.(string), nil 185 } 186 187 func (c *Config) MakeConfigByEcsRoleName() error { 188 accessKey, secretKey, token, err := c.getAuthCredentialByEcsRoleName() 189 if err != nil { 190 return err 191 } 192 c.AccessKey, c.SecretKey, c.SecurityToken = accessKey, secretKey, token 193 return nil 194 }