@@ -13,7 +13,22 @@ import (
1313 "github.com/scaleway/terraform-provider-scaleway/v2/version"
1414)
1515
16- const appendUserAgentEnvVar = "TF_APPEND_USER_AGENT"
16+ const (
17+ appendUserAgentEnvVar = "TF_APPEND_USER_AGENT"
18+ CredentialsSourceEnvironment = "Environment variable"
19+ CredentialsSourceDefault = "Default"
20+ CredentialsSourceActiveProfile = "Active Profile in config.yaml"
21+ CredentialsSourceProviderProfile = "Profile defined in provider{} block"
22+ CredentialsSourceInferred = "CredentialsSourceInferred from default zone"
23+ )
24+
25+ type CredentialsSource struct {
26+ AccessKey string
27+ SecretKey string
28+ ProjectID string
29+ DefaultZone string
30+ DefaultRegion string
31+ }
1732
1833// Meta contains config and SDK clients used by resources.
1934//
@@ -25,6 +40,8 @@ type Meta struct {
2540 // or it can be a http.Client used to record and replay cassettes which is useful
2641 // to replay recorded interactions with APIs locally
2742 httpClient * http.Client
43+ // credentialsSource stores information about the source (env, profile, etc.) of each credential
44+ credentialsSource * CredentialsSource
2845}
2946
3047func (m Meta ) ScwClient () * scw.Client {
@@ -35,6 +52,26 @@ func (m Meta) HTTPClient() *http.Client {
3552 return m .httpClient
3653}
3754
55+ func (m Meta ) AccessKeySource () string {
56+ return m .credentialsSource .AccessKey
57+ }
58+
59+ func (m Meta ) SecretKeySource () string {
60+ return m .credentialsSource .SecretKey
61+ }
62+
63+ func (m Meta ) ProjectIDSource () string {
64+ return m .credentialsSource .ProjectID
65+ }
66+
67+ func (m Meta ) RegionSource () string {
68+ return m .credentialsSource .DefaultRegion
69+ }
70+
71+ func (m Meta ) ZoneSource () string {
72+ return m .credentialsSource .DefaultZone
73+ }
74+
3875type Config struct {
3976 ProviderSchema * schema.ResourceData
4077 TerraformVersion string
@@ -46,12 +83,12 @@ type Config struct {
4683 HTTPClient * http.Client
4784}
4885
49- // providerConfigure creates the Meta object containing the SDK client.
86+ // NewMeta creates the Meta object containing the SDK client.
5087func NewMeta (ctx context.Context , config * Config ) (* Meta , error ) {
5188 ////
5289 // Load Profile
5390 ////
54- profile , err := loadProfile (ctx , config .ProviderSchema )
91+ profile , credentialsSource , err := loadProfile (ctx , config .ProviderSchema )
5592 if err != nil {
5693 return nil , err
5794 }
@@ -98,8 +135,9 @@ func NewMeta(ctx context.Context, config *Config) (*Meta, error) {
98135 }
99136
100137 return & Meta {
101- scwClient : scwClient ,
102- httpClient : httpClient ,
138+ scwClient : scwClient ,
139+ httpClient : httpClient ,
140+ credentialsSource : credentialsSource ,
103141 }, nil
104142}
105143
@@ -114,13 +152,13 @@ func customizeUserAgent(providerVersion string, terraformVersion string) string
114152}
115153
116154//gocyclo:ignore
117- func loadProfile (ctx context.Context , d * schema.ResourceData ) (* scw.Profile , error ) {
155+ func loadProfile (ctx context.Context , d * schema.ResourceData ) (* scw.Profile , * CredentialsSource , error ) {
118156 config , err := scw .LoadConfig ()
119157 // If the config file do not exist, don't return an error as we may find config in ENV or flags.
120158 if _ , isNotFoundError := err .(* scw.ConfigFileNotFoundError ); isNotFoundError {
121159 config = & scw.Config {}
122160 } else if err != nil {
123- return nil , err
161+ return nil , nil , err
124162 }
125163
126164 // By default we set default zone and region to fr-par
@@ -131,7 +169,7 @@ func loadProfile(ctx context.Context, d *schema.ResourceData) (*scw.Profile, err
131169
132170 activeProfile , err := config .GetActiveProfile ()
133171 if err != nil {
134- return nil , err
172+ return nil , nil , err
135173 }
136174 envProfile := scw .LoadEnvProfile ()
137175
@@ -167,6 +205,7 @@ func loadProfile(ctx context.Context, d *schema.ResourceData) (*scw.Profile, err
167205 }
168206
169207 profile := scw .MergeProfiles (defaultZoneProfile , activeProfile , providerProfile , envProfile )
208+ credentialsSource := GetCredentialsSource (defaultZoneProfile , activeProfile , providerProfile , envProfile )
170209
171210 // If profile have a defaultZone but no defaultRegion we set the defaultRegion
172211 // to the one of the defaultZone
@@ -177,9 +216,61 @@ func loadProfile(ctx context.Context, d *schema.ResourceData) (*scw.Profile, err
177216 region , err := zone .Region ()
178217 if err == nil {
179218 profile .DefaultRegion = scw .StringPtr (region .String ())
219+ credentialsSource .DefaultRegion = CredentialsSourceInferred
180220 } else {
181221 tflog .Debug (ctx , "cannot guess region: " + err .Error ())
182222 }
183223 }
184- return profile , nil
224+ return profile , credentialsSource , nil
225+ }
226+
227+ // GetCredentialsSource infers the source of the credentials based on the priority order of the different profiles
228+ func GetCredentialsSource (defaultZoneProfile , activeProfile , providerProfile , envProfile * scw.Profile ) * CredentialsSource {
229+ type SourceProfilePair struct {
230+ Source string
231+ Profile * scw.Profile
232+ }
233+
234+ profilesInOrder := []SourceProfilePair {
235+ {
236+ CredentialsSourceDefault ,
237+ defaultZoneProfile ,
238+ },
239+ {
240+ CredentialsSourceActiveProfile ,
241+ activeProfile ,
242+ },
243+ {
244+ CredentialsSourceProviderProfile ,
245+ providerProfile ,
246+ },
247+ {
248+ CredentialsSourceEnvironment ,
249+ envProfile ,
250+ },
251+ }
252+ credentialsSource := & CredentialsSource {}
253+
254+ for _ , pair := range profilesInOrder {
255+ source := pair .Source
256+ profile := pair .Profile
257+
258+ if profile .AccessKey != nil {
259+ credentialsSource .AccessKey = source
260+ }
261+ if profile .SecretKey != nil {
262+ credentialsSource .SecretKey = source
263+ }
264+ if profile .DefaultProjectID != nil {
265+ credentialsSource .ProjectID = source
266+ }
267+ if profile .DefaultRegion != nil {
268+ credentialsSource .DefaultRegion = source
269+ }
270+ if profile .DefaultZone != nil {
271+ credentialsSource .DefaultZone = source
272+ }
273+ }
274+
275+ return credentialsSource
185276}
0 commit comments