Skip to content

Commit

Permalink
Merge branch 'develop' into fix/SCALRCORE-20543
Browse files Browse the repository at this point in the history
# Conflicts:
#	scalr.go
  • Loading branch information
soltysss committed May 6, 2022
2 parents d3ccafe + 15457c9 commit 49f0210
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.29
version: v1.45.2
tests:
runs-on: ubuntu-latest
name: tests
Expand Down
76 changes: 74 additions & 2 deletions account.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,79 @@
package scalr

import (
"context"
"errors"
"fmt"
"net/url"
)

// Compile-time proof of interface implementation.
var _ Accounts = (*accounts)(nil)

// Accounts describes methods for updating and reading account that the
// Scalr IACP API supports.
type Accounts interface {
Read(ctx context.Context, account string) (*Account, error)
Update(ctx context.Context, account string, options AccountUpdateOptions) (*Account, error)
}

// accounts implements Accounts.
type accounts struct {
client *Client
}

// Account represents a Scalr IACP account.
type Account struct {
ID string `jsonapi:"primary,accounts"`
Name string `jsonapi:"attr,name"`
ID string `jsonapi:"primary,accounts"`
Name string `jsonapi:"attr,name"`
AllowedIPs []string `jsonapi:"attr,allowed-ips"`
}

// Read a account by its ID.
func (s *accounts) Read(ctx context.Context, accountID string) (*Account, error) {
if !validStringID(&accountID) {
return nil, errors.New("invalid value for account ID")
}

u := fmt.Sprintf("accounts/%s", url.QueryEscape(accountID))
req, err := s.client.newRequest("GET", u, nil)
if err != nil {
return nil, err
}

a := &Account{}
err = s.client.do(ctx, req, a)
if err != nil {
return nil, err
}

return a, nil
}

type AccountUpdateOptions struct {
ID string `jsonapi:"primary,accounts"`
AllowedIPs *[]string `jsonapi:"attr,allowed-ips,omitempty"`
}

func (s *accounts) Update(ctx context.Context, accountID string, options AccountUpdateOptions) (*Account, error) {
if !validStringID(&accountID) {
return nil, errors.New("invalid value for account ID")
}

// Make sure we don't send a user provided ID.
options.ID = ""

u := fmt.Sprintf("accounts/%s", url.QueryEscape(accountID))
req, err := s.client.newRequest("PATCH", u, &options)
if err != nil {
return nil, err
}

a := &Account{}
err = s.client.do(ctx, req, a)
if err != nil {
return nil, err
}

return a, nil
}
101 changes: 101 additions & 0 deletions account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package scalr

import (
"context"
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestAccountRead(t *testing.T) {
client := testClient(t)
ctx := context.Background()

t.Run("account exists", func(t *testing.T) {
account, err := client.Accounts.Read(ctx, defaultAccountID)
require.NoError(t, err)

assert.Equal(t, defaultAccountID, account.ID)
assert.Equal(t, defaultAccountName, account.Name)

assert.Equal(t, []string{}, account.AllowedIPs)
})

t.Run("account does not exist", func(t *testing.T) {
var accId = "notexisting"
_, err := client.Accounts.Read(ctx, accId)
assert.Equal(
t,
fmt.Sprintf("Clients with ID '%s' not found or user unauthorized", accId),
err.Error(),
)
})

t.Run("with invalid acc ID", func(t *testing.T) {
r, err := client.Accounts.Read(ctx, badIdentifier)
assert.Nil(t, r)
assert.EqualError(t, err, "invalid value for account ID")
})
}

func TestAccountUpdate(t *testing.T) {
client := testClient(t)
ctx := context.Background()

defer func() {
options := AccountUpdateOptions{
AllowedIPs: &[]string{},
}
if _, err := client.Accounts.Update(ctx, defaultAccountID, options); err != nil {
t.Errorf("Error resetting allowed ips for account! "+
"The full error is shown below.\n\n"+
"Account: %s\nError: %s", defaultAccountID, err)
}
}()

t.Run("valid allowed ips", func(t *testing.T) {
options := AccountUpdateOptions{
AllowedIPs: &[]string{"0.0.0.0/0", "192.168.0.0/24"},
}
account, err := client.Accounts.Update(ctx, defaultAccountID, options)
require.NoError(t, err)
for i, ip := range account.AllowedIPs {
assert.Equal(t, (*options.AllowedIPs)[i], ip)
}

account, err = client.Accounts.Read(ctx, defaultAccountID)
require.NoError(t, err)
for i, ip := range account.AllowedIPs {
assert.Equal(t, (*options.AllowedIPs)[i], ip)
}
})

t.Run("invalid allowed ips", func(t *testing.T) {
options := AccountUpdateOptions{
AllowedIPs: &[]string{"127.0.00"},
}
account, err := client.Accounts.Update(ctx, defaultAccountID, options)
assert.Nil(t, account)
assert.EqualError(t, err, "Invalid Attribute\n\nvalue is not a valid IPv4 network")
})

t.Run("invalid allowed ips ipv6", func(t *testing.T) {
options := AccountUpdateOptions{
AllowedIPs: &[]string{"FE80:CD00:0000:0CDE:1257:0000:211E:729C"},
}
account, err := client.Accounts.Update(ctx, defaultAccountID, options)
assert.Nil(t, account)
assert.EqualError(t, err, "Invalid Attribute\n\nvalue is not a valid IPv4 network")
})

t.Run("reset allowed ips", func(t *testing.T) {
options := AccountUpdateOptions{
AllowedIPs: &[]string{},
}
account, err := client.Accounts.Update(ctx, defaultAccountID, options)
require.NoError(t, err)
assert.Equal(t, []string{}, account.AllowedIPs)
})
}
1 change: 1 addition & 0 deletions helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
)

const defaultAccountID = "acc-svrcncgh453bi8g"
const defaultAccountName = "mainiacp"
const defaultModuleID = "mod-svsmkkjo8sju4o0"
const badIdentifier = "! / nope"
const policyGroupVcsRepoID = "Scalr/tf-revizor-fixtures"
Expand Down
2 changes: 1 addition & 1 deletion policy_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (s *policyGroups) Read(ctx context.Context, policyGroupID string) (*PolicyG
options := struct {
Include string `url:"include"`
}{
Include: "policies,environments,workspaces",
Include: "policies",
}
u := fmt.Sprintf("policy-groups/%s", url.QueryEscape(policyGroupID))
req, err := s.client.newRequest("GET", u, options)
Expand Down
2 changes: 2 additions & 0 deletions scalr.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ type Client struct {
retryLogHook RetryLogHook
retryServerErrors bool

Accounts Accounts
AccessPolicies AccessPolicies
AccessTokens AccessTokens
AccountUsers AccountUsers
Expand Down Expand Up @@ -204,6 +205,7 @@ func NewClient(cfg *Config) (*Client, error) {
}

// Create the services.
client.Accounts = &accounts{client: client}
client.AccessPolicies = &accessPolicies{client: client}
client.AccessTokens = &accessTokens{client: client}
client.AccountUsers = &accountUsers{client: client}
Expand Down

0 comments on commit 49f0210

Please sign in to comment.