Skip to content

Commit

Permalink
feat(core): add scw.MergeProfiles command (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentin Brosse authored Nov 13, 2019
1 parent 7a70251 commit ea25b42
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 70 deletions.
51 changes: 45 additions & 6 deletions scw/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ type Config struct {
}

type Profile struct {
AccessKey *string `yaml:"access_key,omitempty"`
SecretKey *string `yaml:"secret_key,omitempty"`
APIURL *string `yaml:"api_url,omitempty"`
Insecure *bool `yaml:"insecure,omitempty"`
AccessKey *string `yaml:"access_key,omitempty"`
SecretKey *string `yaml:"secret_key,omitempty"`
APIURL *string `yaml:"api_url,omitempty"`
Insecure *bool `yaml:"insecure,omitempty"`
DefaultOrganizationID *string `yaml:"default_organization_id,omitempty"`
DefaultRegion *string `yaml:"default_region,omitempty"`
DefaultZone *string `yaml:"default_zone,omitempty"`
DefaultRegion *string `yaml:"default_region,omitempty"`
DefaultZone *string `yaml:"default_zone,omitempty"`
}

func (p *Profile) String() string {
Expand Down Expand Up @@ -175,3 +175,42 @@ func (c *Config) SaveTo(path string) error {
return nil

}

// MergeProfiles merges profiles in a new one. The last profile has priority.
func MergeProfiles(original *Profile, others ...*Profile) *Profile {
np := &Profile{
AccessKey: original.AccessKey,
SecretKey: original.SecretKey,
APIURL: original.APIURL,
Insecure: original.Insecure,
DefaultOrganizationID: original.DefaultOrganizationID,
DefaultRegion: original.DefaultRegion,
DefaultZone: original.DefaultZone,
}

for _, other := range others {
if other.AccessKey != nil {
np.AccessKey = other.AccessKey
}
if other.SecretKey != nil {
np.SecretKey = other.SecretKey
}
if other.APIURL != nil {
np.APIURL = other.APIURL
}
if other.Insecure != nil {
np.Insecure = other.Insecure
}
if other.DefaultOrganizationID != nil {
np.DefaultOrganizationID = other.DefaultOrganizationID
}
if other.DefaultRegion != nil {
np.DefaultRegion = other.DefaultRegion
}
if other.DefaultZone != nil {
np.DefaultZone = other.DefaultZone
}
}

return np
}
153 changes: 89 additions & 64 deletions scw/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ func TestSaveConfig(t *testing.T) {
},
config: &Config{
Profile: Profile{
AccessKey: s(v2ValidAccessKey),
SecretKey: s(v2ValidSecretKey),
AccessKey: s(v2ValidAccessKey),
SecretKey: s(v2ValidSecretKey),
DefaultOrganizationID: s(v2ValidDefaultOrganizationID),
DefaultRegion: s(v2ValidDefaultRegion),
DefaultRegion: s(v2ValidDefaultRegion),
},
},
expectedFiles: map[string]string{
Expand All @@ -106,10 +106,10 @@ func TestSaveConfig(t *testing.T) {
},
config: &Config{
Profile: Profile{
AccessKey: s(v2ValidAccessKey),
SecretKey: s(v2ValidSecretKey),
AccessKey: s(v2ValidAccessKey),
SecretKey: s(v2ValidSecretKey),
DefaultOrganizationID: s(v2ValidDefaultOrganizationID),
DefaultRegion: s(v2ValidDefaultRegion),
DefaultRegion: s(v2ValidDefaultRegion),
},
},
expectedFiles: map[string]string{
Expand Down Expand Up @@ -145,13 +145,13 @@ func TestSaveConfig(t *testing.T) {
funcUpdateConfig: func(c *Config) {
*c = *MustLoadConfig()
c.Profiles = map[string]*Profile{v2ValidProfile: {
AccessKey: s(v2ValidAccessKey2),
SecretKey: s(v2ValidSecretKey2),
APIURL: s(v2ValidAPIURL2),
Insecure: b(true),
AccessKey: s(v2ValidAccessKey2),
SecretKey: s(v2ValidSecretKey2),
APIURL: s(v2ValidAPIURL2),
Insecure: b(true),
DefaultOrganizationID: s(v2ValidDefaultOrganizationID2),
DefaultRegion: s(v2ValidDefaultRegion2),
DefaultZone: s(v2ValidDefaultZone2),
DefaultRegion: s(v2ValidDefaultRegion2),
DefaultZone: s(v2ValidDefaultZone2),
}}
},
expectedFiles: map[string]string{
Expand Down Expand Up @@ -198,14 +198,14 @@ func TestLoadProfileAndActiveProfile(t *testing.T) {
files map[string]string
isMigrated bool

expectedError string
expectedAccessKey *string
expectedSecretKey *string
expectedAPIURL *string
expectedInsecure *bool
expectedError string
expectedAccessKey *string
expectedSecretKey *string
expectedAPIURL *string
expectedInsecure *bool
expectedDefaultOrganizationID *string
expectedDefaultRegion *string
expectedDefaultZone *string
expectedDefaultRegion *string
expectedDefaultZone *string
}{
// no env variables
{
Expand Down Expand Up @@ -236,10 +236,10 @@ func TestLoadProfileAndActiveProfile(t *testing.T) {
files: map[string]string{
"valid3/test.conf": v2SimpleValidConfigFile,
},
expectedAccessKey: s(v2ValidAccessKey),
expectedSecretKey: s(v2ValidSecretKey),
expectedAccessKey: s(v2ValidAccessKey),
expectedSecretKey: s(v2ValidSecretKey),
expectedDefaultOrganizationID: s(v2ValidDefaultOrganizationID),
expectedDefaultRegion: s(v2ValidDefaultRegion),
expectedDefaultRegion: s(v2ValidDefaultRegion),
},
{
name: "Simple config with valid V2", // default config path
Expand All @@ -249,10 +249,10 @@ func TestLoadProfileAndActiveProfile(t *testing.T) {
files: map[string]string{
".config/scw/config.yaml": v2SimpleValidConfigFile,
},
expectedAccessKey: s(v2ValidAccessKey),
expectedSecretKey: s(v2ValidSecretKey),
expectedAccessKey: s(v2ValidAccessKey),
expectedSecretKey: s(v2ValidSecretKey),
expectedDefaultOrganizationID: s(v2ValidDefaultOrganizationID),
expectedDefaultRegion: s(v2ValidDefaultRegion),
expectedDefaultRegion: s(v2ValidDefaultRegion),
},
{
name: "Simple config with valid V1",
Expand All @@ -262,8 +262,8 @@ func TestLoadProfileAndActiveProfile(t *testing.T) {
files: map[string]string{
".scwrc": v1ValidConfigFile,
},
isMigrated: true,
expectedSecretKey: s(v1ValidToken),
isMigrated: true,
expectedSecretKey: s(v1ValidToken),
expectedDefaultOrganizationID: s(v1ValidOrganizationID),
},
{
Expand All @@ -275,10 +275,10 @@ func TestLoadProfileAndActiveProfile(t *testing.T) {
".config/scw/config.yaml": v2SimpleValidConfigFile,
".scwrc": v1ValidConfigFile,
},
expectedAccessKey: s(v2ValidAccessKey),
expectedSecretKey: s(v2ValidSecretKey),
expectedAccessKey: s(v2ValidAccessKey),
expectedSecretKey: s(v2ValidSecretKey),
expectedDefaultOrganizationID: s(v2ValidDefaultOrganizationID),
expectedDefaultRegion: s(v2ValidDefaultRegion),
expectedDefaultRegion: s(v2ValidDefaultRegion),
},
{
name: "Complete config",
Expand All @@ -288,13 +288,13 @@ func TestLoadProfileAndActiveProfile(t *testing.T) {
files: map[string]string{
".config/scw/config.yaml": v2CompleteValidConfigFile,
},
expectedAccessKey: s(v2ValidAccessKey),
expectedSecretKey: s(v2ValidSecretKey),
expectedAPIURL: s(v2ValidAPIURL),
expectedInsecure: b(false),
expectedAccessKey: s(v2ValidAccessKey),
expectedSecretKey: s(v2ValidSecretKey),
expectedAPIURL: s(v2ValidAPIURL),
expectedInsecure: b(false),
expectedDefaultOrganizationID: s(v2ValidDefaultOrganizationID),
expectedDefaultRegion: s(v2ValidDefaultRegion),
expectedDefaultZone: s(v2ValidDefaultZone),
expectedDefaultRegion: s(v2ValidDefaultRegion),
expectedDefaultZone: s(v2ValidDefaultZone),
},
{
name: "Complete config with active profile",
Expand All @@ -304,13 +304,13 @@ func TestLoadProfileAndActiveProfile(t *testing.T) {
files: map[string]string{
".config/scw/config.yaml": v2CompleteValidConfigWithActiveProfileFile,
},
expectedAccessKey: s(v2ValidAccessKey2),
expectedSecretKey: s(v2ValidSecretKey2),
expectedAPIURL: s(v2ValidAPIURL2),
expectedInsecure: b(true),
expectedAccessKey: s(v2ValidAccessKey2),
expectedSecretKey: s(v2ValidSecretKey2),
expectedAPIURL: s(v2ValidAPIURL2),
expectedInsecure: b(true),
expectedDefaultOrganizationID: s(v2ValidDefaultOrganizationID2),
expectedDefaultRegion: s(v2ValidDefaultRegion2),
expectedDefaultZone: s(v2ValidDefaultZone2),
expectedDefaultRegion: s(v2ValidDefaultRegion2),
expectedDefaultZone: s(v2ValidDefaultZone2),
},
{
name: "Complete config with active profile env variable",
Expand All @@ -321,13 +321,13 @@ func TestLoadProfileAndActiveProfile(t *testing.T) {
files: map[string]string{
".config/scw/config.yaml": v2CompleteValidConfigFile,
},
expectedAccessKey: s(v2ValidAccessKey2),
expectedSecretKey: s(v2ValidSecretKey2),
expectedAPIURL: s(v2ValidAPIURL2),
expectedInsecure: b(true),
expectedAccessKey: s(v2ValidAccessKey2),
expectedSecretKey: s(v2ValidSecretKey2),
expectedAPIURL: s(v2ValidAPIURL2),
expectedInsecure: b(true),
expectedDefaultOrganizationID: s(v2ValidDefaultOrganizationID2),
expectedDefaultRegion: s(v2ValidDefaultRegion2),
expectedDefaultZone: s(v2ValidDefaultZone2),
expectedDefaultRegion: s(v2ValidDefaultRegion2),
expectedDefaultZone: s(v2ValidDefaultZone2),
},

// Valid V1 is not allowed
Expand Down Expand Up @@ -404,29 +404,29 @@ const emptyFile = ""

// v2 config
var (
v2ValidAccessKey2 = "ACCESS_KEY2"
v2ValidSecretKey2 = "6f6e6574-6f72-756c-6c74-68656d616c6c" // hint: | xxd -ps -r
v2ValidAPIURL2 = "api-fr-par.scaleway.com"
v2ValidInsecure2 = "true"
v2ValidAccessKey2 = "ACCESS_KEY2"
v2ValidSecretKey2 = "6f6e6574-6f72-756c-6c74-68656d616c6c" // hint: | xxd -ps -r
v2ValidAPIURL2 = "api-fr-par.scaleway.com"
v2ValidInsecure2 = "true"
v2ValidDefaultOrganizationID2 = "6d6f7264-6f72-6772-6561-74616761696e" // hint: | xxd -ps -r
v2ValidDefaultRegion2 = string(RegionFrPar)
v2ValidDefaultZone2 = string(ZoneFrPar2)
v2ValidDefaultRegion2 = string(RegionFrPar)
v2ValidDefaultZone2 = string(ZoneFrPar2)

v2ValidAccessKey = "ACCESS_KEY"
v2ValidSecretKey = "7363616c-6577-6573-6862-6f7579616161" // hint: | xxd -ps -r
v2ValidAPIURL = "api.scaleway.com"
v2ValidInsecure = "false"
v2ValidAccessKey = "ACCESS_KEY"
v2ValidSecretKey = "7363616c-6577-6573-6862-6f7579616161" // hint: | xxd -ps -r
v2ValidAPIURL = "api.scaleway.com"
v2ValidInsecure = "false"
v2ValidDefaultOrganizationID = "6170692e-7363-616c-6577-61792e636f6d" // hint: | xxd -ps -r
v2ValidDefaultRegion = string(RegionNlAms)
v2ValidDefaultZone = string(ZoneNlAms1)
v2ValidProfile = "flantier"
v2ValidDefaultRegion = string(RegionNlAms)
v2ValidDefaultZone = string(ZoneNlAms1)
v2ValidProfile = "flantier"

v2SimpleValidConfig = &Config{
Profile: Profile{
AccessKey: &v2ValidAccessKey,
SecretKey: &v2ValidSecretKey,
AccessKey: &v2ValidAccessKey,
SecretKey: &v2ValidSecretKey,
DefaultOrganizationID: &v2ValidDefaultOrganizationID,
DefaultRegion: &v2ValidDefaultRegion,
DefaultRegion: &v2ValidDefaultRegion,
},
}
v2PartialValidConfigFile = `
Expand Down Expand Up @@ -518,3 +518,28 @@ secret_key: 6f6e6574-xxxx-xxxx-xxxx-xxxxxxxxxxxx
testhelpers.Equals(t, v2ValidSecretKey2, *p.SecretKey)

}

func TestMergeProfiles(t *testing.T) {
p1 := &Profile{
AccessKey: StringPtr("1"),
SecretKey: StringPtr("1"),
}
p2 := &Profile{
AccessKey: StringPtr("2"),
Insecure: BoolPtr(true),
}
p3 := &Profile{
Insecure: BoolPtr(false),
DefaultZone: StringPtr(string(ZoneFrPar1)),
}

act := MergeProfiles(p1, p2, p3)
exp := &Profile{
AccessKey: StringPtr("2"),
SecretKey: StringPtr("1"),
Insecure: BoolPtr(false),
DefaultZone: StringPtr(string(ZoneFrPar1)),
}

testhelpers.Equals(t, exp, act)
}

0 comments on commit ea25b42

Please sign in to comment.