Skip to content

Commit 9fc0124

Browse files
authored
feat/profile (#2302)
* feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile * feat/profile
1 parent f4471f6 commit 9fc0124

File tree

3 files changed

+261
-29
lines changed

3 files changed

+261
-29
lines changed

.changelog/2302.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
provider: Update some interface input permissions; Add profile authentication
3+
```

tencentcloud/provider.go

Lines changed: 226 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,9 +2057,16 @@ CDWPG
20572057
package tencentcloud
20582058

20592059
import (
2060+
"encoding/json"
2061+
"fmt"
2062+
"io/ioutil"
20602063
"net/url"
20612064
"os"
2065+
"runtime"
20622066
"strconv"
2067+
"strings"
2068+
2069+
"github.com/mitchellh/go-homedir"
20632070

20642071
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
20652072
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
@@ -2079,6 +2086,13 @@ const (
20792086
PROVIDER_ASSUME_ROLE_ARN = "TENCENTCLOUD_ASSUME_ROLE_ARN"
20802087
PROVIDER_ASSUME_ROLE_SESSION_NAME = "TENCENTCLOUD_ASSUME_ROLE_SESSION_NAME"
20812088
PROVIDER_ASSUME_ROLE_SESSION_DURATION = "TENCENTCLOUD_ASSUME_ROLE_SESSION_DURATION"
2089+
PROVIDER_SHARED_CREDENTIALS_DIR = "TENCENTCLOUD_SHARED_CREDENTIALS_DIR"
2090+
PROVIDER_PROFILE = "TENCENTCLOUD_PROFILE"
2091+
)
2092+
2093+
const (
2094+
DEFAULT_REGION = "ap-guangzhou"
2095+
DEFAULT_PROFILE = "default"
20822096
)
20832097

20842098
type TencentCloudClient struct {
@@ -2090,13 +2104,13 @@ func Provider() *schema.Provider {
20902104
Schema: map[string]*schema.Schema{
20912105
"secret_id": {
20922106
Type: schema.TypeString,
2093-
Required: true,
2107+
Optional: true,
20942108
DefaultFunc: schema.EnvDefaultFunc(PROVIDER_SECRET_ID, nil),
20952109
Description: "This is the TencentCloud access key. It must be provided, but it can also be sourced from the `TENCENTCLOUD_SECRET_ID` environment variable.",
20962110
},
20972111
"secret_key": {
20982112
Type: schema.TypeString,
2099-
Required: true,
2113+
Optional: true,
21002114
DefaultFunc: schema.EnvDefaultFunc(PROVIDER_SECRET_KEY, nil),
21012115
Description: "This is the TencentCloud secret key. It must be provided, but it can also be sourced from the `TENCENTCLOUD_SECRET_KEY` environment variable.",
21022116
Sensitive: true,
@@ -2109,11 +2123,10 @@ func Provider() *schema.Provider {
21092123
Sensitive: true,
21102124
},
21112125
"region": {
2112-
Type: schema.TypeString,
2113-
Required: true,
2114-
DefaultFunc: schema.EnvDefaultFunc(PROVIDER_REGION, nil),
2115-
Description: "This is the TencentCloud region. It must be provided, but it can also be sourced from the `TENCENTCLOUD_REGION` environment variables. The default input value is ap-guangzhou.",
2116-
InputDefault: "ap-guangzhou",
2126+
Type: schema.TypeString,
2127+
Optional: true,
2128+
DefaultFunc: schema.EnvDefaultFunc(PROVIDER_REGION, nil),
2129+
Description: "This is the TencentCloud region. It must be provided, but it can also be sourced from the `TENCENTCLOUD_REGION` environment variables. The default input value is ap-guangzhou.",
21172130
},
21182131
"protocol": {
21192132
Type: schema.TypeString,
@@ -2167,6 +2180,18 @@ func Provider() *schema.Provider {
21672180
},
21682181
},
21692182
},
2183+
"shared_credentials_dir": {
2184+
Type: schema.TypeString,
2185+
Optional: true,
2186+
DefaultFunc: schema.EnvDefaultFunc(PROVIDER_SHARED_CREDENTIALS_DIR, nil),
2187+
Description: "The directory of the shared credentials. It can also be sourced from the `TENCENTCLOUD_SHARED_CREDENTIALS_DIR` environment variable. If not set this defaults to ~/.tccli.",
2188+
},
2189+
"profile": {
2190+
Type: schema.TypeString,
2191+
Optional: true,
2192+
DefaultFunc: schema.EnvDefaultFunc(PROVIDER_PROFILE, nil),
2193+
Description: "The profile name as set in the shared credentials. It can also be sourced from the `TENCENTCLOUD_PROFILE` environment variable. If not set, the default profile created with `tccli configure` will be used.",
2194+
},
21702195
},
21712196

21722197
DataSourcesMap: map[string]*schema.Resource{
@@ -3825,12 +3850,68 @@ func Provider() *schema.Provider {
38253850
}
38263851

38273852
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
3828-
secretId := d.Get("secret_id").(string)
3829-
secretKey := d.Get("secret_key").(string)
3830-
securityToken := d.Get("security_token").(string)
3831-
region := d.Get("region").(string)
3832-
protocol := d.Get("protocol").(string)
3833-
domain := d.Get("domain").(string)
3853+
//var getProviderConfig = func(str string, key string) string {
3854+
// if str == "" {
3855+
// value, err := getConfigFromProfile(d, key)
3856+
// if err == nil && value != nil {
3857+
// str = value.(string)
3858+
// }
3859+
// }
3860+
//
3861+
// return str
3862+
//}
3863+
3864+
var getProviderConfig = func(key string) string {
3865+
var str string
3866+
value, err := getConfigFromProfile(d, key)
3867+
if err == nil && value != nil {
3868+
str = value.(string)
3869+
}
3870+
3871+
return str
3872+
}
3873+
3874+
var (
3875+
secretId string
3876+
secretKey string
3877+
securityToken string
3878+
region string
3879+
protocol string
3880+
domain string
3881+
)
3882+
3883+
if v, ok := d.GetOk("secret_id"); ok {
3884+
secretId = v.(string)
3885+
} else {
3886+
secretId = getProviderConfig("secretId")
3887+
}
3888+
3889+
if v, ok := d.GetOk("secret_key"); ok {
3890+
secretKey = v.(string)
3891+
} else {
3892+
secretKey = getProviderConfig("secretKey")
3893+
}
3894+
3895+
if v, ok := d.GetOk("security_token"); ok {
3896+
securityToken = v.(string)
3897+
}
3898+
3899+
if v, ok := d.GetOk("region"); ok {
3900+
region = v.(string)
3901+
} else {
3902+
region = getProviderConfig("region")
3903+
if region == "" {
3904+
region = DEFAULT_REGION
3905+
}
3906+
}
3907+
3908+
if v, ok := d.GetOk("protocol"); ok {
3909+
protocol = v.(string)
3910+
}
3911+
3912+
if v, ok := d.GetOk("domain"); ok {
3913+
domain = v.(string)
3914+
}
38343915

38353916
// standard client
38363917
var tcClient TencentCloudClient
@@ -3845,37 +3926,66 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
38453926
Domain: domain,
38463927
}
38473928

3848-
envRoleArn := os.Getenv(PROVIDER_ASSUME_ROLE_ARN)
3849-
envSessionName := os.Getenv(PROVIDER_ASSUME_ROLE_SESSION_NAME)
3929+
var (
3930+
assumeRoleArn string
3931+
assumeRoleSessionName string
3932+
assumeRoleSessionDuration int
3933+
assumeRolePolicy string
3934+
)
3935+
3936+
// get assume role from credential
3937+
if providerConfig["role-arn"] != nil {
3938+
assumeRoleArn = providerConfig["role-arn"].(string)
3939+
}
3940+
3941+
if providerConfig["role-session-name"] != nil {
3942+
assumeRoleSessionName = providerConfig["role-session-name"].(string)
3943+
}
3944+
3945+
if assumeRoleArn != "" && assumeRoleSessionName != "" {
3946+
assumeRoleSessionDuration = 7200
3947+
assumeRolePolicy = ""
3948+
3949+
_ = genClientWithSTS(&tcClient, assumeRoleArn, assumeRoleSessionName, assumeRoleSessionDuration, assumeRolePolicy)
3950+
}
38503951

38513952
// get assume role from env
3953+
envRoleArn := os.Getenv(PROVIDER_ASSUME_ROLE_ARN)
3954+
envSessionName := os.Getenv(PROVIDER_ASSUME_ROLE_SESSION_NAME)
38523955
if envRoleArn != "" && envSessionName != "" {
3853-
var assumeRoleSessionDuration int
38543956
if envSessionDuration := os.Getenv(PROVIDER_ASSUME_ROLE_SESSION_DURATION); envSessionDuration != "" {
38553957
var err error
38563958
assumeRoleSessionDuration, err = strconv.Atoi(envSessionDuration)
38573959
if err != nil {
38583960
return nil, err
38593961
}
38603962
}
3963+
38613964
if assumeRoleSessionDuration == 0 {
38623965
assumeRoleSessionDuration = 7200
38633966
}
38643967

38653968
_ = genClientWithSTS(&tcClient, envRoleArn, envSessionName, assumeRoleSessionDuration, "")
38663969
}
38673970

3868-
// get assume role from tf config
3869-
assumeRoleList := d.Get("assume_role").(*schema.Set).List()
3870-
if len(assumeRoleList) == 1 {
3871-
assumeRole := assumeRoleList[0].(map[string]interface{})
3872-
assumeRoleArn := assumeRole["role_arn"].(string)
3873-
assumeRoleSessionName := assumeRole["session_name"].(string)
3874-
assumeRoleSessionDuration := assumeRole["session_duration"].(int)
3875-
assumeRolePolicy := assumeRole["policy"].(string)
3971+
// get assume role from tf
3972+
if v, ok := d.GetOk("assume_role"); ok {
3973+
assumeRoleList := v.(*schema.Set).List()
3974+
if len(assumeRoleList) == 1 {
3975+
assumeRole := assumeRoleList[0].(map[string]interface{})
3976+
assumeRoleArn = assumeRole["role_arn"].(string)
3977+
assumeRoleSessionName = assumeRole["session_name"].(string)
3978+
assumeRoleSessionDuration = assumeRole["session_duration"].(int)
3979+
assumeRolePolicy = assumeRole["policy"].(string)
3980+
3981+
_ = genClientWithSTS(&tcClient, assumeRoleArn, assumeRoleSessionName, assumeRoleSessionDuration, assumeRolePolicy)
3982+
}
3983+
}
38763984

3877-
_ = genClientWithSTS(&tcClient, assumeRoleArn, assumeRoleSessionName, assumeRoleSessionDuration, assumeRolePolicy)
3985+
if secretId == "" || secretKey == "" {
3986+
return nil, fmt.Errorf("Please set your `secret_id` and `secret_key`.")
38783987
}
3988+
38793989
return &tcClient, nil
38803990
}
38813991

@@ -3888,16 +3998,107 @@ func genClientWithSTS(tcClient *TencentCloudClient, assumeRoleArn, assumeRoleSes
38883998
if assumeRolePolicy != "" {
38893999
request.Policy = helper.String(url.QueryEscape(assumeRolePolicy))
38904000
}
4001+
38914002
ratelimit.Check(request.GetAction())
38924003
response, err := tcClient.apiV3Conn.UseStsClient().AssumeRole(request)
38934004
if err != nil {
38944005
return err
38954006
}
4007+
38964008
// using STS credentials
38974009
tcClient.apiV3Conn.Credential = common.NewTokenCredential(
38984010
*response.Response.Credentials.TmpSecretId,
38994011
*response.Response.Credentials.TmpSecretKey,
39004012
*response.Response.Credentials.Token,
39014013
)
4014+
39024015
return nil
39034016
}
4017+
4018+
var providerConfig map[string]interface{}
4019+
4020+
func getConfigFromProfile(d *schema.ResourceData, ProfileKey string) (interface{}, error) {
4021+
if providerConfig == nil {
4022+
var (
4023+
profile string
4024+
sharedCredentialsDir string
4025+
credentialPath string
4026+
configurePath string
4027+
)
4028+
4029+
if v, ok := d.GetOk("profile"); ok {
4030+
profile = v.(string)
4031+
} else {
4032+
profile = DEFAULT_PROFILE
4033+
}
4034+
4035+
if v, ok := d.GetOk("shared_credentials_dir"); ok {
4036+
sharedCredentialsDir = v.(string)
4037+
}
4038+
4039+
tmpSharedCredentialsDir, err := homedir.Expand(sharedCredentialsDir)
4040+
if err != nil {
4041+
return nil, err
4042+
}
4043+
4044+
if tmpSharedCredentialsDir == "" {
4045+
credentialPath = fmt.Sprintf("%s/.tccli/%s.credential", os.Getenv("HOME"), profile)
4046+
configurePath = fmt.Sprintf("%s/.tccli/%s.configure", os.Getenv("HOME"), profile)
4047+
if runtime.GOOS == "windows" {
4048+
credentialPath = fmt.Sprintf("%s/.tccli/%s.credential", os.Getenv("USERPROFILE"), profile)
4049+
configurePath = fmt.Sprintf("%s/.tccli/%s.configure", os.Getenv("USERPROFILE"), profile)
4050+
}
4051+
} else {
4052+
credentialPath = fmt.Sprintf("%s/%s.credential", sharedCredentialsDir, profile)
4053+
configurePath = fmt.Sprintf("%s/%s.configure", sharedCredentialsDir, profile)
4054+
}
4055+
4056+
providerConfig = make(map[string]interface{})
4057+
_, err = os.Stat(credentialPath)
4058+
if !os.IsNotExist(err) {
4059+
data, err := ioutil.ReadFile(credentialPath)
4060+
if err != nil {
4061+
return nil, err
4062+
}
4063+
4064+
config := map[string]interface{}{}
4065+
err = json.Unmarshal(data, &config)
4066+
if err != nil {
4067+
return nil, err
4068+
}
4069+
4070+
for k, v := range config {
4071+
providerConfig[k] = strings.TrimSpace(v.(string))
4072+
}
4073+
}
4074+
4075+
_, err = os.Stat(configurePath)
4076+
if !os.IsNotExist(err) {
4077+
data, err := ioutil.ReadFile(configurePath)
4078+
if err != nil {
4079+
return nil, err
4080+
}
4081+
4082+
config := map[string]interface{}{}
4083+
err = json.Unmarshal(data, &config)
4084+
if err != nil {
4085+
return nil, err
4086+
}
4087+
4088+
outerLoop:
4089+
for k, v := range config {
4090+
if k == "_sys_param" {
4091+
tmpMap := v.(map[string]interface{})
4092+
for tmpK, tmpV := range tmpMap {
4093+
if tmpK == "region" {
4094+
providerConfig[tmpK] = strings.TrimSpace(tmpV.(string))
4095+
break outerLoop
4096+
}
4097+
}
4098+
}
4099+
}
4100+
}
4101+
}
4102+
4103+
return providerConfig[ProfileKey], nil
4104+
}

0 commit comments

Comments
 (0)