Skip to content

Commit

Permalink
Merge branch 'develop' into feature/SCALRCORE-17523
Browse files Browse the repository at this point in the history
Conflicts:
	helper_test.go
	scalr.go
  • Loading branch information
petroprotsakh committed Nov 2, 2021
2 parents 09b7155 + 4b0cd0a commit 1f0dd90
Show file tree
Hide file tree
Showing 14 changed files with 1,076 additions and 11 deletions.
3 changes: 0 additions & 3 deletions access_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import (
"github.com/stretchr/testify/require"
)

const defaultUserID = "user-suh84u6vuvidtbg"
const defaultTeamID = "team-t67mjto75maj8p0"

func TestAccessPoliciesList(t *testing.T) {
client := testClient(t)
ctx := context.Background()
Expand Down
3 changes: 2 additions & 1 deletion account.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ package scalr

// Account represents a Scalr IACP account.
type Account struct {
ID string `jsonapi:"primary,accounts"`
ID string `jsonapi:"primary,accounts"`
Name string `jsonapi:"attr,name"`
}
83 changes: 83 additions & 0 deletions account_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package scalr

import (
"context"
"errors"
)

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

// AccountUsers describes all the account user related methods that the
// Scalr IACP API supports.
type AccountUsers interface {
List(ctx context.Context, options AccountUserListOptions) (*AccountUserList, error)
}

// accountUsers implements AccountUsers.
type accountUsers struct {
client *Client
}

// AccountUserStatus represents a status of account user relation.
type AccountUserStatus string

// List of available account user statuses.
const (
AccountUserStatusActive AccountUserStatus = "Active"
AccountUserStatusInactive AccountUserStatus = "Inactive"
AccountUserStatusPending AccountUserStatus = "Pending"
)

// AccountUserListOptions represents the options for listing account users.
type AccountUserListOptions struct {
Account *string `url:"filter[account],omitempty"`
User *string `url:"filter[user],omitempty"`
Query *string `url:"query,omitempty"`
Sort *string `url:"sort,omitempty"`
Include *string `url:"include,omitempty"`
}

func (o AccountUserListOptions) validate() error {
if !(validString(o.Account) || validString(o.User)) {
return errors.New("either filter[account] or filter[user] is required")
}
return nil
}

// AccountUserList represents a list of account users.
type AccountUserList struct {
*Pagination
Items []*AccountUser
}

// AccountUser represents a Scalr account user.
type AccountUser struct {
ID string `jsonapi:"primary,account-users"`
Status AccountUserStatus `jsonapi:"attr,status"`

// Relations
Account *Account `jsonapi:"relation,account"`
User *User `jsonapi:"relation,user"`
Teams []*Team `jsonapi:"relation,teams"`
}

// List all the account users.
func (s *accountUsers) List(ctx context.Context, options AccountUserListOptions) (*AccountUserList, error) {
if err := options.validate(); err != nil {
return nil, err
}

req, err := s.client.newRequest("GET", "account-users", &options)
if err != nil {
return nil, err
}

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

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

import (
"context"
"testing"

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

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

t.Run("with empty options", func(t *testing.T) {
_, err := client.AccountUsers.List(ctx, AccountUserListOptions{})
require.Error(t, err)
assert.EqualError(t, err, "either filter[account] or filter[user] is required")
})

t.Run("with account option", func(t *testing.T) {
aul, err := client.AccountUsers.List(ctx, AccountUserListOptions{
Account: String(defaultAccountID),
})
require.NoError(t, err)

uIDs := make([]string, len(aul.Items))
for _, au := range aul.Items {
uIDs = append(uIDs, au.User.ID)
}
assert.Equal(t, 1, aul.CurrentPage)
assert.True(t, aul.TotalCount >= 1)
assert.Contains(t, uIDs, defaultUserID)
})

t.Run("with user option", func(t *testing.T) {
aul, err := client.AccountUsers.List(ctx, AccountUserListOptions{
User: String(defaultUserID),
})
require.NoError(t, err)

aIDs := make([]string, len(aul.Items))
for _, au := range aul.Items {
aIDs = append(aIDs, au.Account.ID)
}
assert.Equal(t, 1, aul.CurrentPage)
assert.True(t, aul.TotalCount >= 1)
assert.Contains(t, aIDs, defaultAccountID)
})

t.Run("without a valid account", func(t *testing.T) {
aul, err := client.AccountUsers.List(ctx, AccountUserListOptions{
Account: String(badIdentifier),
})
assert.NoError(t, err)
assert.Len(t, aul.Items, 0)
})

t.Run("without a valid user", func(t *testing.T) {
aul, err := client.AccountUsers.List(ctx, AccountUserListOptions{
User: String(badIdentifier),
})
assert.NoError(t, err)
assert.Len(t, aul.Items, 0)
})
}
73 changes: 73 additions & 0 deletions examples/account-users/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package main

import (
"context"
"log"
"strings"

scalr "github.com/scalr/go-scalr"
)

func main() {
accID := "acc-svrcncgh453bi8g"
userID := "user-suh84u6vhn64l0o"

config := scalr.DefaultConfig()
client, err := scalr.NewClient(config)
if err != nil {
log.Fatal(err)
}

// Create a context
ctx := context.Background()

// List users that have access to an account
aul, err := client.AccountUsers.List(ctx, scalr.AccountUserListOptions{
Account: scalr.String(accID),
Include: scalr.String("user"),
})
if err != nil {
log.Fatal(err)
}

if aul.TotalCount == 0 {
log.Printf("No users found in account %s", accID)
} else {
var active []string
for _, usr := range aul.Items {
if usr.Status == scalr.AccountUserStatusActive {
active = append(active, usr.User.Username)
}
}
if len(active) == 0 {
log.Printf("No active relations found for account %s", accID)
} else {
log.Printf("Active users in account %s: %s", accID, strings.Join(active, ", "))
}
}

// List accounts the user has access to
aul, err = client.AccountUsers.List(ctx, scalr.AccountUserListOptions{
User: scalr.String(userID),
Include: scalr.String("account"),
})
if err != nil {
log.Fatal(err)
}

if aul.TotalCount == 0 {
log.Printf("No accounts found for user %s", userID)
} else {
var active []string
for _, usr := range aul.Items {
if usr.Status == scalr.AccountUserStatusActive {
active = append(active, usr.Account.Name)
}
}
if len(active) == 0 {
log.Printf("No active accounts found for user %s", userID)
} else {
log.Printf("Active accounts for user %s: %s", userID, strings.Join(active, ", "))
}
}
}
65 changes: 65 additions & 0 deletions examples/teams/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package main

import (
"context"
"log"
"strings"

scalr "github.com/scalr/go-scalr"
)

func main() {
accID := "acc-svrcncgh453bi8g"

config := scalr.DefaultConfig()
client, err := scalr.NewClient(config)
if err != nil {
log.Fatal(err)
}

// Create a context
ctx := context.Background()

// List all teams in account
tl, err := client.Teams.List(ctx, scalr.TeamListOptions{
Account: scalr.String(accID),
})
if err != nil {
log.Fatal(err)
}

if tl.TotalCount == 0 {
log.Printf("No teams found in account %s", accID)
} else {
var teams []string
for _, t := range tl.Items {
teams = append(teams, t.Name)
}
log.Printf("Teams in account %s: %s", accID, strings.Join(teams, ", "))
}

// Create a new team
t, err := client.Teams.Create(ctx, scalr.TeamCreateOptions{
Name: scalr.String("dev"),
Description: scalr.String("Developers"),
Account: &scalr.Account{ID: accID},
Users: []*scalr.User{
{ID: "user-suh84u6vuvidtbg"},
{ID: "user-suh84u72gfrbd30"},
},
})
if err != nil {
log.Fatal(err)
}

// Update a team
t, err = client.Teams.Update(ctx, t.ID, scalr.TeamUpdateOptions{
Name: scalr.String("dev-new"),
Users: []*scalr.User{
{ID: "user-svrcmmpcrkmit1g"},
},
})
if err != nil {
log.Fatal(err)
}
}
29 changes: 29 additions & 0 deletions examples/users/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"context"
"log"

scalr "github.com/scalr/go-scalr"
)

func main() {
config := scalr.DefaultConfig()
client, err := scalr.NewClient(config)
if err != nil {
log.Fatal(err)
}

// Create a context
ctx := context.Background()

// List all users
ul, err := client.Users.List(ctx, scalr.UserListOptions{
ListOptions: scalr.ListOptions{PageSize: 99},
})
if err != nil {
log.Fatal(err)
}

log.Printf("Obtained %d users", ul.TotalCount)
}
23 changes: 23 additions & 0 deletions helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,29 @@ func createVcsProvider(t *testing.T, client *Client, envs []*Environment) (*VcsP
}
}

func createTeam(t *testing.T, client *Client, users []*User) (*Team, func()) {
ctx := context.Background()
team, err := client.Teams.Create(
ctx,
TeamCreateOptions{
Name: String("tst-" + randomString(t)),
Account: &Account{ID: defaultAccountID},
Users: users,
},
)
if err != nil {
t.Fatal(err)
}

return team, func() {
if err := client.Teams.Delete(ctx, team.ID); err != nil {
t.Errorf("Error deleting team! WARNING: Dangling resources\n"+
"may exist! The full error is shown below.\n\n"+
"VCS Providder: %s\nError: %s", team.ID, err)
}
}
}

func createPolicyGroup(t *testing.T, client *Client, vcsProvider *VcsProvider) (*PolicyGroup, func()) {
var vcsCleanup func()

Expand Down
6 changes: 6 additions & 0 deletions identity_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package scalr

// IdentityProvider represents a Scalr identity provider.
type IdentityProvider struct {
ID string `jsonapi:"primary,identity-providers"`
}
Loading

0 comments on commit 1f0dd90

Please sign in to comment.