Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add projects #452

Merged
merged 4 commits into from
Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions scw/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Client struct {
apiURL string
userAgent string
defaultOrganizationID *string
defaultProjectID *string
defaultRegion *Region
defaultZone *Zone
defaultPageSize *uint32
Expand Down Expand Up @@ -76,6 +77,7 @@ func NewClient(opts ...ClientOption) (*Client, error) {
apiURL: s.apiURL,
userAgent: s.userAgent,
defaultOrganizationID: s.defaultOrganizationID,
defaultProjectID: s.defaultProjectID,
defaultRegion: s.defaultRegion,
defaultZone: s.defaultZone,
defaultPageSize: s.defaultPageSize,
Expand All @@ -92,6 +94,16 @@ func (c *Client) GetDefaultOrganizationID() (organizationID string, exists bool)
return "", false
}

// GetDefaultProjectID returns the default project ID
// of the client. This value can be set in the client option
// WithDefaultProjectID(). Be aware this value can be empty.
func (c *Client) GetDefaultProjectID() (projectID string, exists bool) {
if c.defaultProjectID != nil {
return *c.defaultProjectID, true
}
return "", false
}

// GetDefaultRegion returns the default region of the client.
// This value can be set in the client option
// WithDefaultRegion(). Be aware this value can be empty.
Expand Down
25 changes: 25 additions & 0 deletions scw/client_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ func WithProfile(p *Profile) ClientOption {
s.defaultOrganizationID = &organizationID
}

if p.DefaultProjectID != nil {
projectID := *p.DefaultProjectID
s.defaultProjectID = &projectID
}

if p.DefaultRegion != nil {
defaultRegion := Region(*p.DefaultRegion)
s.defaultRegion = &defaultRegion
Expand All @@ -120,6 +125,15 @@ func WithDefaultOrganizationID(organizationID string) ClientOption {
}
}

// WithDefaultProjectID client option sets the client default project ID.
//
// It will be used as the default value of the projectID field in all requests made with this client.
func WithDefaultProjectID(projectID string) ClientOption {
return func(s *settings) {
s.defaultProjectID = &projectID
}
}

// WithDefaultRegion client option sets the client default region.
//
// It will be used as the default value of the region field in all requests made with this client.
Expand Down Expand Up @@ -155,6 +169,7 @@ type settings struct {
httpClient httpClient
insecure bool
defaultOrganizationID *string
defaultProjectID *string
defaultRegion *Region
defaultZone *Zone
defaultPageSize *uint32
Expand Down Expand Up @@ -201,6 +216,16 @@ func (s *settings) validate() error {
}
}

// Default Project ID.
if s.defaultProjectID != nil {
if *s.defaultProjectID == "" {
return NewInvalidClientOptionError("default project ID cannot be empty")
}
if !validation.IsProjectID(*s.defaultProjectID) {
return NewInvalidClientOptionError("invalid project ID format '%s', expected a UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", *s.defaultProjectID)
}
}

// Default Region.
if s.defaultRegion != nil {
if *s.defaultRegion == "" {
Expand Down
24 changes: 24 additions & 0 deletions scw/client_option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

var (
defaultOrganizationID = "6170692e-7363-616c-6577-61792e636f6d" // hint: | xxd -ps -r
defaultProjectID = "6170692e-7363-616c-6577-61792e636f6d" // hint: | xxd -ps -r
defaultRegion = RegionNlAms
defaultZone = ZoneNlAms1
)
Expand All @@ -27,6 +28,7 @@ func TestClientOptions(t *testing.T) {
s.token = auth.NewToken(v2ValidAccessKey, v2ValidSecretKey)
s.apiURL = v2ValidAPIURL
s.defaultOrganizationID = &defaultOrganizationID
s.defaultProjectID = &defaultProjectID
s.defaultRegion = &defaultRegion
s.defaultZone = &defaultZone
},
Expand Down Expand Up @@ -83,6 +85,22 @@ func TestClientOptions(t *testing.T) {
},
errStr: "scaleway-sdk-go: invalid organization ID format 'invalid', expected a UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
},
{
name: "Should throw an empty project ID error",
clientOption: func(s *settings) {
s.token = auth.NewToken(v2ValidAccessKey, v2ValidSecretKey)
s.defaultProjectID = StringPtr("")
},
errStr: "scaleway-sdk-go: default project ID cannot be empty",
},
{
name: "Should throw a bad project ID error",
clientOption: func(s *settings) {
s.token = auth.NewToken(v2ValidAccessKey, v2ValidSecretKey)
s.defaultProjectID = StringPtr(v2InvalidDefaultProjectID)
},
errStr: "scaleway-sdk-go: invalid project ID format 'invalid', expected a UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
},
{
name: "Should throw a region error",
clientOption: func(s *settings) {
Expand Down Expand Up @@ -153,6 +171,7 @@ func TestCombinedClientOptions(t *testing.T) {
expectedSecretKey string
expectedAPIURL string
expectedDefaultOrganizationID *string
expectedDefaultProjectID *string
expectedDefaultRegion *Region
expectedDefaultZone *Zone
}{
Expand All @@ -164,6 +183,7 @@ func TestCombinedClientOptions(t *testing.T) {
ScwSecretKeyEnv: v2ValidSecretKey2,
ScwAPIURLEnv: v2ValidAPIURL2,
ScwDefaultOrganizationIDEnv: v2ValidDefaultOrganizationID2,
ScwDefaultProjectIDEnv: v2ValidDefaultProjectID2,
ScwDefaultRegionEnv: v2ValidDefaultRegion2,
ScwDefaultZoneEnv: v2ValidDefaultZone2,
},
Expand All @@ -174,6 +194,7 @@ func TestCombinedClientOptions(t *testing.T) {
expectedSecretKey: v2ValidSecretKey2,
expectedAPIURL: v2ValidAPIURL2,
expectedDefaultOrganizationID: s(v2ValidDefaultOrganizationID2),
expectedDefaultProjectID: s(v2ValidDefaultProjectID2),
expectedDefaultRegion: r(Region(v2ValidDefaultRegion2)),
expectedDefaultZone: z(Zone(v2ValidDefaultZone2)),
},
Expand All @@ -186,6 +207,7 @@ func TestCombinedClientOptions(t *testing.T) {
ScwSecretKeyEnv: v2ValidSecretKey,
ScwAPIURLEnv: v2ValidAPIURL,
ScwDefaultOrganizationIDEnv: v2ValidDefaultOrganizationID,
ScwDefaultProjectIDEnv: v2ValidDefaultProjectID,
ScwDefaultRegionEnv: v2ValidDefaultRegion,
ScwDefaultZoneEnv: v2ValidDefaultZone,
},
Expand All @@ -196,6 +218,7 @@ func TestCombinedClientOptions(t *testing.T) {
expectedSecretKey: v2ValidSecretKey,
expectedAPIURL: v2ValidAPIURL,
expectedDefaultOrganizationID: s(v2ValidDefaultOrganizationID),
expectedDefaultProjectID: s(v2ValidDefaultProjectID),
expectedDefaultRegion: r(Region(v2ValidDefaultRegion)),
expectedDefaultZone: z(Zone(v2ValidDefaultZone)),
},
Expand Down Expand Up @@ -230,6 +253,7 @@ func TestCombinedClientOptions(t *testing.T) {
testhelpers.Equals(t, test.expectedSecretKey, client.auth.(*auth.Token).SecretKey)
testhelpers.Equals(t, test.expectedAPIURL, client.apiURL)
testhelpers.Equals(t, test.expectedDefaultOrganizationID, client.defaultOrganizationID)
testhelpers.Equals(t, test.expectedDefaultProjectID, client.defaultProjectID)
testhelpers.Equals(t, test.expectedDefaultRegion, client.defaultRegion)
testhelpers.Equals(t, test.expectedDefaultZone, client.defaultZone)
// skip insecure tests
Expand Down
11 changes: 11 additions & 0 deletions scw/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const (
testAccessKey = "SCW1234567890ABCDEFG"
testSecretKey = "7363616c-6577-6573-6862-6f7579616161" // hint: | xxd -ps -r
testDefaultOrganizationID = "6170692e-7363-616c-6577-61792e636f6d" // hint: | xxd -ps -r
testDefaultProjectID = "6170692e-7363-616c-6577-61792e636f6e"
testDefaultRegion = RegionFrPar
testDefaultZone = ZoneFrPar1
testDefaultPageSize = uint32(5)
Expand Down Expand Up @@ -60,6 +61,7 @@ func TestNewClientWithOptions(t *testing.T) {
WithAuth(testAccessKey, testSecretKey),
WithHTTPClient(someHTTPClient),
WithDefaultOrganizationID(testDefaultOrganizationID),
WithDefaultProjectID(testDefaultProjectID),
WithDefaultRegion(testDefaultRegion),
WithDefaultZone(testDefaultZone),
WithDefaultPageSize(testDefaultPageSize),
Expand All @@ -77,6 +79,10 @@ func TestNewClientWithOptions(t *testing.T) {
testhelpers.Equals(t, testDefaultOrganizationID, defaultOrganizationID)
testhelpers.Assert(t, exist, "defaultOrganizationID must exist")

defaultProjectID, exist := client.GetDefaultProjectID()
testhelpers.Equals(t, testDefaultProjectID, defaultProjectID)
testhelpers.Assert(t, exist, "defaultProjectID must exist")

defaultRegion, exist := client.GetDefaultRegion()
testhelpers.Equals(t, testDefaultRegion, defaultRegion)
testhelpers.Assert(t, exist, "defaultRegion must exist")
Expand Down Expand Up @@ -105,6 +111,7 @@ func TestNewClientWithOptions(t *testing.T) {
s(testAPIURL),
b(testInsecure),
s(testDefaultOrganizationID),
s(testDefaultProjectID),
s(string(testDefaultRegion)),
s(string(testDefaultZone)),
b(true),
Expand All @@ -125,6 +132,10 @@ func TestNewClientWithOptions(t *testing.T) {
testhelpers.Equals(t, testDefaultOrganizationID, defaultOrganizationID)
testhelpers.Assert(t, exist, "defaultOrganizationID must exist")

defaultProjectID, exist := client.GetDefaultProjectID()
testhelpers.Equals(t, testDefaultProjectID, defaultProjectID)
testhelpers.Assert(t, exist, "defaultProjectID must exist")

defaultRegion, exist := client.GetDefaultRegion()
testhelpers.Equals(t, testDefaultRegion, defaultRegion)
testhelpers.Assert(t, exist, "defaultRegion must exist")
Expand Down
12 changes: 11 additions & 1 deletion scw/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ const configFileTemplate = `# Scaleway configuration file
# Your organization ID is the identifier of your account inside Scaleway infrastructure.
{{ if .DefaultOrganizationID }}default_organization_id: {{ .DefaultOrganizationID }}{{ else }}# default_organization_id: 11111111-1111-1111-1111-111111111111{{ end }}

# Your project ID is the identifier of the project your resources are attached to (beta).
{{ if .DefaultProjectID }}default_project_id: {{ .DefaultProjectID }}{{ else }}# default_project_id: 11111111-1111-1111-1111-111111111111{{ end }}

# A region is represented as a geographical area such as France (Paris) or the Netherlands (Amsterdam).
# It can contain multiple availability zones.
# Example of region: fr-par, nl-ams
Expand Down Expand Up @@ -81,6 +84,7 @@ profiles:
{{ if $v.AccessKey }}access_key: {{ $v.AccessKey }}{{ else }}# access_key: SCW11111111111111111{{ end }}
{{ if $v.SecretKey }}secret_key: {{ $v.SecretKey }}{{ else }}# secret_key: 11111111-1111-1111-1111-111111111111{{ end }}
{{ if $v.DefaultOrganizationID }}default_organization_id: {{ $v.DefaultOrganizationID }}{{ else }}# default_organization_id: 11111111-1111-1111-1111-111111111111{{ end }}
{{ if $v.DefaultProjectID }}default_project_id: {{ $v.DefaultProjectID }}{{ else }}# default_project_id: 11111111-1111-1111-1111-111111111111{{ end }}
{{ if $v.DefaultZone }}default_zone: {{ $v.DefaultZone }}{{ else }}# default_zone: fr-par-1{{ end }}
{{ if $v.DefaultRegion }}default_region: {{ $v.DefaultRegion }}{{ else }}# default_region: fr-par{{ end }}
{{ if $v.APIURL }}api_url: {{ $v.APIURL }}{{ else }}# api_url: https://api.scaleway.com{{ end }}
Expand All @@ -91,7 +95,8 @@ profiles:
# myProfile:
# access_key: 11111111-1111-1111-1111-111111111111
# secret_key: 11111111-1111-1111-1111-111111111111
# organization_id: 11111111-1111-1111-1111-111111111111
kindermoumoute marked this conversation as resolved.
Show resolved Hide resolved
# default_organization_id: 11111111-1111-1111-1111-111111111111
# default_project_id: 11111111-1111-1111-1111-111111111111
# default_zone: fr-par-1
# default_region: fr-par
# api_url: https://api.scaleway.com
Expand All @@ -111,6 +116,7 @@ type Profile struct {
APIURL *string `yaml:"api_url,omitempty"`
Insecure *bool `yaml:"insecure,omitempty"`
DefaultOrganizationID *string `yaml:"default_organization_id,omitempty"`
DefaultProjectID *string `yaml:"default_project_id,omitempty"`
DefaultRegion *string `yaml:"default_region,omitempty"`
DefaultZone *string `yaml:"default_zone,omitempty"`
SendTelemetry *bool `yaml:"send_telemetry,omitempty"`
Expand Down Expand Up @@ -294,6 +300,7 @@ func MergeProfiles(original *Profile, others ...*Profile) *Profile {
APIURL: original.APIURL,
Insecure: original.Insecure,
DefaultOrganizationID: original.DefaultOrganizationID,
DefaultProjectID: original.DefaultProjectID,
DefaultRegion: original.DefaultRegion,
DefaultZone: original.DefaultZone,
}
Expand All @@ -314,6 +321,9 @@ func MergeProfiles(original *Profile, others ...*Profile) *Profile {
if other.DefaultOrganizationID != nil {
np.DefaultOrganizationID = other.DefaultOrganizationID
}
if other.DefaultProjectID != nil {
np.DefaultProjectID = other.DefaultProjectID
}
if other.DefaultRegion != nil {
np.DefaultRegion = other.DefaultRegion
}
Expand Down
1 change: 1 addition & 0 deletions scw/config_legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (v1 *configV1) toV2() *Config {
return &Config{
Profile: Profile{
DefaultOrganizationID: &v1.Organization,
DefaultProjectID: &v1.Organization, // v1 config is not aware of project, so default project is set to organization ID
SecretKey: &v1.Token,
// ignore v1 version
},
Expand Down
Loading