Skip to content

Commit a32c9bd

Browse files
authored
feat(config): add a commented configuration file (#231)
1 parent 5b36e82 commit a32c9bd

File tree

2 files changed

+331
-5
lines changed

2 files changed

+331
-5
lines changed

scw/config.go

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package scw
22

33
import (
4+
"bytes"
45
"io/ioutil"
56
"os"
67
"path/filepath"
8+
"text/template"
79

810
"github.com/scaleway/scaleway-sdk-go/internal/auth"
911
"github.com/scaleway/scaleway-sdk-go/internal/errors"
@@ -16,6 +18,78 @@ const (
1618
defaultConfigPermission = 0600
1719
)
1820

21+
const configFileTemplate = `# Scaleway configuration file
22+
# https://github.com/scaleway/scaleway-sdk-go/tree/master/scw#scaleway-config
23+
24+
# You need an access key and a secret key to connect to Scaleway API.
25+
# Generate your token at the following address: https://console.scaleway.com/account/credentials
26+
27+
# An access key is a secret key identifier.
28+
{{ if .AccessKey }}access_key: {{.AccessKey}}{{ else }}# access_key: SCW11111111111111111{{ end }}
29+
30+
# The secret key is the value that can be used to authenticate against the API (the value used in X-Auth-Token HTTP-header).
31+
# The secret key MUST remain secret and not given to anyone or published online.
32+
{{ if .SecretKey }}secret_key: {{ .SecretKey }}{{ else }}# secret_key: 11111111-1111-1111-1111-111111111111{{ end }}
33+
34+
# Your organization ID is the identifier of your account inside Scaleway infrastructure.
35+
{{ if .DefaultOrganizationID }}default_organization_id: {{ .DefaultOrganizationID }}{{ else }}# default_organization_id: 11111111-1111-1111-1111-111111111111{{ end }}
36+
37+
# A region is represented as a geographical area such as France (Paris) or the Netherlands (Amsterdam).
38+
# It can contain multiple availability zones.
39+
# Example of region: fr-par, nl-ams
40+
{{ if .DefaultRegion }}default_region: {{ .DefaultRegion }}{{ else }}# default_region: fr-par{{ end }}
41+
42+
# A region can be split into many availability zones (AZ).
43+
# Latency between multiple AZ of the same region are low as they have a common network layer.
44+
# Example of zones: fr-par-1, nl-ams-1
45+
{{ if .DefaultZone }}default_zone: {{.DefaultZone}}{{ else }}# default_zone: fr-par-1{{ end }}
46+
47+
# APIURL overrides the API URL of the Scaleway API to the given URL.
48+
# Change that if you want to direct requests to a different endpoint.
49+
{{ if .APIURL }}apiurl: {{ .APIURL }}{{ else }}# api_url: https://api.scaleway.com{{ end }}
50+
51+
# Insecure enables insecure transport on the client.
52+
# Default to false
53+
{{ if .Insecure }}insecure: {{ .Insecure }}{{ else }}# insecure: false{{ end }}
54+
55+
# A configuration is a named set of Scaleway properties.
56+
# Starting off with a Scaleway SDK or Scaleway CLI, you’ll work with a single configuration named default.
57+
# You can set properties of the default profile by running either scw init or scw config set.
58+
# This single default configuration is suitable for most use cases.
59+
{{ if .ActiveProfile }}active_profile: {{ .ActiveProfile }}{{ else }}# active_profile: myProfile{{ end }}
60+
61+
# To work with multiple projects or authorization accounts, you can set up multiple configurations with scw config configurations create and switch among them accordingly.
62+
# You can use a profile by either:
63+
# - Define the profile you want to use as the SCW_PROFILE environment variable
64+
# - Use the GetActiveProfile() function in the SDK
65+
# - Use the --profile flag with the CLI
66+
67+
# You can define a profile using the following syntax:
68+
{{ if gt (len .Profiles) 0 }}
69+
profiles:
70+
{{- range $k,$v := .Profiles }}
71+
{{ $k }}:
72+
{{ if $v.AccessKey }}access_key: {{ $v.AccessKey }}{{ else }}# access_key: SCW11111111111111111{{ end }}
73+
{{ if $v.SecretKey }}secret_key: {{ $v.SecretKey }}{{ else }}# secret_key: 11111111-1111-1111-1111-111111111111{{ end }}
74+
{{ if $v.DefaultOrganizationID }}default_organization_id: {{ $v.DefaultOrganizationID }}{{ else }}# default_organization_id: 11111111-1111-1111-1111-111111111111{{ end }}
75+
{{ if $v.DefaultZone }}default_zone: {{ $v.DefaultZone }}{{ else }}# default_zone: fr-par-1{{ end }}
76+
{{ if $v.DefaultRegion }}default_region: {{ $v.DefaultRegion }}{{ else }}# default_region: fr-par{{ end }}
77+
{{ if $v.APIURL }}api_url: {{ $v.APIURL }}{{ else }}# api_url: https://api.scaleway.com{{ end }}
78+
{{ if $v.Insecure }}insecure: {{ $v.Insecure }}{{ else }}# insecure: false{{ end }}
79+
{{ end }}
80+
{{- else }}
81+
# profiles:
82+
# myProfile:
83+
# access_key: 11111111-1111-1111-1111-111111111111
84+
# secret_key: 11111111-1111-1111-1111-111111111111
85+
# organization_id: 11111111-1111-1111-1111-111111111111
86+
# default_zone: fr-par-1
87+
# default_region: fr-par
88+
# api_url: https://api.scaleway.com
89+
# insecure: false
90+
{{ end -}}
91+
`
92+
1993
type Config struct {
2094
Profile `yaml:",inline"`
2195
ActiveProfile *string `yaml:"active_profile,omitempty"`
@@ -150,13 +224,29 @@ func (c *Config) Save() error {
150224
return c.SaveTo(GetConfigPath())
151225
}
152226

227+
// HumanConfig will generate a config file with documented arguments.
228+
func (c *Config) HumanConfig() (string, error) {
229+
tmpl, err := template.New("configuration").Parse(configFileTemplate)
230+
if err != nil {
231+
return "", err
232+
}
233+
234+
var buf bytes.Buffer
235+
err = tmpl.Execute(&buf, c)
236+
if err != nil {
237+
return "", err
238+
}
239+
240+
return buf.String(), nil
241+
}
242+
153243
// SaveTo will save the config to the given path. This action will
154244
// overwrite the previous file when it exists.
155245
func (c *Config) SaveTo(path string) error {
156246
path = filepath.Clean(path)
157247

158-
// STEP 1: marshal config
159-
file, err := yaml.Marshal(c)
248+
// STEP 1: Render the configuration file as a file
249+
file, err := c.HumanConfig()
160250
if err != nil {
161251
return err
162252
}
@@ -168,7 +258,7 @@ func (c *Config) SaveTo(path string) error {
168258
}
169259

170260
// STEP 3: write new config file
171-
err = ioutil.WriteFile(path, file, defaultConfigPermission)
261+
err = ioutil.WriteFile(path, []byte(file), defaultConfigPermission)
172262
if err != nil {
173263
return err
174264
}

scw/config_test.go

Lines changed: 238 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,12 @@ func TestSaveConfig(t *testing.T) {
228228
testhelpers.AssertNoError(t, test.config.Save())
229229

230230
// test expected files
231-
for fileName, expectedContent := range test.expectedFiles {
231+
for fileName := range test.expectedFiles {
232+
expectedContent, err := test.config.HumanConfig()
233+
testhelpers.AssertNoError(t, err)
232234
content, err := ioutil.ReadFile(filepath.Join(dir, fileName))
233235
testhelpers.AssertNoError(t, err)
234-
testhelpers.Equals(t, expectedContent, "\n"+string(content))
236+
testhelpers.Equals(t, expectedContent, string(content))
235237
}
236238

237239
})
@@ -580,3 +582,237 @@ func z(value Zone) *Zone {
580582
func b(value bool) *bool {
581583
return &value
582584
}
585+
586+
func TestConfig_ConfigFile(t *testing.T) {
587+
588+
type testCase struct {
589+
config *Config
590+
result string
591+
}
592+
593+
run := func(c *testCase) func(t *testing.T) {
594+
return func(t *testing.T) {
595+
config, err := c.config.HumanConfig()
596+
testhelpers.AssertNoError(t, err)
597+
testhelpers.Equals(t, c.result, config)
598+
599+
loaded, err2 := unmarshalConfV2([]byte(config))
600+
testhelpers.AssertNoError(t, err2)
601+
testhelpers.Equals(t, c.config, loaded)
602+
}
603+
}
604+
605+
t.Run("empty", run(&testCase{
606+
config: &Config{},
607+
result: `# Scaleway configuration file
608+
# https://github.com/scaleway/scaleway-sdk-go/tree/master/scw#scaleway-config
609+
610+
# You need an access key and a secret key to connect to Scaleway API.
611+
# Generate your token at the following address: https://console.scaleway.com/account/credentials
612+
613+
# An access key is a secret key identifier.
614+
# access_key: SCW11111111111111111
615+
616+
# The secret key is the value that can be used to authenticate against the API (the value used in X-Auth-Token HTTP-header).
617+
# The secret key MUST remain secret and not given to anyone or published online.
618+
# secret_key: 11111111-1111-1111-1111-111111111111
619+
620+
# Your organization ID is the identifier of your account inside Scaleway infrastructure.
621+
# default_organization_id: 11111111-1111-1111-1111-111111111111
622+
623+
# A region is represented as a geographical area such as France (Paris) or the Netherlands (Amsterdam).
624+
# It can contain multiple availability zones.
625+
# Example of region: fr-par, nl-ams
626+
# default_region: fr-par
627+
628+
# A region can be split into many availability zones (AZ).
629+
# Latency between multiple AZ of the same region are low as they have a common network layer.
630+
# Example of zones: fr-par-1, nl-ams-1
631+
# default_zone: fr-par-1
632+
633+
# APIURL overrides the API URL of the Scaleway API to the given URL.
634+
# Change that if you want to direct requests to a different endpoint.
635+
# api_url: https://api.scaleway.com
636+
637+
# Insecure enables insecure transport on the client.
638+
# Default to false
639+
# insecure: false
640+
641+
# A configuration is a named set of Scaleway properties.
642+
# Starting off with a Scaleway SDK or Scaleway CLI, you’ll work with a single configuration named default.
643+
# You can set properties of the default profile by running either scw init or scw config set.
644+
# This single default configuration is suitable for most use cases.
645+
# active_profile: myProfile
646+
647+
# To work with multiple projects or authorization accounts, you can set up multiple configurations with scw config configurations create and switch among them accordingly.
648+
# You can use a profile by either:
649+
# - Define the profile you want to use as the SCW_PROFILE environment variable
650+
# - Use the GetActiveProfile() function in the SDK
651+
# - Use the --profile flag with the CLI
652+
653+
# You can define a profile using the following syntax:
654+
655+
# profiles:
656+
# myProfile:
657+
# access_key: 11111111-1111-1111-1111-111111111111
658+
# secret_key: 11111111-1111-1111-1111-111111111111
659+
# organization_id: 11111111-1111-1111-1111-111111111111
660+
# default_zone: fr-par-1
661+
# default_region: fr-par
662+
# api_url: https://api.scaleway.com
663+
# insecure: false
664+
`,
665+
}))
666+
667+
t.Run("partial", run(&testCase{
668+
config: &Config{
669+
Profile: Profile{
670+
AccessKey: s(v2ValidAccessKey),
671+
}},
672+
result: `# Scaleway configuration file
673+
# https://github.com/scaleway/scaleway-sdk-go/tree/master/scw#scaleway-config
674+
675+
# You need an access key and a secret key to connect to Scaleway API.
676+
# Generate your token at the following address: https://console.scaleway.com/account/credentials
677+
678+
# An access key is a secret key identifier.
679+
access_key: SCW1234567890ABCDEFG
680+
681+
# The secret key is the value that can be used to authenticate against the API (the value used in X-Auth-Token HTTP-header).
682+
# The secret key MUST remain secret and not given to anyone or published online.
683+
# secret_key: 11111111-1111-1111-1111-111111111111
684+
685+
# Your organization ID is the identifier of your account inside Scaleway infrastructure.
686+
# default_organization_id: 11111111-1111-1111-1111-111111111111
687+
688+
# A region is represented as a geographical area such as France (Paris) or the Netherlands (Amsterdam).
689+
# It can contain multiple availability zones.
690+
# Example of region: fr-par, nl-ams
691+
# default_region: fr-par
692+
693+
# A region can be split into many availability zones (AZ).
694+
# Latency between multiple AZ of the same region are low as they have a common network layer.
695+
# Example of zones: fr-par-1, nl-ams-1
696+
# default_zone: fr-par-1
697+
698+
# APIURL overrides the API URL of the Scaleway API to the given URL.
699+
# Change that if you want to direct requests to a different endpoint.
700+
# api_url: https://api.scaleway.com
701+
702+
# Insecure enables insecure transport on the client.
703+
# Default to false
704+
# insecure: false
705+
706+
# A configuration is a named set of Scaleway properties.
707+
# Starting off with a Scaleway SDK or Scaleway CLI, you’ll work with a single configuration named default.
708+
# You can set properties of the default profile by running either scw init or scw config set.
709+
# This single default configuration is suitable for most use cases.
710+
# active_profile: myProfile
711+
712+
# To work with multiple projects or authorization accounts, you can set up multiple configurations with scw config configurations create and switch among them accordingly.
713+
# You can use a profile by either:
714+
# - Define the profile you want to use as the SCW_PROFILE environment variable
715+
# - Use the GetActiveProfile() function in the SDK
716+
# - Use the --profile flag with the CLI
717+
718+
# You can define a profile using the following syntax:
719+
720+
# profiles:
721+
# myProfile:
722+
# access_key: 11111111-1111-1111-1111-111111111111
723+
# secret_key: 11111111-1111-1111-1111-111111111111
724+
# organization_id: 11111111-1111-1111-1111-111111111111
725+
# default_zone: fr-par-1
726+
# default_region: fr-par
727+
# api_url: https://api.scaleway.com
728+
# insecure: false
729+
`,
730+
}))
731+
732+
t.Run("full", run(&testCase{
733+
config: &Config{
734+
Profile: Profile{
735+
AccessKey: s(v2ValidAccessKey),
736+
SecretKey: s(v2ValidSecretKey),
737+
},
738+
ActiveProfile: s(v2ValidProfile),
739+
Profiles: map[string]*Profile{
740+
"profile1": {
741+
AccessKey: s(v2ValidAccessKey2),
742+
SecretKey: s(v2ValidSecretKey2),
743+
},
744+
"profile2": {
745+
AccessKey: s(v2ValidAccessKey2),
746+
SecretKey: s(v2ValidSecretKey2),
747+
},
748+
},
749+
},
750+
result: `# Scaleway configuration file
751+
# https://github.com/scaleway/scaleway-sdk-go/tree/master/scw#scaleway-config
752+
753+
# You need an access key and a secret key to connect to Scaleway API.
754+
# Generate your token at the following address: https://console.scaleway.com/account/credentials
755+
756+
# An access key is a secret key identifier.
757+
access_key: SCW1234567890ABCDEFG
758+
759+
# The secret key is the value that can be used to authenticate against the API (the value used in X-Auth-Token HTTP-header).
760+
# The secret key MUST remain secret and not given to anyone or published online.
761+
secret_key: 7363616c-6577-6573-6862-6f7579616161
762+
763+
# Your organization ID is the identifier of your account inside Scaleway infrastructure.
764+
# default_organization_id: 11111111-1111-1111-1111-111111111111
765+
766+
# A region is represented as a geographical area such as France (Paris) or the Netherlands (Amsterdam).
767+
# It can contain multiple availability zones.
768+
# Example of region: fr-par, nl-ams
769+
# default_region: fr-par
770+
771+
# A region can be split into many availability zones (AZ).
772+
# Latency between multiple AZ of the same region are low as they have a common network layer.
773+
# Example of zones: fr-par-1, nl-ams-1
774+
# default_zone: fr-par-1
775+
776+
# APIURL overrides the API URL of the Scaleway API to the given URL.
777+
# Change that if you want to direct requests to a different endpoint.
778+
# api_url: https://api.scaleway.com
779+
780+
# Insecure enables insecure transport on the client.
781+
# Default to false
782+
# insecure: false
783+
784+
# A configuration is a named set of Scaleway properties.
785+
# Starting off with a Scaleway SDK or Scaleway CLI, you’ll work with a single configuration named default.
786+
# You can set properties of the default profile by running either scw init or scw config set.
787+
# This single default configuration is suitable for most use cases.
788+
active_profile: flantier
789+
790+
# To work with multiple projects or authorization accounts, you can set up multiple configurations with scw config configurations create and switch among them accordingly.
791+
# You can use a profile by either:
792+
# - Define the profile you want to use as the SCW_PROFILE environment variable
793+
# - Use the GetActiveProfile() function in the SDK
794+
# - Use the --profile flag with the CLI
795+
796+
# You can define a profile using the following syntax:
797+
798+
profiles:
799+
profile1:
800+
access_key: SCW234567890ABCDEFGH
801+
secret_key: 6f6e6574-6f72-756c-6c74-68656d616c6c
802+
# default_organization_id: 11111111-1111-1111-1111-111111111111
803+
# default_zone: fr-par-1
804+
# default_region: fr-par
805+
# api_url: https://api.scaleway.com
806+
# insecure: false
807+
808+
profile2:
809+
access_key: SCW234567890ABCDEFGH
810+
secret_key: 6f6e6574-6f72-756c-6c74-68656d616c6c
811+
# default_organization_id: 11111111-1111-1111-1111-111111111111
812+
# default_zone: fr-par-1
813+
# default_region: fr-par
814+
# api_url: https://api.scaleway.com
815+
# insecure: false
816+
`,
817+
}))
818+
}

0 commit comments

Comments
 (0)