Skip to content

Commit 0cfe921

Browse files
committed
feat(meta): warn the user if there are multiple variable sources used
1 parent 8505cd4 commit 0cfe921

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

internal/meta/meta.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package meta
22

33
import (
4+
"bytes"
45
"context"
56
"errors"
67
"fmt"
78
"net/http"
89
"os"
10+
"strings"
11+
"text/tabwriter"
912

1013
"github.com/hashicorp/terraform-plugin-log/tflog"
1114
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -24,6 +27,7 @@ const (
2427
)
2528

2629
type CredentialsSource struct {
30+
Variables map[string][]string
2731
AccessKey string
2832
SecretKey string
2933
ProjectID string
@@ -73,6 +77,41 @@ func (m Meta) ZoneSource() string {
7377
return m.credentialsSource.DefaultZone
7478
}
7579

80+
// HasMultipleVariableSources return an informative message during the Provider initialization
81+
// if there are multiple sources of configuration that could confuse the user
82+
//
83+
// Variable AvailableSources Using
84+
// SCW_ACCESS_KEY Active Profile in config.yaml, Environment variable Environment variable
85+
// SCW_SECRET_KEY Active Profile in config.yaml, Environment variable Environment variable
86+
func (m Meta) HasMultipleVariableSources() (bool, string) {
87+
multiple := false
88+
89+
variables := []string{scw.ScwAccessKeyEnv, scw.ScwSecretKeyEnv, scw.ScwDefaultProjectIDEnv, scw.ScwDefaultRegionEnv, scw.ScwDefaultZoneEnv}
90+
91+
w := new(tabwriter.Writer)
92+
buf := &bytes.Buffer{}
93+
w.Init(buf, 0, 8, 0, '\t', 0)
94+
95+
fmt.Fprintln(w, "Variable\tAvailableSources\tUsing") //nolint:errcheck
96+
97+
for _, variable := range variables {
98+
values, ok := m.credentialsSource.Variables[variable]
99+
if ok {
100+
if len(values) > 1 {
101+
fmt.Fprintf(w, "%s\t%s\t%s\n", variable, strings.Join(values, ", "), values[len(values)-1]) //nolint:errcheck
102+
103+
multiple = true
104+
}
105+
}
106+
}
107+
108+
if err := w.Flush(); err != nil {
109+
panic(err) // lintignore: R009
110+
}
111+
112+
return multiple, buf.String()
113+
}
114+
76115
type Config struct {
77116
ProviderSchema *schema.ResourceData
78117
HTTPClient *http.Client
@@ -270,29 +309,39 @@ func GetCredentialsSource(defaultZoneProfile, activeProfile, providerProfile, en
270309
},
271310
}
272311
credentialsSource := &CredentialsSource{}
312+
credentialsSource.Variables = map[string][]string{}
273313

274314
for _, pair := range profilesInOrder {
275315
source := pair.Source
276316
profile := pair.Profile
277317

278318
if profile.AccessKey != nil {
279319
credentialsSource.AccessKey = source
320+
credentialsSource.Variables[scw.ScwAccessKeyEnv] = append(credentialsSource.Variables[scw.ScwAccessKeyEnv], source)
280321
}
281322

282323
if profile.SecretKey != nil {
283324
credentialsSource.SecretKey = source
325+
credentialsSource.Variables[scw.ScwSecretKeyEnv] = append(credentialsSource.Variables[scw.ScwSecretKeyEnv], source)
284326
}
285327

286328
if profile.DefaultProjectID != nil {
287329
credentialsSource.ProjectID = source
330+
credentialsSource.Variables[scw.ScwDefaultProjectIDEnv] = append(credentialsSource.Variables[scw.ScwDefaultProjectIDEnv], source)
288331
}
289332

290333
if profile.DefaultRegion != nil {
291334
credentialsSource.DefaultRegion = source
335+
if source != CredentialsSourceDefault {
336+
credentialsSource.Variables[scw.ScwDefaultRegionEnv] = append(credentialsSource.Variables[scw.ScwDefaultRegionEnv], source)
337+
}
292338
}
293339

294340
if profile.DefaultZone != nil {
295341
credentialsSource.DefaultZone = source
342+
if source != CredentialsSourceDefault {
343+
credentialsSource.Variables[scw.ScwDefaultZoneEnv] = append(credentialsSource.Variables[scw.ScwDefaultZoneEnv], source)
344+
}
296345
}
297346
}
298347

internal/meta/meta_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package meta_test
2+
3+
import (
4+
"os"
5+
"path"
6+
"testing"
7+
8+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestHasMultipleVariableSources(t *testing.T) {
14+
ctx := t.Context()
15+
16+
cfg := &meta.Config{}
17+
18+
scwConfigigFile := `profiles:
19+
test:
20+
access_key: SCWXXXXXXXXXXXXXXXXX
21+
secret_key: 866F4A9A-D058-4D3C-A39F-86930849CCC0
22+
default_project_id: 866F4A9A-D058-4D3C-A39F-86930849CCC0
23+
`
24+
25+
dir := t.TempDir()
26+
27+
err := os.WriteFile(path.Join(dir, "config.yaml"), []byte(scwConfigigFile), 0o644)
28+
require.NoError(t, err)
29+
30+
t.Setenv("SCW_CONFIG_PATH", path.Join(dir, "config.yaml"))
31+
t.Setenv("SCW_PROFILE", "test")
32+
t.Setenv("SCW_ACCESS_KEY", "SCWXXXXXXXXXXXXXXXXX")
33+
t.Setenv("SCW_SECRET_KEY", "866F4A9A-D058-4D3C-A39F-86930849CCC0")
34+
t.Setenv("SCW_DEFAULT_PROJECT_ID", "866F4A9A-D058-4D3C-A39F-86930849CCC0")
35+
36+
m, err := meta.NewMeta(ctx, cfg)
37+
require.NoError(t, err)
38+
39+
ok, message := m.HasMultipleVariableSources()
40+
assert.True(t, ok)
41+
42+
expectedMessage := `Variable AvailableSources Using
43+
SCW_ACCESS_KEY Active Profile in config.yaml, Environment variable Environment variable
44+
SCW_SECRET_KEY Active Profile in config.yaml, Environment variable Environment variable
45+
SCW_DEFAULT_PROJECT_ID Active Profile in config.yaml, Environment variable Environment variable
46+
`
47+
assert.Equal(t, expectedMessage, message)
48+
}

internal/provider/provider.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,17 @@ func Provider(config *Config) plugin.ProviderFunc {
355355
return nil, diag.FromErr(err)
356356
}
357357

358-
return m, nil
358+
var diags diag.Diagnostics
359+
360+
if ok, message := m.HasMultipleVariableSources(); ok {
361+
diags = append(diags, diag.Diagnostic{
362+
Severity: diag.Warning,
363+
Summary: "Multiple variable sources detected, please make sure the right credentials are used",
364+
Detail: message,
365+
})
366+
}
367+
368+
return m, diags
359369
}
360370

361371
return p

0 commit comments

Comments
 (0)