Shuffle things around out of new modules
This commit is contained in:
1 parent
70a8051974
commit
5cbfcf8eb6
20 files changed
+2
-29
No files matched your search
@@ -1,193 +0,0 @@
|
||||
package accounts_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/accounts"
|
||||
"github.com/hashicorp/boundary/api/authmethods"
|
||||
"github.com/hashicorp/boundary/internal/auth/password"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
os.Setenv("BOUNDARY_LOG_URLS", "1")
|
||||
os.Setenv("BOUNDARY_DEV_SKIP_AUTHZ", "1")
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
require.NotNil(client)
|
||||
token := tc.Token()
|
||||
require.NotNil(token)
|
||||
client.SetToken(token.Token)
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
amClient := authmethods.NewClient(client)
|
||||
amResult, err := amClient.Create(tc.Context(), "password", org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(amResult)
|
||||
am := amResult.Item
|
||||
|
||||
accountClient := accounts.NewClient(client)
|
||||
|
||||
lr, err := accountClient.List(tc.Context(), am.Id)
|
||||
require.NoError(err)
|
||||
expected := lr.Items
|
||||
assert.Len(expected, 0)
|
||||
|
||||
expected = append(expected, &accounts.Account{Attributes: map[string]interface{}{"login_name": "loginname0"}})
|
||||
|
||||
cr, err := accountClient.Create(tc.Context(), am.Id, accounts.WithPasswordAccountLoginName(expected[0].Attributes["login_name"].(string)))
|
||||
require.NoError(err)
|
||||
expected[0] = cr.Item
|
||||
|
||||
ulResult, err := accountClient.List(tc.Context(), am.Id)
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected[:1]), comparableSlice(ulResult.Items))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
newAcctResult, err := accountClient.Create(tc.Context(), am.Id, accounts.WithPasswordAccountLoginName(fmt.Sprintf("loginname%d", i)))
|
||||
require.NoError(err)
|
||||
expected = append(expected, newAcctResult.Item)
|
||||
}
|
||||
ulResult, err = accountClient.List(tc.Context(), am.Id)
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(ulResult.Items))
|
||||
}
|
||||
|
||||
func comparableSlice(in []*accounts.Account) []accounts.Account {
|
||||
var filtered []accounts.Account
|
||||
for _, i := range in {
|
||||
p := accounts.Account{
|
||||
Id: i.Id,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
Attributes: i.Attributes,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
amId := token.AuthMethodId
|
||||
accountClient := accounts.NewClient(client)
|
||||
|
||||
checkAccount := func(step string, u *accounts.Account, err error, wantedName string, wantedVersion uint32) {
|
||||
assert.NoError(err, step)
|
||||
require.NotNil(u, "returned no resource", step)
|
||||
gotName := ""
|
||||
if u.Name != "" {
|
||||
gotName = u.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.EqualValues(wantedVersion, u.Version)
|
||||
}
|
||||
|
||||
u, err := accountClient.Create(tc.Context(), amId, accounts.WithName("foo"), accounts.WithPasswordAccountLoginName("loginname"))
|
||||
checkAccount("create", u.Item, err, "foo", 1)
|
||||
|
||||
u, err = accountClient.Read(tc.Context(), u.Item.Id)
|
||||
checkAccount("read", u.Item, err, "foo", 1)
|
||||
|
||||
u, err = accountClient.Update(tc.Context(), u.Item.Id, u.Item.Version, accounts.WithName("bar"))
|
||||
checkAccount("update", u.Item, err, "bar", 2)
|
||||
|
||||
u, err = accountClient.Update(tc.Context(), u.Item.Id, u.Item.Version, accounts.DefaultName())
|
||||
checkAccount("update", u.Item, err, "", 3)
|
||||
|
||||
_, err = accountClient.Delete(tc.Context(), u.Item.Id)
|
||||
require.NoError(err)
|
||||
}
|
||||
|
||||
func TestCustomMethods(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
amId := token.AuthMethodId
|
||||
|
||||
accountClient := accounts.NewClient(client)
|
||||
|
||||
al, err := accountClient.List(tc.Context(), amId)
|
||||
require.NoError(err)
|
||||
require.Len(al.Items, 1)
|
||||
|
||||
acct := al.Items[0]
|
||||
|
||||
setAcct, err := accountClient.SetPassword(tc.Context(), acct.Id, "setpassword", acct.Version)
|
||||
require.NoError(err)
|
||||
require.NotNil(setAcct)
|
||||
assert.Equal(acct.Version+1, setAcct.Item.Version)
|
||||
|
||||
changeAcct, err := accountClient.ChangePassword(tc.Context(), acct.Id, "setpassword", "changepassword", setAcct.Item.Version)
|
||||
require.NoError(err)
|
||||
require.NotNil(changeAcct)
|
||||
assert.Equal(setAcct.Item.Version+1, changeAcct.Item.Version)
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
amId := token.AuthMethodId
|
||||
accountClient := accounts.NewClient(client)
|
||||
|
||||
u, err := accountClient.Create(tc.Context(), amId, accounts.WithPasswordAccountLoginName("first"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(u)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = accountClient.Update(tc.Context(), u.Item.Id, 73, accounts.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
// Create another resource with the same name.
|
||||
_, err = accountClient.Create(tc.Context(), amId, accounts.WithPasswordAccountLoginName("first"))
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
|
||||
_, err = accountClient.Read(tc.Context(), password.AccountPrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = accountClient.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
|
||||
_, err = accountClient.Update(tc.Context(), u.Item.Id, u.Item.Version)
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package authmethods_test
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/authmethods"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAuthenticate(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
methods := authmethods.NewClient(client)
|
||||
|
||||
tok, err := methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "passpass"})
|
||||
require.NoError(err)
|
||||
assert.NotNil(tok)
|
||||
|
||||
_, err = methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "wrong"})
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValuesf(http.StatusUnauthorized, apiErr.Status, "Expected unauthorized, got %q", apiErr.Message)
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package authtokens_test
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/accounts"
|
||||
"github.com/hashicorp/boundary/api/authmethods"
|
||||
"github.com/hashicorp/boundary/api/authtokens"
|
||||
"github.com/hashicorp/boundary/api/roles"
|
||||
"github.com/hashicorp/boundary/internal/authtoken"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
defer tc.Shutdown()
|
||||
|
||||
token := tc.Token()
|
||||
client := tc.Client()
|
||||
client.SetToken(token.Token)
|
||||
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
amClient := authmethods.NewClient(client)
|
||||
amResult, err := amClient.Create(tc.Context(), "password", org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(amResult)
|
||||
amId = amResult.Item.Id
|
||||
|
||||
rolesClient := roles.NewClient(client)
|
||||
role, err := rolesClient.Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(role)
|
||||
role, err = rolesClient.AddPrincipals(tc.Context(), role.Item.Id, 0, []string{"u_anon"}, roles.WithAutomaticVersioning(true))
|
||||
require.NoError(err)
|
||||
require.NotNil(role)
|
||||
role, err = rolesClient.AddGrants(tc.Context(), role.Item.Id, 0, []string{"id=*;type=auth-method;actions=authenticate"}, roles.WithAutomaticVersioning(true))
|
||||
require.NoError(err)
|
||||
require.NotNil(role)
|
||||
|
||||
acctClient := accounts.NewClient(client)
|
||||
acct, err := acctClient.Create(tc.Context(), amId, accounts.WithPasswordAccountLoginName("user"), accounts.WithPasswordAccountPassword("passpass"))
|
||||
require.NoError(err)
|
||||
require.NotNil(acct)
|
||||
|
||||
tokens := authtokens.NewClient(client)
|
||||
|
||||
atl, err := tokens.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Empty(atl.Items)
|
||||
|
||||
var expected []*authtokens.AuthToken
|
||||
methods := authmethods.NewClient(client)
|
||||
|
||||
at, err := methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "passpass"})
|
||||
require.NoError(err)
|
||||
expected = append(expected, at.Item)
|
||||
|
||||
atl, err = tokens.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(atl.Items))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
at, err = methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "passpass"})
|
||||
require.NoError(err)
|
||||
expected = append(expected, at.Item)
|
||||
}
|
||||
atl, err = tokens.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(atl.Items))
|
||||
}
|
||||
|
||||
func comparableResource(i *authtokens.AuthToken) authtokens.AuthToken {
|
||||
return authtokens.AuthToken{
|
||||
Id: i.Id,
|
||||
UserId: i.UserId,
|
||||
AuthMethodId: i.AuthMethodId,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
ApproximateLastUsedTime: i.ApproximateLastUsedTime,
|
||||
ExpirationTime: i.ExpirationTime,
|
||||
}
|
||||
}
|
||||
|
||||
func comparableSlice(in []*authtokens.AuthToken) []authtokens.AuthToken {
|
||||
var filtered []authtokens.AuthToken
|
||||
for _, i := range in {
|
||||
filtered = append(filtered, comparableResource(i))
|
||||
}
|
||||
sort.Slice(filtered, func(i, j int) bool {
|
||||
return filtered[i].Id < filtered[j].Id
|
||||
})
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
tokens := authtokens.NewClient(client)
|
||||
methods := authmethods.NewClient(client)
|
||||
|
||||
want, err := methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "passpass"})
|
||||
require.NoError(err)
|
||||
|
||||
at, err := tokens.Read(tc.Context(), want.Item.Id)
|
||||
require.NoError(err)
|
||||
assert.EqualValues(comparableResource(want.Item), comparableResource(at.Item))
|
||||
|
||||
_, err = tokens.Delete(tc.Context(), at.Item.Id)
|
||||
require.NoError(err)
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
tokens := authtokens.NewClient(client)
|
||||
|
||||
_, err := tokens.Read(tc.Context(), authtoken.AuthTokenPrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = tokens.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestConfigSetAddress(t *testing.T) {
|
||||
type test struct {
|
||||
name string
|
||||
input string
|
||||
address string
|
||||
err string
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
"bare",
|
||||
"http://127.0.0.1:9200",
|
||||
"http://127.0.0.1:9200",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"bare with version",
|
||||
"http://127.0.0.1:9200/v1",
|
||||
"http://127.0.0.1:9200",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"bare with version and trailing slash",
|
||||
"http://127.0.0.1:9200/v1/",
|
||||
"http://127.0.0.1:9200",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"valid top level scope",
|
||||
"http://127.0.0.1:9200/v1/scopes",
|
||||
"http://127.0.0.1:9200",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"valid scope",
|
||||
"http://127.0.0.1:9200/v1/scopes/scopeid",
|
||||
"http://127.0.0.1:9200",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"longer path project",
|
||||
"http://127.0.0.1:9200/v1/auth-methods",
|
||||
"http://127.0.0.1:9200",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"valid project",
|
||||
"http://127.0.0.1:9200/my-install",
|
||||
"http://127.0.0.1:9200/my-install",
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, v := range tests {
|
||||
t.Run(v.name, func(t *testing.T) {
|
||||
var c Config
|
||||
err := c.setAddr(v.input)
|
||||
if err != nil {
|
||||
assert.Equal(t, v.err, err.Error())
|
||||
}
|
||||
assert.Equal(t, v.address, c.Addr)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
package groups_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/groups"
|
||||
"github.com/hashicorp/boundary/api/users"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
grps := groups.NewClient(client)
|
||||
pl, err := grps.List(tc.Context(), tt.scopeId)
|
||||
assert.NoError(err)
|
||||
assert.Empty(pl.Items)
|
||||
|
||||
expected := make([]*groups.Group, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
createResult, err := grps.Create(tc.Context(), tt.scopeId, groups.WithName(fmt.Sprint(i)))
|
||||
require.NoError(err)
|
||||
expected[i] = createResult.Item
|
||||
}
|
||||
pl, err = grps.List(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
require.NotNil(pl)
|
||||
require.Len(pl.Items, 10)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(pl.Items))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func comparableSlice(in []*groups.Group) []groups.Group {
|
||||
var filtered []groups.Group
|
||||
for _, i := range in {
|
||||
p := groups.Group{
|
||||
Id: i.Id,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
checkGroup := func(step string, g *groups.Group, err error, wantedName string, wantedVersion uint32, expectedUserIds []string) {
|
||||
require.NoError(err, step)
|
||||
assert.NotNil(g, "returned no resource", step)
|
||||
gotName := ""
|
||||
if g.Name != "" {
|
||||
gotName = g.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.EqualValues(wantedVersion, g.Version)
|
||||
assert.Equal(len(expectedUserIds), len(g.MemberIds))
|
||||
if len(expectedUserIds) > 0 {
|
||||
assert.EqualValues(expectedUserIds, g.MemberIds)
|
||||
}
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
user1, err := users.NewClient(client).Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
|
||||
user2, err := users.NewClient(client).Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
groupsClient := groups.NewClient(client)
|
||||
g, err := groupsClient.Create(tc.Context(), tt.scopeId, groups.WithName("foo"))
|
||||
checkGroup("create", g.Item, err, "foo", 1, nil)
|
||||
|
||||
g, err = groupsClient.Read(tc.Context(), g.Item.Id)
|
||||
checkGroup("read", g.Item, err, "foo", 1, nil)
|
||||
|
||||
g, err = groupsClient.Update(tc.Context(), g.Item.Id, g.Item.Version, groups.WithName("bar"))
|
||||
checkGroup("update", g.Item, err, "bar", 2, nil)
|
||||
|
||||
g, err = groupsClient.Update(tc.Context(), g.Item.Id, g.Item.Version, groups.DefaultName())
|
||||
checkGroup("update", g.Item, err, "", 3, nil)
|
||||
|
||||
g, err = groupsClient.AddMembers(tc.Context(), g.Item.Id, g.Item.Version, []string{user1.Item.Id})
|
||||
checkGroup("update", g.Item, err, "", 4, []string{user1.Item.Id})
|
||||
|
||||
g, err = groupsClient.SetMembers(tc.Context(), g.Item.Id, g.Item.Version, []string{user2.Item.Id})
|
||||
checkGroup("update", g.Item, err, "", 5, []string{user2.Item.Id})
|
||||
|
||||
g, err = groupsClient.RemoveMembers(tc.Context(), g.Item.Id, g.Item.Version, []string{user2.Item.Id})
|
||||
checkGroup("update", g.Item, err, "", 6, nil)
|
||||
|
||||
_, err = groupsClient.Delete(tc.Context(), g.Item.Id)
|
||||
require.NoError(err)
|
||||
|
||||
_, err = groupsClient.Delete(tc.Context(), g.Item.Id)
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
groupClient := groups.NewClient(client)
|
||||
|
||||
g, err := groupClient.Create(tc.Context(), tt.scopeId, groups.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(g)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = groupClient.Update(tc.Context(), g.Item.Id, 73, groups.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
// Create another resource with the same name.
|
||||
_, err = groupClient.Create(tc.Context(), tt.scopeId, groups.WithName("first"))
|
||||
require.Error(err)
|
||||
|
||||
_, err = groupClient.Read(tc.Context(), iam.GroupPrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = groupClient.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
|
||||
_, err = groupClient.Update(tc.Context(), g.Item.Id, g.Item.Version)
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package hostcatalogs_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/hostcatalogs"
|
||||
"github.com/hashicorp/boundary/internal/host/static"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
catalogClient := hostcatalogs.NewClient(client)
|
||||
|
||||
ul, err := catalogClient.List(tc.Context(), proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Empty(ul.Items)
|
||||
|
||||
var expected []*hostcatalogs.HostCatalog
|
||||
for i := 0; i < 10; i++ {
|
||||
expected = append(expected, &hostcatalogs.HostCatalog{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
cr, err := catalogClient.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName(expected[0].Name))
|
||||
require.NoError(err)
|
||||
expected[0] = cr.Item
|
||||
|
||||
ul, err = catalogClient.List(tc.Context(), proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableCatalogSlice(expected[:1]), comparableCatalogSlice(ul.Items))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
cr, err = catalogClient.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName(expected[i].Name))
|
||||
require.NoError(err)
|
||||
expected[i] = cr.Item
|
||||
}
|
||||
ul, err = catalogClient.List(tc.Context(), proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableCatalogSlice(expected), comparableCatalogSlice(ul.Items))
|
||||
}
|
||||
|
||||
func comparableCatalogSlice(in []*hostcatalogs.HostCatalog) []hostcatalogs.HostCatalog {
|
||||
var filtered []hostcatalogs.HostCatalog
|
||||
for _, i := range in {
|
||||
p := hostcatalogs.HostCatalog{
|
||||
Id: i.Id,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
checkCatalog := func(step string, hc *hostcatalogs.HostCatalog, err error, wantedName string, wantVersion uint32) {
|
||||
require.NoError(err, step)
|
||||
assert.NotNil(hc, "returned no resource", step)
|
||||
gotName := ""
|
||||
if hc.Name != "" {
|
||||
gotName = hc.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.Equal(wantVersion, hc.Version)
|
||||
}
|
||||
|
||||
hcClient := hostcatalogs.NewClient(client)
|
||||
|
||||
hc, err := hcClient.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName("foo"))
|
||||
checkCatalog("create", hc.Item, err, "foo", 1)
|
||||
|
||||
hc, err = hcClient.Read(tc.Context(), hc.Item.Id)
|
||||
checkCatalog("read", hc.Item, err, "foo", 1)
|
||||
|
||||
hc, err = hcClient.Update(tc.Context(), hc.Item.Id, hc.Item.Version, hostcatalogs.WithName("bar"))
|
||||
checkCatalog("update", hc.Item, err, "bar", 2)
|
||||
|
||||
hc, err = hcClient.Update(tc.Context(), hc.Item.Id, hc.Item.Version, hostcatalogs.DefaultName())
|
||||
checkCatalog("update", hc.Item, err, "", 3)
|
||||
|
||||
_, err = hcClient.Delete(tc.Context(), hc.Item.Id)
|
||||
assert.NoError(err)
|
||||
|
||||
_, err = hcClient.Delete(tc.Context(), hc.Item.Id)
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
pc := hostcatalogs.NewClient(client)
|
||||
|
||||
hc, err := pc.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName("foo"))
|
||||
require.NoError(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.NotNil(hc)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = pc.Update(tc.Context(), hc.Item.Id, 73, hostcatalogs.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = pc.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName("foo"))
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
_, err = pc.Read(tc.Context(), static.HostCatalogPrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = pc.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
package hosts_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/hostcatalogs"
|
||||
"github.com/hashicorp/boundary/api/hosts"
|
||||
"github.com/hashicorp/boundary/internal/host/static"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(hc)
|
||||
|
||||
hClient := hosts.NewClient(client)
|
||||
|
||||
ul, err := hClient.List(tc.Context(), hc.Item.Id)
|
||||
assert.NoError(err)
|
||||
assert.Empty(ul.Items)
|
||||
|
||||
var expected []*hosts.Host
|
||||
for i := 0; i < 10; i++ {
|
||||
expected = append(expected, &hosts.Host{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
hcr, err := hClient.Create(tc.Context(), hc.Item.Id, hosts.WithName(expected[0].Name), hosts.WithStaticHostAddress("someaddress"))
|
||||
assert.NoError(err)
|
||||
expected[0] = hcr.Item
|
||||
|
||||
ul, err = hClient.List(tc.Context(), hc.Item.Id)
|
||||
assert.NoError(err)
|
||||
assert.ElementsMatch(comparableHostSlice(expected[:1]), comparableHostSlice(ul.Items))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
hcr, err = hClient.Create(tc.Context(), hc.Item.Id, hosts.WithName(expected[i].Name), hosts.WithStaticHostAddress("someaddress"))
|
||||
assert.NoError(err)
|
||||
expected[i] = hcr.Item
|
||||
}
|
||||
ul, err = hClient.List(tc.Context(), hc.Item.Id)
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableHostSlice(expected), comparableHostSlice(ul.Items))
|
||||
}
|
||||
|
||||
func comparableHostSlice(in []*hosts.Host) []hosts.Host {
|
||||
var filtered []hosts.Host
|
||||
for _, i := range in {
|
||||
p := hosts.Host{
|
||||
Id: i.Id,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(hc)
|
||||
|
||||
checkHost := func(step string, h *hosts.Host, err error, wantedName string, wantVersion uint32) {
|
||||
require.NoError(err, step)
|
||||
assert.NotNil(h, "returned no resource", step)
|
||||
gotName := ""
|
||||
if h.Name != "" {
|
||||
gotName = h.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.Equal(wantVersion, h.Version)
|
||||
}
|
||||
|
||||
hClient := hosts.NewClient(client)
|
||||
|
||||
h, err := hClient.Create(tc.Context(), hc.Item.Id, hosts.WithName("foo"), hosts.WithStaticHostAddress("someaddress"))
|
||||
checkHost("create", h.Item, err, "foo", 1)
|
||||
|
||||
h, err = hClient.Read(tc.Context(), h.Item.Id)
|
||||
checkHost("read", h.Item, err, "foo", 1)
|
||||
|
||||
h, err = hClient.Update(tc.Context(), h.Item.Id, h.Item.Version, hosts.WithName("bar"))
|
||||
checkHost("update", h.Item, err, "bar", 2)
|
||||
|
||||
h, err = hClient.Update(tc.Context(), h.Item.Id, h.Item.Version, hosts.DefaultName())
|
||||
checkHost("update", h.Item, err, "", 3)
|
||||
|
||||
_, err = hClient.Delete(tc.Context(), h.Item.Id)
|
||||
assert.NoError(err)
|
||||
|
||||
_, err = hClient.Delete(tc.Context(), h.Item.Id)
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(hc)
|
||||
|
||||
hClient := hosts.NewClient(client)
|
||||
|
||||
h, err := hClient.Create(tc.Context(), hc.Item.Id, hosts.WithName("foo"), hosts.WithStaticHostAddress("someaddress"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(h)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = hClient.Update(tc.Context(), h.Item.Id, 73, hosts.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = hClient.Create(tc.Context(), hc.Item.Id, hosts.WithName("foo"), hosts.WithStaticHostAddress("someaddress"))
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
_, err = hClient.Read(tc.Context(), static.HostPrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = hClient.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
package hostsets_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/hostcatalogs"
|
||||
"github.com/hashicorp/boundary/api/hosts"
|
||||
"github.com/hashicorp/boundary/api/hostsets"
|
||||
"github.com/hashicorp/boundary/internal/host/static"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCustom(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
|
||||
hClient := hosts.NewClient(client)
|
||||
h1, err := hClient.Create(tc.Context(), hc.Item.Id, hosts.WithStaticHostAddress("someaddress"))
|
||||
require.NoError(err)
|
||||
h2, err := hClient.Create(tc.Context(), hc.Item.Id, hosts.WithStaticHostAddress("someaddress"))
|
||||
require.NoError(err)
|
||||
|
||||
hSetClient := hostsets.NewClient(client)
|
||||
hSet, err := hSetClient.Create(tc.Context(), hc.Item.Id)
|
||||
require.NoError(err)
|
||||
|
||||
hSet, err = hSetClient.AddHosts(tc.Context(), hSet.Item.Id, hSet.Item.Version, []string{h1.Item.Id, h2.Item.Id})
|
||||
require.NoError(err)
|
||||
assert.Contains(hSet.Item.HostIds, h1.Item.Id, h2.Item.Id)
|
||||
|
||||
hSet, err = hSetClient.SetHosts(tc.Context(), hSet.Item.Id, hSet.Item.Version, []string{h1.Item.Id})
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch([]string{h1.Item.Id}, hSet.Item.HostIds)
|
||||
|
||||
hSet, err = hSetClient.RemoveHosts(tc.Context(), hSet.Item.Id, hSet.Item.Version, []string{h1.Item.Id})
|
||||
require.NoError(err)
|
||||
assert.Empty(hSet.Item.HostIds)
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(hc)
|
||||
|
||||
hClient := hostsets.NewClient(client)
|
||||
|
||||
ul, err := hClient.List(tc.Context(), hc.Item.Id)
|
||||
require.NoError(err)
|
||||
assert.Empty(ul.Items)
|
||||
|
||||
var expected []*hostsets.HostSet
|
||||
for i := 0; i < 10; i++ {
|
||||
expected = append(expected, &hostsets.HostSet{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
hcr, err := hClient.Create(tc.Context(), hc.Item.Id, hostsets.WithName(expected[0].Name))
|
||||
require.NoError(err)
|
||||
expected[0] = hcr.Item
|
||||
|
||||
ul, err = hClient.List(tc.Context(), hc.Item.Id)
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSetSlice(expected[:1]), comparableSetSlice(ul.Items))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
hcr, err = hClient.Create(tc.Context(), hc.Item.Id, hostsets.WithName(expected[i].Name))
|
||||
require.NoError(err)
|
||||
expected[i] = hcr.Item
|
||||
}
|
||||
ul, err = hClient.List(tc.Context(), hc.Item.Id)
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSetSlice(expected), comparableSetSlice(ul.Items))
|
||||
}
|
||||
|
||||
func comparableSetSlice(in []*hostsets.HostSet) []hostsets.HostSet {
|
||||
var filtered []hostsets.HostSet
|
||||
for _, i := range in {
|
||||
p := hostsets.HostSet{
|
||||
Id: i.Id,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(hc)
|
||||
|
||||
checkHost := func(t *testing.T, step string, h *hostsets.HostSet, err error, wantedName string, wantVersion uint32) {
|
||||
t.Helper()
|
||||
require.NoError(err, step)
|
||||
assert.NotNil(h, "returned no resource", step)
|
||||
gotName := ""
|
||||
if h.Name != "" {
|
||||
gotName = h.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.Equal(wantVersion, h.Version)
|
||||
}
|
||||
|
||||
hClient := hostsets.NewClient(client)
|
||||
|
||||
h, err := hClient.Create(tc.Context(), hc.Item.Id, hostsets.WithName("foo"))
|
||||
checkHost(t, "create", h.Item, err, "foo", 1)
|
||||
|
||||
h, err = hClient.Read(tc.Context(), h.Item.Id)
|
||||
checkHost(t, "read", h.Item, err, "foo", 1)
|
||||
|
||||
h, err = hClient.Update(tc.Context(), h.Item.Id, h.Item.Version, hostsets.WithName("bar"))
|
||||
checkHost(t, "update", h.Item, err, "bar", 2)
|
||||
|
||||
h, err = hClient.Update(tc.Context(), h.Item.Id, h.Item.Version, hostsets.DefaultName())
|
||||
checkHost(t, "update", h.Item, err, "", 3)
|
||||
|
||||
_, err = hClient.Delete(tc.Context(), h.Item.Id)
|
||||
assert.NoError(err)
|
||||
_, err = hClient.Delete(tc.Context(), h.Item.Id)
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
require.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
}
|
||||
|
||||
// TODO: Get better coverage for expected errors and error formats.
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.NotNil(hc)
|
||||
|
||||
hClient := hostsets.NewClient(client)
|
||||
|
||||
h, err := hClient.Create(tc.Context(), hc.Item.Id, hostsets.WithName("foo"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(h)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = hClient.Update(tc.Context(), h.Item.Id, 73, hostsets.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
h, err = hClient.Create(tc.Context(), hc.Item.Id, hostsets.WithName("foo"))
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.Nil(h)
|
||||
|
||||
_, err = hClient.Read(tc.Context(), static.HostSetPrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = hClient.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
# Determine this makefile's path.
|
||||
# Be sure to place this BEFORE `include` directives, if any.
|
||||
THIS_FILE := $(lastword $(MAKEFILE_LIST))
|
||||
|
||||
export API_GEN_BASEPATH := ${GEN_BASEPATH}/api
|
||||
|
||||
api:
|
||||
go run .
|
||||
goimports -w ${API_GEN_BASEPATH}
|
||||
|
||||
.PHONY: api
|
||||
@@ -1,408 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"text/template"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/accounts"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/authmethods"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/authtokens"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/groups"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/hostcatalogs"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/hosts"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/hostsets"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/roles"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/scopes"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/sessions"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/targets"
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/users"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type structureInfo struct {
|
||||
pkg string
|
||||
name string
|
||||
fields []fieldInfo
|
||||
}
|
||||
|
||||
type fieldInfo struct {
|
||||
Name string
|
||||
ProtoName string
|
||||
FieldType string
|
||||
GenerateSdkOption bool
|
||||
SubtypeName string
|
||||
Query bool
|
||||
SkipDefault bool
|
||||
}
|
||||
|
||||
type structInfo struct {
|
||||
inProto proto.Message
|
||||
outFile string
|
||||
generatedStructure structureInfo
|
||||
templates []*template.Template
|
||||
|
||||
// Subtype name for types implementing an abstract resource type. This is
|
||||
// used as text to insert into With/Default function calls to separate out
|
||||
// implementations of the same abstract type. This way e.g. a WithLoginName
|
||||
// option turns into WithPasswordAccountLoginName which is wordy but
|
||||
// unambiguous. It also switches the behavior of the functions to work on
|
||||
// the attributes map.
|
||||
subtypeName string
|
||||
|
||||
// For non-top-level collections, this can be used to indicate the name of
|
||||
// the argument that should be used
|
||||
parentTypeName string
|
||||
|
||||
// mappings of names of resources and param names for sub slice types, e.g.
|
||||
// role principals and group members
|
||||
sliceSubTypes map[string]string
|
||||
|
||||
// outputOnly indicates that we shouldn't create options for setting members
|
||||
// for this struct
|
||||
outputOnly bool
|
||||
|
||||
// versionEnabled indicates that we should build a Version handler in
|
||||
// update. Some structs are embedded in others and shouldn't have version
|
||||
// fields.
|
||||
versionEnabled bool
|
||||
|
||||
// The parameters passed into the path. These should be non-pluralized resource names.
|
||||
// The templates will convert '-' to '_' and append an _id to them in the SDK param
|
||||
// and append an 's' to it when building the path.
|
||||
// The final value should be the path name of the resource since for single resource
|
||||
// operations all values are used for the function argument.
|
||||
// For collection based operations the last value is ignored for generating function argument.
|
||||
pathArgs []string
|
||||
|
||||
// typeOnCreate indicates that create will be creating a concrete
|
||||
// implementation of an abstract type and thus a type field is necessary
|
||||
typeOnCreate bool
|
||||
|
||||
// extraOptions allows specifying extra options that will be created for a
|
||||
// given type, e.g. arguments only valid for one call or purpose and not
|
||||
// conveyed within the item itself
|
||||
extraOptions []fieldInfo
|
||||
|
||||
// createResponseTypes controls for which structs response types are created
|
||||
createResponseTypes bool
|
||||
|
||||
// fieldFilter is a set of field names that will not result in generated API
|
||||
// fields
|
||||
fieldFilter []string
|
||||
}
|
||||
|
||||
var inputStructs = []*structInfo{
|
||||
{
|
||||
inProto: &api.Error{},
|
||||
outFile: "error.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
{
|
||||
inProto: &api.ErrorDetails{},
|
||||
outFile: "error_details.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
{
|
||||
inProto: &api.FieldError{},
|
||||
outFile: "field_error.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
// Scope related resources
|
||||
{
|
||||
inProto: &scopes.ScopeInfo{},
|
||||
outFile: "scopes/scope_info.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
{
|
||||
inProto: &scopes.Scope{},
|
||||
outFile: "scopes/scope.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"scope"},
|
||||
extraOptions: []fieldInfo{
|
||||
{
|
||||
Name: "SkipAdminRoleCreation",
|
||||
ProtoName: "skip_admin_role_creation",
|
||||
FieldType: "bool",
|
||||
Query: true,
|
||||
},
|
||||
{
|
||||
Name: "SkipDefaultRoleCreation",
|
||||
ProtoName: "skip_default_role_creation",
|
||||
FieldType: "bool",
|
||||
Query: true,
|
||||
},
|
||||
},
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
// User related resources
|
||||
{
|
||||
inProto: &users.Account{},
|
||||
outFile: "users/account.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
{
|
||||
inProto: &users.User{},
|
||||
outFile: "users/user.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
sliceSubTypes: map[string]string{
|
||||
"Accounts": "accountIds",
|
||||
},
|
||||
pathArgs: []string{"user"},
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
// Group related resources
|
||||
{
|
||||
inProto: &groups.Member{},
|
||||
outFile: "groups/member.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
{
|
||||
inProto: &groups.Group{},
|
||||
outFile: "groups/group.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
sliceSubTypes: map[string]string{
|
||||
"Members": "memberIds",
|
||||
},
|
||||
pathArgs: []string{"group"},
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
// Role related resources
|
||||
{
|
||||
inProto: &roles.Grant{},
|
||||
outFile: "roles/grant.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
{
|
||||
inProto: &roles.Principal{},
|
||||
outFile: "roles/principal.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
{
|
||||
inProto: &roles.GrantJson{},
|
||||
outFile: "roles/grant_json.gen.go",
|
||||
outputOnly: true,
|
||||
},
|
||||
{
|
||||
inProto: &roles.Role{},
|
||||
outFile: "roles/role.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
sliceSubTypes: map[string]string{
|
||||
"Principals": "principalIds",
|
||||
"Grants": "grantStrings",
|
||||
},
|
||||
pathArgs: []string{"role"},
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
// Auth Methods related resources
|
||||
{
|
||||
inProto: &authmethods.AuthMethod{},
|
||||
outFile: "authmethods/authmethods.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"auth-method"},
|
||||
typeOnCreate: true,
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
{
|
||||
inProto: &authmethods.PasswordAuthMethodAttributes{},
|
||||
outFile: "authmethods/password_auth_method_attributes.gen.go",
|
||||
subtypeName: "PasswordAuthMethod",
|
||||
},
|
||||
// Accounts
|
||||
{
|
||||
inProto: &accounts.Account{},
|
||||
outFile: "accounts/account.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"account"},
|
||||
parentTypeName: "auth-method",
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
{
|
||||
inProto: &accounts.PasswordAccountAttributes{},
|
||||
outFile: "accounts/password_account_attributes.gen.go",
|
||||
subtypeName: "PasswordAccount",
|
||||
},
|
||||
// Auth Tokens
|
||||
{
|
||||
inProto: &authtokens.AuthToken{},
|
||||
outFile: "authtokens/authtokens.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
readTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"auth-token"},
|
||||
createResponseTypes: true,
|
||||
},
|
||||
// Host related resources
|
||||
{
|
||||
inProto: &hostcatalogs.HostCatalog{},
|
||||
outFile: "hostcatalogs/host_catalog.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"host-catalog"},
|
||||
typeOnCreate: true,
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
{
|
||||
inProto: &hosts.Host{},
|
||||
outFile: "hosts/host.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"host"},
|
||||
parentTypeName: "host-catalog",
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
{
|
||||
inProto: &hosts.StaticHostAttributes{},
|
||||
outFile: "hosts/static_host_attributes.gen.go",
|
||||
subtypeName: "StaticHost",
|
||||
},
|
||||
{
|
||||
inProto: &hostsets.HostSet{},
|
||||
outFile: "hostsets/host_set.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"host-set"},
|
||||
parentTypeName: "host-catalog",
|
||||
sliceSubTypes: map[string]string{
|
||||
"Hosts": "hostIds",
|
||||
},
|
||||
versionEnabled: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
{
|
||||
inProto: &targets.HostSet{},
|
||||
outFile: "targets/host_set.gen.go",
|
||||
},
|
||||
{
|
||||
inProto: &targets.Target{},
|
||||
outFile: "targets/target.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"target"},
|
||||
sliceSubTypes: map[string]string{
|
||||
"HostSets": "hostSetIds",
|
||||
},
|
||||
extraOptions: []fieldInfo{
|
||||
{
|
||||
Name: "HostId",
|
||||
ProtoName: "host_id",
|
||||
FieldType: "string",
|
||||
SkipDefault: true,
|
||||
},
|
||||
},
|
||||
versionEnabled: true,
|
||||
typeOnCreate: true,
|
||||
createResponseTypes: true,
|
||||
},
|
||||
{
|
||||
inProto: &targets.TcpTargetAttributes{},
|
||||
outFile: "targets/tcp_target_attributes.gen.go",
|
||||
subtypeName: "TcpTarget",
|
||||
},
|
||||
{
|
||||
inProto: &sessions.Session{},
|
||||
outFile: "sessions/session.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
readTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"session"},
|
||||
createResponseTypes: true,
|
||||
fieldFilter: []string{"private_key"},
|
||||
},
|
||||
{
|
||||
inProto: &sessions.SessionState{},
|
||||
outFile: "sessions/state.gen.go",
|
||||
},
|
||||
{
|
||||
inProto: &sessions.WorkerInfo{},
|
||||
outFile: "sessions/workers.gen.go",
|
||||
},
|
||||
{
|
||||
inProto: &targets.SessionAuthorization{},
|
||||
outFile: "targets/session_authorization.gen.go",
|
||||
subtypeName: "SessionAuthorization",
|
||||
},
|
||||
{
|
||||
inProto: &targets.WorkerInfo{},
|
||||
outFile: "targets/worker_info.gen.go",
|
||||
subtypeName: "WorkerInfo",
|
||||
},
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
parsePBs()
|
||||
fillTemplates()
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
_struct "github.com/golang/protobuf/ptypes/struct"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/types/descriptorpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/gen/controller/protooptions"
|
||||
"github.com/hashicorp/boundary/sdk/strutil"
|
||||
|
||||
"github.com/iancoleman/strcase"
|
||||
)
|
||||
|
||||
func printDebug(desc protoreflect.MessageDescriptor) {
|
||||
fmt.Printf("Evaluating: %q\n", desc.FullName())
|
||||
fmt.Printf("Name: %q\n", strcase.ToCamel(string(desc.Name())))
|
||||
fmt.Printf("ProtoName: %q\n", desc.Name())
|
||||
fmt.Printf("Double Parent: %q\n", desc.FullName().Parent().Parent().Name())
|
||||
fmt.Printf("Field Descriptors:\n")
|
||||
for i := 0; i < desc.Fields().Len(); i++ {
|
||||
fieldDesc := desc.Fields().Get(i)
|
||||
fmt.Printf(" field %d: %#v\n", i, fieldDesc)
|
||||
fieldDesc.Options()
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func parsePBs() {
|
||||
for _, in := range inputStructs {
|
||||
msg := in.inProto.ProtoReflect()
|
||||
desc := msg.Descriptor()
|
||||
|
||||
//printDebug(desc)
|
||||
|
||||
// Evaluate above, populate below.
|
||||
in.generatedStructure.pkg = packageFromFullName(desc.FullName())
|
||||
in.generatedStructure.name = string(desc.Name())
|
||||
for i := 0; i < desc.Fields().Len(); i++ {
|
||||
fd := desc.Fields().Get(i)
|
||||
if strutil.StrListContains(in.fieldFilter, string(fd.Name())) {
|
||||
continue
|
||||
}
|
||||
fi := fieldInfo{
|
||||
Name: strcase.ToCamel(string(fd.Name())),
|
||||
ProtoName: string(fd.Name()),
|
||||
}
|
||||
// Adjust for slices
|
||||
sliceText := ""
|
||||
if fd.Cardinality() == protoreflect.Repeated {
|
||||
sliceText = "[]"
|
||||
}
|
||||
// Add generate option info
|
||||
opts := fd.Options().(*descriptorpb.FieldOptions)
|
||||
if proto.GetExtension(opts, protooptions.E_GenerateSdkOption).(bool) {
|
||||
fi.GenerateSdkOption = true
|
||||
}
|
||||
switch k := fd.Kind(); k {
|
||||
case protoreflect.MessageKind:
|
||||
ptr, pkg, name := messageKind(fd)
|
||||
if pkg != "" && pkg != in.generatedStructure.pkg {
|
||||
name = fmt.Sprintf("%s.%s", pkg, name)
|
||||
}
|
||||
fi.FieldType = sliceText + ptr + name
|
||||
case protoreflect.BytesKind:
|
||||
fi.FieldType = "[]byte"
|
||||
default:
|
||||
fi.FieldType = sliceText + k.String()
|
||||
}
|
||||
in.generatedStructure.fields = append(in.generatedStructure.fields, fi)
|
||||
}
|
||||
//fmt.Printf("Parsed: %#v\n", in.generatedStructure)
|
||||
}
|
||||
}
|
||||
|
||||
func packageFromFullName(fullName protoreflect.FullName) string {
|
||||
// Example full name: controller.api.resources.groups.v1.Group
|
||||
// Crawling up the parent twice jumps back past v1.Group placing us at "groups".
|
||||
pkgName := fullName.Parent().Parent().Name()
|
||||
if pkgName.IsValid() {
|
||||
return string(pkgName)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var (
|
||||
stringValueName = (&wrapperspb.StringValue{}).ProtoReflect().Descriptor().FullName()
|
||||
boolValueName = (&wrapperspb.BoolValue{}).ProtoReflect().Descriptor().FullName()
|
||||
uInt32ValueName = (&wrapperspb.UInt32Value{}).ProtoReflect().Descriptor().FullName()
|
||||
int32ValueName = (&wrapperspb.Int32Value{}).ProtoReflect().Descriptor().FullName()
|
||||
structValueName = (&_struct.Struct{}).ProtoReflect().Descriptor().FullName()
|
||||
timestampName = (×tamppb.Timestamp{}).ProtoReflect().Descriptor().FullName()
|
||||
)
|
||||
|
||||
func messageKind(fd protoreflect.FieldDescriptor) (ptr, pkg, name string) {
|
||||
switch fd.Message().FullName() {
|
||||
case stringValueName:
|
||||
return "", "", "string"
|
||||
case boolValueName:
|
||||
return "", "", "bool"
|
||||
case uInt32ValueName:
|
||||
return "", "", "uint32"
|
||||
case int32ValueName:
|
||||
return "", "", "int32"
|
||||
case structValueName:
|
||||
return "", "", "map[string]interface{}"
|
||||
case timestampName:
|
||||
return "", "time", "Time"
|
||||
default:
|
||||
return "*", packageFromFullName(fd.Message().FullName()), string(fd.Message().Name())
|
||||
}
|
||||
}
|
||||
@@ -1,738 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/iancoleman/strcase"
|
||||
)
|
||||
|
||||
func getArgsAndPaths(in []string, parentTypeName, action string) (colArg, resArg string, colPath, resPath string) {
|
||||
resArg = fmt.Sprintf("%sId", strcase.ToLowerCamel(strings.ReplaceAll(in[len(in)-1], "-", "_")))
|
||||
strToReplace := "scope"
|
||||
if len(in) == 1 {
|
||||
if parentTypeName != "" {
|
||||
strToReplace = parentTypeName
|
||||
}
|
||||
} else {
|
||||
strToReplace = in[len(in)-2]
|
||||
}
|
||||
colArg = fmt.Sprintf("%sId", strcase.ToLowerCamel(strings.ReplaceAll(strToReplace, "-", "_")))
|
||||
colPath = fmt.Sprintf("%ss", in[len(in)-1])
|
||||
|
||||
if action != "" {
|
||||
action = fmt.Sprintf(":%s", action)
|
||||
}
|
||||
resPath = fmt.Sprintf("fmt.Sprintf(\"%s/%%s%s\", %s)", colPath, action, resArg)
|
||||
return
|
||||
}
|
||||
|
||||
type templateInput struct {
|
||||
Name string
|
||||
Package string
|
||||
Fields []fieldInfo
|
||||
PathArgs []string
|
||||
CollectionFunctionArg string
|
||||
ResourceFunctionArg string
|
||||
CollectionPath string
|
||||
ResourcePath string
|
||||
ParentTypeName string
|
||||
SliceSubTypes map[string]string
|
||||
ExtraOptions []fieldInfo
|
||||
VersionEnabled bool
|
||||
TypeOnCreate bool
|
||||
CreateResponseTypes bool
|
||||
}
|
||||
|
||||
func fillTemplates() {
|
||||
optionsMap := map[string]map[string]fieldInfo{}
|
||||
for _, in := range inputStructs {
|
||||
outBuf := new(bytes.Buffer)
|
||||
input := templateInput{
|
||||
Name: in.generatedStructure.name,
|
||||
Package: in.generatedStructure.pkg,
|
||||
Fields: in.generatedStructure.fields,
|
||||
PathArgs: in.pathArgs,
|
||||
ParentTypeName: in.parentTypeName,
|
||||
ExtraOptions: in.extraOptions,
|
||||
VersionEnabled: in.versionEnabled,
|
||||
TypeOnCreate: in.typeOnCreate,
|
||||
CreateResponseTypes: in.createResponseTypes,
|
||||
}
|
||||
|
||||
if len(in.pathArgs) > 0 {
|
||||
input.CollectionFunctionArg, input.ResourceFunctionArg, input.CollectionPath, input.ResourcePath = getArgsAndPaths(in.pathArgs, in.parentTypeName, "")
|
||||
}
|
||||
|
||||
if err := structTemplate.Execute(outBuf, input); err != nil {
|
||||
fmt.Printf("error executing struct template for resource %s: %v\n", in.generatedStructure.name, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(in.sliceSubTypes) > 0 {
|
||||
input.SliceSubTypes = in.sliceSubTypes
|
||||
in.templates = append(in.templates, sliceSubTypeTemplate)
|
||||
}
|
||||
|
||||
for _, t := range in.templates {
|
||||
if err := t.Execute(outBuf, input); err != nil {
|
||||
fmt.Printf("error executing function template for resource %s: %v\n", in.generatedStructure.name, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// We want to generate options per-package, not per-struct, so we
|
||||
// collate them all here for writing later. The map argument of the
|
||||
// package map is to prevent duplicates since we may have multiple e.g.
|
||||
// Name or Description fields.
|
||||
if !in.outputOnly {
|
||||
pkgOptionMap := map[string]fieldInfo{}
|
||||
for _, val := range input.Fields {
|
||||
if val.GenerateSdkOption {
|
||||
val.SubtypeName = in.subtypeName
|
||||
pkgOptionMap[val.Name] = val
|
||||
}
|
||||
}
|
||||
optionMap := optionsMap[input.Package]
|
||||
if optionMap == nil {
|
||||
optionMap = map[string]fieldInfo{}
|
||||
}
|
||||
for name, val := range pkgOptionMap {
|
||||
optionMap[name] = val
|
||||
}
|
||||
optionsMap[input.Package] = optionMap
|
||||
}
|
||||
// Add in extra defined options
|
||||
if len(in.extraOptions) > 0 {
|
||||
optionMap := optionsMap[input.Package]
|
||||
if optionMap == nil {
|
||||
optionMap = map[string]fieldInfo{}
|
||||
}
|
||||
for _, val := range in.extraOptions {
|
||||
optionMap[val.Name] = val
|
||||
}
|
||||
optionsMap[input.Package] = optionMap
|
||||
}
|
||||
|
||||
outFile, err := filepath.Abs(fmt.Sprintf("%s/%s", os.Getenv("API_GEN_BASEPATH"), in.outFile))
|
||||
if err != nil {
|
||||
fmt.Printf("error opening file %q: %v\n", in.outFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
outDir := filepath.Dir(outFile)
|
||||
if _, err := os.Stat(outDir); os.IsNotExist(err) {
|
||||
_ = os.Mkdir(outDir, os.ModePerm)
|
||||
}
|
||||
if err := ioutil.WriteFile(outFile, outBuf.Bytes(), 0644); err != nil {
|
||||
fmt.Printf("error writing file %q: %v\n", outFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Now reconstruct options per package and write them out
|
||||
for pkg, options := range optionsMap {
|
||||
outBuf := new(bytes.Buffer)
|
||||
|
||||
var fieldNames []string
|
||||
for _, v := range options {
|
||||
fieldNames = append(fieldNames, v.Name)
|
||||
}
|
||||
sort.Strings(fieldNames)
|
||||
|
||||
var fields []fieldInfo
|
||||
for _, v := range fieldNames {
|
||||
fields = append(fields, options[v])
|
||||
}
|
||||
|
||||
input := templateInput{
|
||||
Package: pkg,
|
||||
Fields: fields,
|
||||
}
|
||||
|
||||
if err := optionTemplate.Execute(outBuf, input); err != nil {
|
||||
fmt.Printf("error executing option template for package %s: %v\n", pkg, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
outFile, err := filepath.Abs(fmt.Sprintf("%s/%s/%s", os.Getenv("API_GEN_BASEPATH"), pkg, "option.gen.go"))
|
||||
if err != nil {
|
||||
fmt.Printf("error opening file %q: %v\n", "option.gen.go", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
outDir := filepath.Dir(outFile)
|
||||
if _, err := os.Stat(outDir); os.IsNotExist(err) {
|
||||
_ = os.Mkdir(outDir, os.ModePerm)
|
||||
}
|
||||
if err := ioutil.WriteFile(outFile, outBuf.Bytes(), 0644); err != nil {
|
||||
fmt.Printf("error writing file %q: %v\n", outFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var listTemplate = template.Must(template.New("").Funcs(
|
||||
template.FuncMap{
|
||||
"snakeCase": snakeCase,
|
||||
},
|
||||
).Parse(`
|
||||
func (c *Client) List(ctx context.Context, {{ .CollectionFunctionArg }} string, opt... Option) (*{{ .Name }}ListResult, error) {
|
||||
if {{ .CollectionFunctionArg }} == "" {
|
||||
return nil, fmt.Errorf("empty {{ .CollectionFunctionArg }} value passed into List request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["{{ snakeCase .CollectionFunctionArg }}"] = {{ .CollectionFunctionArg }}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "{{ .CollectionPath }}", nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating List request: %w", err)
|
||||
}
|
||||
{{ if ( eq .CollectionPath "\"scopes\"" ) }}
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
{{ end }}
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during List call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ .Name }}ListResult)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding List response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
target.responseBody = resp.Body
|
||||
target.responseMap = resp.Map
|
||||
return target, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var readTemplate = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Read(ctx context.Context, {{ .ResourceFunctionArg }} string, opt... Option) (*{{ .Name }}ReadResult, error) {
|
||||
if {{ .ResourceFunctionArg }} == "" {
|
||||
return nil, fmt.Errorf("empty {{ .ResourceFunctionArg }} value passed into Read request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", {{ .ResourcePath }}, nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating Read request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during Read call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ .Name }}ReadResult)
|
||||
target.Item = new({{ .Name }})
|
||||
apiErr, err := resp.Decode(target.Item)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding Read response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
target.responseBody = resp.Body
|
||||
target.responseMap = resp.Map
|
||||
return target, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var deleteTemplate = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Delete(ctx context.Context, {{ .ResourceFunctionArg }} string, opt... Option) (*{{ .Name }}DeleteResult, error) {
|
||||
if {{ .ResourceFunctionArg }} == "" {
|
||||
return nil, fmt.Errorf("empty {{ .ResourceFunctionArg }} value passed into Delete request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", {{ .ResourcePath }}, nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating Delete request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during Delete call: %w", err)
|
||||
}
|
||||
|
||||
apiErr, err := resp.Decode(nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding Delete response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
|
||||
target := &{{ .Name }}DeleteResult{
|
||||
responseBody: resp.Body,
|
||||
responseMap: resp.Map,
|
||||
}
|
||||
return target, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var createTemplate = template.Must(template.New("").Funcs(
|
||||
template.FuncMap{
|
||||
"snakeCase": snakeCase,
|
||||
},
|
||||
).Parse(`
|
||||
func (c *Client) Create (ctx context.Context, {{ if .TypeOnCreate }} resourceType string, {{ end }} {{ .CollectionFunctionArg }} string, opt... Option) (*{{ .Name }}CreateResult, error) {
|
||||
if {{ .CollectionFunctionArg }} == "" {
|
||||
return nil, fmt.Errorf("empty {{ .CollectionFunctionArg }} value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, fmt.Errorf("nil client")
|
||||
}
|
||||
{{ if .TypeOnCreate }} if resourceType == "" {
|
||||
return nil, fmt.Errorf("empty resourceType value passed into Create request")
|
||||
} else {
|
||||
opts.postMap["type"] = resourceType
|
||||
}{{ end }}
|
||||
|
||||
opts.postMap["{{ snakeCase .CollectionFunctionArg }}"] = {{ .CollectionFunctionArg }}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "{{ .CollectionPath }}", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
{{ if ( eq .CollectionPath "\"scopes\"" ) }}
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
{{ end }}
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during Create call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ .Name }}CreateResult)
|
||||
target.Item = new({{ .Name }})
|
||||
apiErr, err := resp.Decode(target.Item)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding Create response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
target.responseBody = resp.Body
|
||||
target.responseMap = resp.Map
|
||||
return target, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var updateTemplate = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Update(ctx context.Context, {{ .ResourceFunctionArg }} string, version uint32, opt... Option) (*{{ .Name }}UpdateResult, error) {
|
||||
if {{ .ResourceFunctionArg }} == "" {
|
||||
return nil, fmt.Errorf("empty {{ .ResourceFunctionArg }} value passed into Update request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
{{ if .VersionEnabled }}
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingErr := c.Read(ctx, {{ .ResourceFunctionArg }}, opt...)
|
||||
if existingErr != nil {
|
||||
if api.AsServerError(existingErr) != nil {
|
||||
return nil, fmt.Errorf("error from controller when performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
return nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, errors.New("nil resource response found when performing initial check-and-set read")
|
||||
}
|
||||
if existingTarget.Item == nil {
|
||||
return nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Item.Version
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "PATCH", {{ .ResourcePath }}, opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating Update request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during Update call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ .Name }}UpdateResult)
|
||||
target.Item = new({{ .Name }})
|
||||
apiErr, err := resp.Decode(target.Item)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding Update response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
target.responseBody = resp.Body
|
||||
target.responseMap = resp.Map
|
||||
return target, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var sliceSubTypeTemplate = template.Must(template.New("").Funcs(
|
||||
template.FuncMap{
|
||||
"makeSlice": makeSlice,
|
||||
"snakeCase": snakeCase,
|
||||
"kebabCase": kebabCase,
|
||||
"getPathWithAction": getPathWithAction,
|
||||
},
|
||||
).Parse(`
|
||||
{{ $input := . }}
|
||||
{{ range $index, $op := makeSlice "Add" "Set" "Remove" }}
|
||||
{{ range $key, $value := $input.SliceSubTypes }}
|
||||
{{ $fullName := print $op $key }}
|
||||
{{ $actionName := kebabCase $fullName }}
|
||||
{{ $resPath := getPathWithAction $input.PathArgs $input.ParentTypeName $actionName }}
|
||||
func (c *Client) {{ $fullName }}(ctx context.Context, {{ $input.ResourceFunctionArg }} string, version uint32, {{ $value }} []string, opt... Option) (*{{ $input.Name }}UpdateResult, error) {
|
||||
if {{ $input.ResourceFunctionArg }} == "" {
|
||||
return nil, fmt.Errorf("empty {{ $input.ResourceFunctionArg }} value passed into {{ $fullName }} request")
|
||||
}
|
||||
{{ if ( not ( eq $op "Set" ) ) }}if len({{ $value }}) == 0 {
|
||||
return nil, errors.New("empty {{ $value }} passed into {{ $fullName }} request")
|
||||
}{{ end }}
|
||||
if c.client == nil {
|
||||
return nil, errors.New("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
{{ if $input.VersionEnabled }}
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, errors.New("zero version number passed into {{ $fullName }} request")
|
||||
}
|
||||
existingTarget, existingErr := c.Read(ctx, {{ $input.ResourceFunctionArg }}, opt...)
|
||||
if existingErr != nil {
|
||||
if api.AsServerError(existingErr) != nil {
|
||||
return nil, fmt.Errorf("error from controller when performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
return nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, errors.New("nil resource response found when performing initial check-and-set read")
|
||||
}
|
||||
if existingTarget.Item == nil {
|
||||
return nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Item.Version
|
||||
}
|
||||
{{ end }}
|
||||
opts.postMap["version"] = version
|
||||
opts.postMap["{{ snakeCase $value }}"] = {{ $value }}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", {{ $resPath }}, opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating {{ $fullName }} request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
q.Add(k, v)
|
||||
}
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error performing client request during {{ $fullName }} call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ $input.Name }}UpdateResult)
|
||||
target.Item = new({{ $input.Name }})
|
||||
apiErr, err := resp.Decode(target.Item)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding {{ $fullName }} response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr
|
||||
}
|
||||
target.responseBody = resp.Body
|
||||
target.responseMap = resp.Map
|
||||
return target, nil
|
||||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
`))
|
||||
|
||||
var structTemplate = template.Must(template.New("").Parse(
|
||||
fmt.Sprint(`// Code generated by "make api"; DO NOT EDIT.
|
||||
package {{ .Package }}
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/kr/pretty"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/scopes"
|
||||
)
|
||||
|
||||
type {{ .Name }} struct { {{ range .Fields }}
|
||||
{{ .Name }} {{ .FieldType }} `, "`json:\"{{ .ProtoName }},omitempty\"`", `{{ end }}
|
||||
{{ if ( or .CreateResponseTypes ( eq .Name "Error" ) ) }}
|
||||
responseBody *bytes.Buffer
|
||||
responseMap map[string]interface{}
|
||||
{{ end }}
|
||||
}
|
||||
|
||||
{{ if ( or .CreateResponseTypes ( eq .Name "Error" ) ) }}
|
||||
func (n {{ .Name }}) ResponseBody() *bytes.Buffer {
|
||||
return n.responseBody
|
||||
}
|
||||
|
||||
func (n {{ .Name }}) ResponseMap() map[string]interface{} {
|
||||
return n.responseMap
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ if .CreateResponseTypes }}
|
||||
type {{ .Name }}ReadResult struct {
|
||||
Item *{{ .Name }}
|
||||
responseBody *bytes.Buffer
|
||||
responseMap map[string]interface{}
|
||||
}
|
||||
|
||||
func (n {{ .Name }}ReadResult) GetItem() interface{} {
|
||||
return n.Item
|
||||
}
|
||||
|
||||
func (n {{ .Name }}ReadResult) GetResponseBody() *bytes.Buffer {
|
||||
return n.responseBody
|
||||
}
|
||||
|
||||
func (n {{ .Name }}ReadResult) GetResponseMap() map[string]interface{} {
|
||||
return n.responseMap
|
||||
}
|
||||
|
||||
type {{ .Name }}CreateResult = {{ .Name }}ReadResult
|
||||
type {{ .Name }}UpdateResult = {{ .Name }}ReadResult
|
||||
|
||||
type {{ .Name }}DeleteResult struct {
|
||||
responseBody *bytes.Buffer
|
||||
responseMap map[string]interface{}
|
||||
}
|
||||
|
||||
func (n {{ .Name }}DeleteResult) GetResponseBody() *bytes.Buffer {
|
||||
return n.responseBody
|
||||
}
|
||||
|
||||
func (n {{ .Name }}DeleteResult) GetResponseMap() map[string]interface{} {
|
||||
return n.responseMap
|
||||
}
|
||||
|
||||
type {{ .Name }}ListResult struct {
|
||||
Items []*{{ .Name }}
|
||||
responseBody *bytes.Buffer
|
||||
responseMap map[string]interface{}
|
||||
}
|
||||
|
||||
func (n {{ .Name }}ListResult) GetItems() interface{} {
|
||||
return n.Items
|
||||
}
|
||||
|
||||
func (n {{ .Name }}ListResult) GetResponseBody() *bytes.Buffer {
|
||||
return n.responseBody
|
||||
}
|
||||
|
||||
func (n {{ .Name }}ListResult) GetResponseMap() map[string]interface{} {
|
||||
return n.responseMap
|
||||
}
|
||||
{{ end }}
|
||||
`)))
|
||||
|
||||
var clientTemplate = template.Must(template.New("").Parse(`
|
||||
// Client is a client for this collection
|
||||
type Client struct {
|
||||
client *api.Client
|
||||
}
|
||||
|
||||
// Creates a new client for this collection. The submitted API client is cloned;
|
||||
// modifications to it after generating this client will not have effect. If you
|
||||
// need to make changes to the underlying API client, use ApiClient() to access
|
||||
// it.
|
||||
func NewClient(c *api.Client) *Client {
|
||||
return &Client{ client: c.Clone() }
|
||||
}
|
||||
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
`))
|
||||
|
||||
var optionTemplate = template.Must(template.New("").Parse(`
|
||||
package {{ .Package }}
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
)
|
||||
|
||||
// Option is a func that sets optional attributes for a call. This does not need
|
||||
// to be used directly, but instead option arguments are built from the
|
||||
// functions in this package. WithX options set a value to that given in the
|
||||
// argument; DefaultX options indicate that the value should be set to its
|
||||
// default. When an API call is made options are processed in ther order they
|
||||
// appear in the function call, so for a given argument X, a succession of WithX
|
||||
// or DefaultX calls will result in the last call taking effect.
|
||||
type Option func(*options)
|
||||
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
func getDefaultOptions() options {
|
||||
return options{
|
||||
postMap: make(map[string]interface{}),
|
||||
queryMap: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
func getOpts(opt ...Option) (options, []api.Option) {
|
||||
opts := getDefaultOptions()
|
||||
for _, o := range opt {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
// If set, and if the version is zero during an update, the API will perform a
|
||||
// fetch to get the current version of the resource and populate it during the
|
||||
// update call. This is convenient but opens up the possibility for subtle
|
||||
// order-of-modification issues, so use carefully.
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
{{ range .Fields }}
|
||||
func With{{ .SubtypeName }}{{ .Name }}(in{{ .Name }} {{ .FieldType }}) Option {
|
||||
return func(o *options) { {{ if ( not ( eq .SubtypeName "" ) ) }}
|
||||
raw, ok := o.postMap["attributes"]
|
||||
if !ok {
|
||||
raw = interface{}(map[string]interface{}{})
|
||||
}
|
||||
val := raw.(map[string]interface{})
|
||||
val["{{ .ProtoName }}"] = in{{ .Name }}
|
||||
o.postMap["attributes"] = val
|
||||
{{ else if .Query }}
|
||||
o.queryMap["{{ .ProtoName }}"] = fmt.Sprintf("%v", in{{ .Name }})
|
||||
{{ else }}
|
||||
o.postMap["{{ .ProtoName }}"] = in{{ .Name }}
|
||||
{{ end }} }
|
||||
}
|
||||
{{ if ( not .SkipDefault ) }}
|
||||
func Default{{ .SubtypeName }}{{ .Name }}() Option {
|
||||
return func(o *options) { {{ if ( not ( eq .SubtypeName "" ) ) }}
|
||||
raw, ok := o.postMap["attributes"]
|
||||
if !ok {
|
||||
raw = interface{}(map[string]interface{}{})
|
||||
}
|
||||
val := raw.(map[string]interface{})
|
||||
val["{{ .ProtoName }}"] = nil
|
||||
o.postMap["attributes"] = val
|
||||
{{ else }}
|
||||
o.postMap["{{ .ProtoName }}"] = nil
|
||||
{{ end }} }
|
||||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
`))
|
||||
|
||||
func makeSlice(strs ...string) []string {
|
||||
return strs
|
||||
}
|
||||
|
||||
func snakeCase(in string) string {
|
||||
return strcase.ToSnake(in)
|
||||
}
|
||||
|
||||
func kebabCase(in string) string {
|
||||
return strcase.ToKebab(in)
|
||||
}
|
||||
|
||||
func getPathWithAction(resArgs []string, parentTypeName, action string) string {
|
||||
_, _, _, resPath := getArgsAndPaths(resArgs, parentTypeName, action)
|
||||
return resPath
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package tests
|
||||
|
||||
// TODO: Reenable once we reimplement generation of As functions once static hosts lands
|
||||
/*
|
||||
func TestDetailTemplating(t *testing.T) {
|
||||
lt := time.Now()
|
||||
c := hosts.HostCatalog{
|
||||
Id: "id",
|
||||
CreatedTime: lt,
|
||||
Attributes: map[string]interface{}{
|
||||
"regions": []string{"a", "b"},
|
||||
"access_key": "access",
|
||||
"secret_key": "secret",
|
||||
"rotate": true,
|
||||
},
|
||||
}
|
||||
|
||||
ac, err := c.AsAwsEc2HostCatalog()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &hosts.AwsEc2HostCatalog{
|
||||
HostCatalog: &c,
|
||||
Regions: []string{"a", "b"},
|
||||
AccessKey: api.String("access"),
|
||||
SecretKey: api.String("secret"),
|
||||
Rotate: api.Bool(true),
|
||||
}, ac)
|
||||
}
|
||||
*/
|
||||
@@ -1,307 +0,0 @@
|
||||
package roles_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/groups"
|
||||
"github.com/hashicorp/boundary/api/roles"
|
||||
"github.com/hashicorp/boundary/api/users"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCustom(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
user, err := users.NewClient(client).Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
|
||||
hasPrincipal := func(role *roles.Role, principalId string) bool {
|
||||
var foundInPrincipals bool
|
||||
var foundInPrincipalIds bool
|
||||
for _, v := range role.Principals {
|
||||
if v.Id == principalId {
|
||||
foundInPrincipals = true
|
||||
}
|
||||
}
|
||||
for _, v := range role.PrincipalIds {
|
||||
if v == principalId {
|
||||
foundInPrincipalIds = true
|
||||
}
|
||||
}
|
||||
return foundInPrincipals && foundInPrincipalIds
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g, err := groups.NewClient(client).Create(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
require.NotNil(g)
|
||||
|
||||
rc := roles.NewClient(client)
|
||||
var version uint32 = 1
|
||||
|
||||
r, err := rc.Create(tc.Context(), tt.scopeId, roles.WithName("foo"))
|
||||
require.NoError(err)
|
||||
require.NotNil(r)
|
||||
require.EqualValues(r.Item.Version, version)
|
||||
version++
|
||||
|
||||
updatedRole, err := rc.AddPrincipals(tc.Context(), r.Item.Id, r.Item.Version, []string{g.Item.Id})
|
||||
require.NoError(err)
|
||||
assert.EqualValues(updatedRole.Item.Version, version)
|
||||
assert.True(hasPrincipal(updatedRole.Item, g.Item.Id))
|
||||
version++
|
||||
|
||||
updatedRole, err = rc.SetPrincipals(tc.Context(), updatedRole.Item.Id, updatedRole.Item.Version, []string{user.Item.Id})
|
||||
require.NoError(err)
|
||||
assert.EqualValues(updatedRole.Item.Version, version)
|
||||
assert.True(hasPrincipal(updatedRole.Item, user.Item.Id))
|
||||
version++
|
||||
|
||||
updatedRole, err = rc.RemovePrincipals(tc.Context(), updatedRole.Item.Id, updatedRole.Item.Version, []string{user.Item.Id})
|
||||
require.NoError(err)
|
||||
assert.EqualValues(updatedRole.Item.Version, version)
|
||||
assert.Empty(updatedRole.Item.Principals)
|
||||
version++
|
||||
|
||||
updatedRole, err = rc.AddGrants(tc.Context(), updatedRole.Item.Id, updatedRole.Item.Version, []string{"id=*;type=*;actions=read"})
|
||||
require.NoError(err)
|
||||
assert.EqualValues(updatedRole.Item.Version, version)
|
||||
assert.Contains(updatedRole.Item.GrantStrings, "id=*;type=*;actions=read")
|
||||
version++
|
||||
|
||||
updatedRole, err = rc.SetGrants(tc.Context(), updatedRole.Item.Id, updatedRole.Item.Version, []string{"id=*;type=*;actions=*"})
|
||||
require.NoError(err)
|
||||
assert.EqualValues(updatedRole.Item.Version, version)
|
||||
assert.Contains(updatedRole.Item.GrantStrings, "id=*;type=*;actions=*")
|
||||
version++
|
||||
|
||||
updatedRole, err = rc.RemoveGrants(tc.Context(), updatedRole.Item.Id, updatedRole.Item.Version, []string{"id=*;type=*;actions=*"})
|
||||
require.NoError(err)
|
||||
assert.EqualValues(updatedRole.Item.Version, version)
|
||||
assert.Empty(updatedRole.Item.Grants)
|
||||
version++
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var expected []*roles.Role
|
||||
|
||||
roleClient := roles.NewClient(client)
|
||||
p1, err := roleClient.List(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
require.Len(p1.Items, 2)
|
||||
expected = append(expected, p1.Items[0:2]...)
|
||||
|
||||
for i := 2; i < 12; i++ {
|
||||
expected = append(expected, &roles.Role{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
rcr, err := roleClient.Create(tc.Context(), tt.scopeId, roles.WithName(expected[2].Name))
|
||||
require.NoError(err)
|
||||
expected[2] = rcr.Item
|
||||
|
||||
p2, err := roleClient.List(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected[0:3]), comparableSlice(p2.Items))
|
||||
|
||||
for i := 3; i < 12; i++ {
|
||||
rcr, err = roleClient.Create(tc.Context(), tt.scopeId, roles.WithName(expected[i].Name))
|
||||
assert.NoError(err)
|
||||
expected[i] = rcr.Item
|
||||
}
|
||||
p3, err := roleClient.List(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(p3.Items))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func comparableSlice(in []*roles.Role) []roles.Role {
|
||||
var filtered []roles.Role
|
||||
for _, i := range in {
|
||||
p := roles.Role{
|
||||
Id: i.Id,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
checkRole := func(step string, g *roles.Role, err error, wantedName string, wantedVersion uint32) {
|
||||
assert.NoError(err, step)
|
||||
assert.NotNil(g, "returned no resource", step)
|
||||
gotName := ""
|
||||
if g.Name != "" {
|
||||
gotName = g.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.EqualValues(wantedVersion, g.Version)
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
roleClient := roles.NewClient(client)
|
||||
g, err := roleClient.Create(tc.Context(), tt.scopeId, roles.WithName("foo"))
|
||||
checkRole("create", g.Item, err, "foo", 1)
|
||||
|
||||
g, err = roleClient.Read(tc.Context(), g.Item.Id)
|
||||
checkRole("read", g.Item, err, "foo", 1)
|
||||
|
||||
g, err = roleClient.Update(tc.Context(), g.Item.Id, g.Item.Version, roles.WithName("bar"))
|
||||
checkRole("update", g.Item, err, "bar", 2)
|
||||
|
||||
g, err = roleClient.Update(tc.Context(), g.Item.Id, g.Item.Version, roles.DefaultName())
|
||||
checkRole("update", g.Item, err, "", 3)
|
||||
|
||||
_, err = roleClient.Delete(tc.Context(), g.Item.Id)
|
||||
require.NoError(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
roleClient := roles.NewClient(client)
|
||||
u, err := roleClient.Create(tc.Context(), tt.scopeId, roles.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(u)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = roleClient.Update(tc.Context(), u.Item.Id, 73, roles.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
// Create another resource with the same name.
|
||||
_, err = roleClient.Create(tc.Context(), tt.scopeId, roles.WithName("first"))
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
_, err = roleClient.Read(tc.Context(), iam.RolePrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = roleClient.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
|
||||
_, err = roleClient.Update(tc.Context(), u.Item.Id, u.Item.Version)
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
package scopes_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/scopes"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
scps := scopes.NewClient(client)
|
||||
|
||||
pl, err := scps.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Empty(pl.Items)
|
||||
|
||||
expected := make([]*scopes.Scope, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
scr, err := scps.Create(tc.Context(), org.GetPublicId(), scopes.WithName(fmt.Sprintf("%d", i)))
|
||||
require.NoError(err)
|
||||
expected[i] = scr.Item
|
||||
}
|
||||
pl, err = scps.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(pl.Items))
|
||||
}
|
||||
|
||||
func comparableSlice(in []*scopes.Scope) []scopes.Scope {
|
||||
var filtered []scopes.Scope
|
||||
for _, i := range in {
|
||||
p := scopes.Scope{
|
||||
Id: i.Id,
|
||||
ScopeId: i.ScopeId,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, _ := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
scps := scopes.NewClient(client)
|
||||
|
||||
checkProject := func(step string, s *scopes.Scope, err error, wantedName string, wantedVersion uint32) {
|
||||
require.NoError(err, step)
|
||||
assert.NotNil(s, "returned project", step)
|
||||
gotName := ""
|
||||
if s.Name != "" {
|
||||
gotName = s.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.Equal(wantedVersion, s.Version)
|
||||
}
|
||||
|
||||
s, err := scps.Create(tc.Context(), org.GetPublicId(), scopes.WithName("foo"))
|
||||
checkProject("create", s.Item, err, "foo", 1)
|
||||
|
||||
s, err = scps.Read(tc.Context(), s.Item.Id)
|
||||
checkProject("read", s.Item, err, "foo", 1)
|
||||
|
||||
s, err = scps.Update(tc.Context(), s.Item.Id, s.Item.Version, scopes.WithName("bar"))
|
||||
checkProject("update", s.Item, err, "bar", 2)
|
||||
|
||||
s, err = scps.Update(tc.Context(), s.Item.Id, s.Item.Version, scopes.DefaultName())
|
||||
checkProject("update, unset name", s.Item, err, "", 3)
|
||||
|
||||
_, err = scps.Delete(tc.Context(), s.Item.Id)
|
||||
require.NoError(err)
|
||||
|
||||
_, err = scps.Delete(tc.Context(), s.Item.Id)
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, _ := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
scps := scopes.NewClient(client)
|
||||
|
||||
createdProj, err := scps.Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.NotNil(createdProj)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = scps.Update(tc.Context(), createdProj.Item.Id, 73, scopes.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = scps.Read(tc.Context(), "p_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = scps.Read(tc.Context(), "invalid id")
|
||||
assert.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
package targets_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/hostcatalogs"
|
||||
"github.com/hashicorp/boundary/api/hostsets"
|
||||
"github.com/hashicorp/boundary/api/targets"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/hashicorp/boundary/internal/target"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCustom(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
token := tc.Token()
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
client := tc.Client().Clone()
|
||||
client.SetToken(token.Token)
|
||||
|
||||
hc, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
|
||||
hSetClient := hostsets.NewClient(client)
|
||||
hSet, err := hSetClient.Create(tc.Context(), hc.Item.Id)
|
||||
require.NoError(err)
|
||||
require.NotNil(hSet)
|
||||
hSet2, err := hSetClient.Create(tc.Context(), hc.Item.Id)
|
||||
require.NoError(err)
|
||||
require.NotNil(hSet2)
|
||||
|
||||
tarClient := targets.NewClient(client)
|
||||
tar, err := tarClient.Create(tc.Context(), "tcp", proj.GetPublicId(), targets.WithName("foo"))
|
||||
require.NoError(err)
|
||||
require.NotNil(tar)
|
||||
assert.Empty(tar.Item.HostSetIds)
|
||||
|
||||
tar, err = tarClient.AddHostSets(tc.Context(), tar.Item.Id, tar.Item.Version, []string{hSet.Item.Id})
|
||||
require.NoError(err)
|
||||
require.NotNil(tar)
|
||||
assert.ElementsMatch(tar.Item.HostSetIds, []string{hSet.Item.Id})
|
||||
|
||||
tar, err = tarClient.SetHostSets(tc.Context(), tar.Item.Id, tar.Item.Version, []string{hSet2.Item.Id})
|
||||
require.NoError(err)
|
||||
require.NotNil(tar)
|
||||
assert.ElementsMatch(tar.Item.HostSetIds, []string{hSet2.Item.Id})
|
||||
|
||||
tar, err = tarClient.RemoveHostSets(tc.Context(), tar.Item.Id, tar.Item.Version, []string{hSet2.Item.Id})
|
||||
require.NoError(err)
|
||||
require.NotNil(tar)
|
||||
assert.Empty(tar.Item.HostSetIds)
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
tarClient := targets.NewClient(client)
|
||||
ul, err := tarClient.List(tc.Context(), proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Empty(ul.Items)
|
||||
|
||||
var expected []*targets.Target
|
||||
for i := 0; i < 10; i++ {
|
||||
expected = append(expected, &targets.Target{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
tcr, err := tarClient.Create(tc.Context(), "tcp", proj.GetPublicId(), targets.WithName(expected[0].Name))
|
||||
require.NoError(err)
|
||||
expected[0] = tcr.Item
|
||||
|
||||
ul, err = tarClient.List(tc.Context(), proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected[:1]), comparableSlice(ul.Items))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
tcr, err = tarClient.Create(tc.Context(), "tcp", proj.GetPublicId(), targets.WithName(expected[i].Name))
|
||||
require.NoError(err)
|
||||
expected[i] = tcr.Item
|
||||
}
|
||||
ul, err = tarClient.List(tc.Context(), proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(ul.Items))
|
||||
}
|
||||
|
||||
func comparableSlice(in []*targets.Target) []targets.Target {
|
||||
var filtered []targets.Target
|
||||
for _, i := range in {
|
||||
p := targets.Target{
|
||||
Id: i.Id,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
checkResource := func(t *testing.T, step string, h *targets.Target, err error, wantedName string, wantVersion uint32) {
|
||||
t.Helper()
|
||||
require.NoError(err, step)
|
||||
assert.NotNil(h, "returned no resource", step)
|
||||
gotName := ""
|
||||
if h.Name != "" {
|
||||
gotName = h.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.Equal(wantVersion, h.Version)
|
||||
}
|
||||
|
||||
tarClient := targets.NewClient(client)
|
||||
|
||||
tar, err := tarClient.Create(tc.Context(), "tcp", proj.GetPublicId(), targets.WithName("foo"))
|
||||
checkResource(t, "create", tar.Item, err, "foo", 1)
|
||||
|
||||
tar, err = tarClient.Read(tc.Context(), tar.Item.Id)
|
||||
checkResource(t, "read", tar.Item, err, "foo", 1)
|
||||
|
||||
tar, err = tarClient.Update(tc.Context(), tar.Item.Id, tar.Item.Version, targets.WithName("bar"))
|
||||
checkResource(t, "update", tar.Item, err, "bar", 2)
|
||||
|
||||
_, err = tarClient.Delete(tc.Context(), tar.Item.Id)
|
||||
assert.NoError(err)
|
||||
|
||||
_, err = tarClient.Delete(tc.Context(), tar.Item.Id)
|
||||
assert.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
}
|
||||
|
||||
func TestSet_Errors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
tarClient := targets.NewClient(client)
|
||||
|
||||
tar, err := tarClient.Create(tc.Context(), "tcp", proj.GetPublicId(), targets.WithName("foo"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(tar)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = tarClient.Update(tc.Context(), tar.Item.Id, 73, targets.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
tar, err = tarClient.Create(tc.Context(), "tcp", proj.GetPublicId(), targets.WithName("foo"))
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.Nil(tar)
|
||||
|
||||
_, err = tarClient.Read(tc.Context(), target.TcpTargetPrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = tarClient.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
package users_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/accounts"
|
||||
"github.com/hashicorp/boundary/api/users"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/servers/controller"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCustom(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
uClient := users.NewClient(client)
|
||||
aClient := accounts.NewClient(client)
|
||||
|
||||
usr1, err := uClient.Create(tc.Context(), "global")
|
||||
require.NoError(err)
|
||||
|
||||
acct1, err := aClient.Create(tc.Context(), token.AuthMethodId, accounts.WithPasswordAccountLoginName("accountname"))
|
||||
require.NoError(err)
|
||||
acct2, err := aClient.Create(tc.Context(), token.AuthMethodId, accounts.WithPasswordAccountLoginName("accountname2"))
|
||||
require.NoError(err)
|
||||
|
||||
addResult, err := uClient.AddAccounts(tc.Context(), usr1.Item.Id, 0, []string{acct1.Item.Id, acct2.Item.Id}, users.WithAutomaticVersioning(true))
|
||||
assert.NoError(err)
|
||||
assert.ElementsMatch([]string{acct1.Item.Id, acct2.Item.Id}, addResult.Item.AccountIds)
|
||||
|
||||
// Add the account to the default user
|
||||
_, err = uClient.AddAccounts(tc.Context(), token.UserId, 0, []string{acct1.Item.Id}, users.WithAutomaticVersioning(true))
|
||||
assert.Error(err)
|
||||
|
||||
remResult, err := uClient.RemoveAccounts(tc.Context(), usr1.Item.Id, 0, []string{acct1.Item.Id}, users.WithAutomaticVersioning(true))
|
||||
assert.NoError(err)
|
||||
assert.ElementsMatch([]string{acct2.Item.Id}, remResult.Item.AccountIds)
|
||||
|
||||
// Cannot remove an account that isn't associated with a user.
|
||||
_, err = uClient.RemoveAccounts(tc.Context(), usr1.Item.Id, 0, []string{acct1.Item.Id}, users.WithAutomaticVersioning(true))
|
||||
assert.Error(err)
|
||||
|
||||
setResult, err := uClient.SetAccounts(tc.Context(), usr1.Item.Id, 0, []string{acct1.Item.Id, acct2.Item.Id}, users.WithAutomaticVersioning(true))
|
||||
assert.NoError(err)
|
||||
assert.ElementsMatch([]string{acct1.Item.Id, acct2.Item.Id}, setResult.Item.AccountIds)
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
userClient := users.NewClient(client)
|
||||
|
||||
ul, err := userClient.List(tc.Context(), org.GetPublicId())
|
||||
assert.NoError(err)
|
||||
assert.Empty(ul.Items)
|
||||
|
||||
var expected []*users.User
|
||||
for i := 0; i < 10; i++ {
|
||||
expected = append(expected, &users.User{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
ucr, err := userClient.Create(tc.Context(), org.GetPublicId(), users.WithName(expected[0].Name))
|
||||
assert.NoError(err)
|
||||
expected[0] = ucr.Item
|
||||
|
||||
ul, err = userClient.List(tc.Context(), org.GetPublicId())
|
||||
assert.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected[:1]), comparableSlice(ul.Items))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
ucr, err = userClient.Create(tc.Context(), org.GetPublicId(), users.WithName(expected[i].Name))
|
||||
assert.NoError(err)
|
||||
expected[i] = ucr.Item
|
||||
}
|
||||
ul, err = userClient.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(ul.Items))
|
||||
}
|
||||
|
||||
func comparableSlice(in []*users.User) []users.User {
|
||||
var filtered []users.User
|
||||
for _, i := range in {
|
||||
p := users.User{
|
||||
Id: i.Id,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
CreatedTime: i.CreatedTime,
|
||||
UpdatedTime: i.UpdatedTime,
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
userClient := users.NewClient(client)
|
||||
|
||||
checkUser := func(step string, u *users.User, err error, wantedName string, wantedVersion uint32) {
|
||||
assert.NoError(err, step)
|
||||
assert.NotNil(u, "returned no resource", step)
|
||||
gotName := ""
|
||||
if u.Name != "" {
|
||||
gotName = u.Name
|
||||
}
|
||||
assert.Equal(wantedName, gotName, step)
|
||||
assert.EqualValues(wantedVersion, u.Version)
|
||||
}
|
||||
|
||||
u, err := userClient.Create(tc.Context(), org.GetPublicId(), users.WithName("foo"))
|
||||
checkUser("create", u.Item, err, "foo", 1)
|
||||
|
||||
u, err = userClient.Read(tc.Context(), u.Item.Id)
|
||||
checkUser("read", u.Item, err, "foo", 1)
|
||||
|
||||
u, err = userClient.Update(tc.Context(), u.Item.Id, u.Item.Version, users.WithName("bar"))
|
||||
checkUser("update", u.Item, err, "bar", 2)
|
||||
|
||||
u, err = userClient.Update(tc.Context(), u.Item.Id, u.Item.Version, users.DefaultName())
|
||||
checkUser("update", u.Item, err, "", 3)
|
||||
|
||||
_, err = userClient.Delete(tc.Context(), u.Item.Id)
|
||||
require.NoError(err)
|
||||
|
||||
_, err = userClient.Delete(tc.Context(), u.Item.Id)
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
userClient := users.NewClient(client)
|
||||
|
||||
u, err := userClient.Create(tc.Context(), org.GetPublicId(), users.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(u)
|
||||
|
||||
// Updating the wrong version should fail.
|
||||
_, err = userClient.Update(tc.Context(), u.Item.Id, 73, users.WithName("anything"))
|
||||
require.Error(err)
|
||||
apiErr := api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
// Create another resource with the same name.
|
||||
_, err = userClient.Create(tc.Context(), org.GetPublicId(), users.WithName("first"))
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
_, err = userClient.Read(tc.Context(), iam.UserPrefix+"_doesntexis")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusNotFound, apiErr.Status)
|
||||
|
||||
_, err = userClient.Read(tc.Context(), "invalid id")
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
|
||||
_, err = userClient.Update(tc.Context(), u.Item.Id, u.Item.Version)
|
||||
require.Error(err)
|
||||
apiErr = api.AsServerError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
Reference in new issue
Block a user