Generate new version of SDK resources and Add Tests (#331)
This commit is contained in:
1 parent
96e4b1cdba
commit
c3ecea172d
93 files changed
+3414
-2826
No files matched your search
+27
-25
@@ -27,27 +27,42 @@ type Account struct {
|
||||
Attributes map[string]interface{} `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, authMethodId string, opt ...Option) (*Account, *api.Error, error) {
|
||||
if authMethodId == "" {
|
||||
return nil, nil, fmt.Errorf("empty authMethodId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("auth-methods/%s/accounts", authMethodId), opts.postMap, apiOpts...)
|
||||
opts.postMap["auth_method_id"] = authMethodId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "accounts", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
@@ -72,22 +87,17 @@ func (c *Client) Create(ctx context.Context, authMethodId string, opt ...Option)
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Read(ctx context.Context, authMethodId string, accountId string, opt ...Option) (*Account, *api.Error, error) {
|
||||
if authMethodId == "" {
|
||||
return nil, nil, fmt.Errorf("empty authMethodId value passed into Read request")
|
||||
}
|
||||
|
||||
func (c *Client) Read(ctx context.Context, accountId string, opt ...Option) (*Account, *api.Error, error) {
|
||||
if accountId == "" {
|
||||
return nil, nil, fmt.Errorf("empty accountId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty accountId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("auth-methods/%s/accounts/%s", authMethodId, accountId), nil, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("accounts/%s", accountId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Read request: %w", err)
|
||||
}
|
||||
@@ -116,10 +126,7 @@ func (c *Client) Read(ctx context.Context, authMethodId string, accountId string
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Update(ctx context.Context, authMethodId string, accountId string, version uint32, opt ...Option) (*Account, *api.Error, error) {
|
||||
if authMethodId == "" {
|
||||
return nil, nil, fmt.Errorf("empty authMethodId value passed into Update request")
|
||||
}
|
||||
func (c *Client) Update(ctx context.Context, accountId string, version uint32, opt ...Option) (*Account, *api.Error, error) {
|
||||
if accountId == "" {
|
||||
return nil, nil, fmt.Errorf("empty accountId value passed into Update request")
|
||||
}
|
||||
@@ -133,7 +140,7 @@ func (c *Client) Update(ctx context.Context, authMethodId string, accountId stri
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, authMethodId, accountId, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, accountId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -148,7 +155,7 @@ func (c *Client) Update(ctx context.Context, authMethodId string, accountId stri
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "PATCH", fmt.Sprintf("auth-methods/%s/accounts/%s", authMethodId, accountId), opts.postMap, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "PATCH", fmt.Sprintf("accounts/%s", accountId), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Update request: %w", err)
|
||||
}
|
||||
@@ -177,22 +184,17 @@ func (c *Client) Update(ctx context.Context, authMethodId string, accountId stri
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Delete(ctx context.Context, authMethodId string, accountId string, opt ...Option) (bool, *api.Error, error) {
|
||||
if authMethodId == "" {
|
||||
return false, nil, fmt.Errorf("empty authMethodId value passed into Delete request")
|
||||
}
|
||||
|
||||
func (c *Client) Delete(ctx context.Context, accountId string, opt ...Option) (bool, *api.Error, error) {
|
||||
if accountId == "" {
|
||||
return false, nil, fmt.Errorf("empty accountId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("auth-methods/%s/accounts/%s", authMethodId, accountId), nil, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("accounts/%s", accountId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("error creating Delete request: %w", err)
|
||||
}
|
||||
@@ -228,14 +230,14 @@ func (c *Client) List(ctx context.Context, authMethodId string, opt ...Option) (
|
||||
if authMethodId == "" {
|
||||
return nil, nil, fmt.Errorf("empty authMethodId value passed into List request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["auth_method_id"] = authMethodId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("auth-methods/%s/accounts", authMethodId), nil, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "GET", "accounts", nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating List request: %w", err)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package accounts_test
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
@@ -15,18 +16,21 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAccounts_List(t *testing.T) {
|
||||
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, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
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)
|
||||
am, apiErr, err := amClient.Create(tc.Context(), "password")
|
||||
am, apiErr, err := amClient.Create(tc.Context(), "password", org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(am)
|
||||
@@ -77,21 +81,15 @@ func comparableSlice(in []*accounts.Account) []accounts.Account {
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestAccount_Crud(t *testing.T) {
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
amId := token.AuthMethodId
|
||||
accountClient := accounts.NewClient(client)
|
||||
|
||||
checkAccount := func(step string, u *accounts.Account, apiErr *api.Error, err error, wantedName string, wantedVersion uint32) {
|
||||
@@ -111,35 +109,30 @@ func TestAccount_Crud(t *testing.T) {
|
||||
u, apiErr, err := accountClient.Create(tc.Context(), amId, accounts.WithName("foo"), accounts.WithPasswordAccountLoginName("loginname"))
|
||||
checkAccount("create", u, apiErr, err, "foo", 1)
|
||||
|
||||
u, apiErr, err = accountClient.Read(tc.Context(), amId, u.Id)
|
||||
u, apiErr, err = accountClient.Read(tc.Context(), u.Id)
|
||||
checkAccount("read", u, apiErr, err, "foo", 1)
|
||||
|
||||
u, apiErr, err = accountClient.Update(tc.Context(), amId, u.Id, u.Version, accounts.WithName("bar"))
|
||||
u, apiErr, err = accountClient.Update(tc.Context(), u.Id, u.Version, accounts.WithName("bar"))
|
||||
checkAccount("update", u, apiErr, err, "bar", 2)
|
||||
|
||||
u, apiErr, err = accountClient.Update(tc.Context(), amId, u.Id, u.Version, accounts.DefaultName())
|
||||
u, apiErr, err = accountClient.Update(tc.Context(), u.Id, u.Version, accounts.DefaultName())
|
||||
checkAccount("update", u, apiErr, err, "", 3)
|
||||
|
||||
existed, _, err := accountClient.Delete(tc.Context(), amId, u.Id)
|
||||
existed, _, err := accountClient.Delete(tc.Context(), u.Id)
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.True(existed, "Expected existing account when deleted, but it wasn't.")
|
||||
}
|
||||
|
||||
func TestAccount_CustomMethods(t *testing.T) {
|
||||
func TestCustomMethods(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
amId := token.AuthMethodId
|
||||
|
||||
accountClient := accounts.NewClient(client)
|
||||
|
||||
@@ -150,34 +143,28 @@ func TestAccount_CustomMethods(t *testing.T) {
|
||||
|
||||
acct := al[0]
|
||||
|
||||
setAcct, apiErr, err := accountClient.SetPassword(tc.Context(), amId, acct.Id, "setpassword", acct.Version)
|
||||
setAcct, apiErr, err := accountClient.SetPassword(tc.Context(), acct.Id, "setpassword", acct.Version)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(setAcct)
|
||||
assert.Equal(acct.Version+1, setAcct.Version)
|
||||
|
||||
changeAcct, apiErr, err := accountClient.ChangePassword(tc.Context(), amId, acct.Id, "setpassword", "changepassword", setAcct.Version)
|
||||
changeAcct, apiErr, err := accountClient.ChangePassword(tc.Context(), acct.Id, "setpassword", "changepassword", setAcct.Version)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(changeAcct)
|
||||
assert.Equal(setAcct.Version+1, changeAcct.Version)
|
||||
}
|
||||
|
||||
func TestAccount_Errors(t *testing.T) {
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
amId := token.AuthMethodId
|
||||
accountClient := accounts.NewClient(client)
|
||||
|
||||
u, apiErr, err := accountClient.Create(tc.Context(), amId, accounts.WithPasswordAccountLoginName("first"))
|
||||
@@ -190,17 +177,17 @@ func TestAccount_Errors(t *testing.T) {
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
_, apiErr, err = accountClient.Read(tc.Context(), amId, password.AccountPrefix+"_doesntexis")
|
||||
_, apiErr, err = accountClient.Read(tc.Context(), password.AccountPrefix+"_doesntexis")
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusForbidden, apiErr.Status)
|
||||
|
||||
_, apiErr, err = accountClient.Read(tc.Context(), amId, "invalid id")
|
||||
_, apiErr, err = accountClient.Read(tc.Context(), "invalid id")
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
|
||||
_, apiErr, err = accountClient.Update(tc.Context(), amId, u.Id, u.Version)
|
||||
_, apiErr, err = accountClient.Update(tc.Context(), u.Id, u.Version)
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
|
||||
@@ -9,10 +9,7 @@ import (
|
||||
"github.com/kr/pretty"
|
||||
)
|
||||
|
||||
func (c *Client) ChangePassword(ctx context.Context, authMethodId, accountId, oldPassword, newPassword string, version uint32, opt ...Option) (*Account, *api.Error, error) {
|
||||
if authMethodId == "" {
|
||||
return nil, nil, fmt.Errorf("empty authMethodId value passed into ChangePassword request")
|
||||
}
|
||||
func (c *Client) ChangePassword(ctx context.Context, accountId, currentPassword, newPassword string, version uint32, opt ...Option) (*Account, *api.Error, error) {
|
||||
if accountId == "" {
|
||||
return nil, nil, fmt.Errorf("empty accountId value passed into ChangePassword request")
|
||||
}
|
||||
@@ -26,7 +23,7 @@ func (c *Client) ChangePassword(ctx context.Context, authMethodId, accountId, ol
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, authMethodId, accountId, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, accountId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -40,12 +37,12 @@ func (c *Client) ChangePassword(ctx context.Context, authMethodId, accountId, ol
|
||||
}
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"version": version,
|
||||
"old_password": oldPassword,
|
||||
"new_password": newPassword,
|
||||
"version": version,
|
||||
"current_password": currentPassword,
|
||||
"new_password": newPassword,
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("auth-methods/%s/accounts/%s:change-password", authMethodId, accountId), reqBody, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("accounts/%s:change-password", accountId), reqBody, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating ChangePassword request: %w", err)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,7 @@ import (
|
||||
"github.com/kr/pretty"
|
||||
)
|
||||
|
||||
func (c *Client) SetPassword(ctx context.Context, authMethodId, accountId, password string, version uint32, opt ...Option) (*Account, *api.Error, error) {
|
||||
if authMethodId == "" {
|
||||
return nil, nil, fmt.Errorf("empty authMethodId value passed into SetPassword request")
|
||||
}
|
||||
func (c *Client) SetPassword(ctx context.Context, accountId, password string, version uint32, opt ...Option) (*Account, *api.Error, error) {
|
||||
if accountId == "" {
|
||||
return nil, nil, fmt.Errorf("empty accountId value passed into SetPassword request")
|
||||
}
|
||||
@@ -26,7 +23,7 @@ func (c *Client) SetPassword(ctx context.Context, authMethodId, accountId, passw
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, authMethodId, accountId, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, accountId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -44,7 +41,7 @@ func (c *Client) SetPassword(ctx context.Context, authMethodId, accountId, passw
|
||||
"password": password,
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("auth-methods/%s/accounts/%s:set-password", authMethodId, accountId), reqBody, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("accounts/%s:set-password", accountId), reqBody, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating SetPassword request: %w", err)
|
||||
}
|
||||
|
||||
@@ -8,9 +8,7 @@ import (
|
||||
"github.com/hashicorp/boundary/api/authtokens"
|
||||
)
|
||||
|
||||
// TODO: This will need to be changed when we add Auth Method API to boundary. We'll also need a better
|
||||
// way to handle different auth method types.
|
||||
func (c *Client) Authenticate(ctx context.Context, authMethodId, loginName, password string, opt ...Option) (*authtokens.AuthToken, *api.Error, error) {
|
||||
func (c *Client) Authenticate(ctx context.Context, authMethodId string, credentials map[string]interface{}, opt ...Option) (*authtokens.AuthToken, *api.Error, error) {
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client in Authenticate request")
|
||||
}
|
||||
@@ -18,10 +16,7 @@ func (c *Client) Authenticate(ctx context.Context, authMethodId, loginName, pass
|
||||
_, apiOpts := getOpts(opt...)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"credentials": map[string]string{
|
||||
"login_name": loginName,
|
||||
"password": password,
|
||||
},
|
||||
"credentials": credentials,
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("auth-methods/%s:authenticate", authMethodId), reqBody, apiOpts...)
|
||||
|
||||
@@ -15,22 +15,21 @@ func TestAuthenticate(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
methods := authmethods.NewClient(client)
|
||||
|
||||
tok, apiErr, err := methods.Authenticate(tc.Context(), amId, "user", "passpass")
|
||||
tok, apiErr, err := methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "passpass"})
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr, pretty.Sprint(apiErr))
|
||||
assert.NotNil(tok)
|
||||
|
||||
_, apiErr, err = methods.Authenticate(tc.Context(), amId, "user", "wrong")
|
||||
_, apiErr, err = methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "wrong"})
|
||||
require.NoError(err)
|
||||
require.NotNil(t, apiErr)
|
||||
assert.EqualValuesf(http.StatusUnauthorized, apiErr.Status, "Expected unauthenticated, got %q", apiErr.Message)
|
||||
|
||||
@@ -27,16 +27,31 @@ type AuthMethod struct {
|
||||
Attributes map[string]interface{} `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, resourceType string, opt ...Option) (*AuthMethod, *api.Error, error) {
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, resourceType string, scopeId string, opt ...Option) (*AuthMethod, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -46,10 +61,13 @@ func (c *Client) Create(ctx context.Context, resourceType string, opt ...Option)
|
||||
opts.postMap["type"] = resourceType
|
||||
}
|
||||
|
||||
opts.postMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "auth-methods", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
@@ -76,9 +94,8 @@ func (c *Client) Create(ctx context.Context, resourceType string, opt ...Option)
|
||||
|
||||
func (c *Client) Read(ctx context.Context, authMethodId string, opt ...Option) (*AuthMethod, *api.Error, error) {
|
||||
if authMethodId == "" {
|
||||
return nil, nil, fmt.Errorf("empty authMethodId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty authMethodId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -176,7 +193,6 @@ func (c *Client) Delete(ctx context.Context, authMethodId string, opt ...Option)
|
||||
if authMethodId == "" {
|
||||
return false, nil, fmt.Errorf("empty authMethodId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -215,12 +231,16 @@ func (c *Client) Delete(ctx context.Context, authMethodId string, opt ...Option)
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) List(ctx context.Context, opt ...Option) ([]*AuthMethod, *api.Error, error) {
|
||||
func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) ([]*AuthMethod, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into List request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "auth-methods", nil, apiOpts...)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"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"
|
||||
@@ -15,21 +16,41 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAuthTokens_List(t *testing.T) {
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
defer tc.Shutdown()
|
||||
|
||||
token := tc.Token()
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
client.SetToken(token.Token)
|
||||
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
amClient := authmethods.NewClient(client)
|
||||
am, apiErr, err := amClient.Create(tc.Context(), "password")
|
||||
am, apiErr, err := amClient.Create(tc.Context(), "password", org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(am)
|
||||
amId := am.Id
|
||||
amId = am.Id
|
||||
|
||||
rolesClient := roles.NewClient(client)
|
||||
role, apiErr, err := rolesClient.Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(role)
|
||||
role, apiErr, err = rolesClient.AddPrincipals(tc.Context(), role.Id, 0, []string{"u_anon"}, roles.WithAutomaticVersioning(true))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(role)
|
||||
role, apiErr, err = rolesClient.AddGrants(tc.Context(), role.Id, 0, []string{"type=auth-method;actions=authenticate"}, roles.WithAutomaticVersioning(true))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(role)
|
||||
|
||||
acctClient := accounts.NewClient(client)
|
||||
acct, apiErr, err := acctClient.Create(tc.Context(), amId, accounts.WithPasswordAccountLoginName("user"), accounts.WithPasswordAccountPassword("passpass"))
|
||||
@@ -38,32 +59,32 @@ func TestAuthTokens_List(t *testing.T) {
|
||||
require.NotNil(acct)
|
||||
|
||||
tokens := authtokens.NewClient(client)
|
||||
methods := authmethods.NewClient(client)
|
||||
|
||||
atl, apiErr, err := tokens.List(tc.Context())
|
||||
atl, apiErr, err := tokens.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.Empty(atl)
|
||||
|
||||
var expected []*authtokens.AuthToken
|
||||
methods := authmethods.NewClient(client)
|
||||
|
||||
at, apiErr, err := methods.Authenticate(tc.Context(), amId, "user", "passpass")
|
||||
at, apiErr, err := methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "passpass"})
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
expected = append(expected, at)
|
||||
|
||||
atl, apiErr, err = tokens.List(tc.Context())
|
||||
atl, apiErr, err = tokens.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(atl))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
at, apiErr, err = methods.Authenticate(tc.Context(), amId, "user", "passpass")
|
||||
at, apiErr, err = methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "passpass"})
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
expected = append(expected, at)
|
||||
}
|
||||
atl, apiErr, err = tokens.List(tc.Context())
|
||||
atl, apiErr, err = tokens.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(atl))
|
||||
@@ -92,22 +113,23 @@ func comparableSlice(in []*authtokens.AuthToken) []authtokens.AuthToken {
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestAuthToken_Crud(t *testing.T) {
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
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, apiErr, err := methods.Authenticate(tc.Context(), amId, "user", "passpass")
|
||||
want, apiErr, err := methods.Authenticate(tc.Context(), amId, map[string]interface{}{"login_name": "user", "password": "passpass"})
|
||||
require.NoError(err)
|
||||
assert.Empty(apiErr)
|
||||
|
||||
@@ -122,18 +144,14 @@ func TestAuthToken_Crud(t *testing.T) {
|
||||
assert.True(existed, "Expected existing token when deleted, but it wasn't.")
|
||||
}
|
||||
|
||||
func TestAuthToken_Errors(t *testing.T) {
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
tokens := authtokens.NewClient(client)
|
||||
|
||||
_, apiErr, err := tokens.Read(tc.Context(), authtoken.AuthTokenPrefix+"_doesntexis")
|
||||
|
||||
@@ -24,19 +24,28 @@ type AuthToken struct {
|
||||
ExpirationTime time.Time `json:"expiration_time,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Read(ctx context.Context, authTokenId string, opt ...Option) (*AuthToken, *api.Error, error) {
|
||||
if authTokenId == "" {
|
||||
return nil, nil, fmt.Errorf("empty authTokenId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty authTokenId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -76,7 +85,6 @@ func (c *Client) Delete(ctx context.Context, authTokenId string, opt ...Option)
|
||||
if authTokenId == "" {
|
||||
return false, nil, fmt.Errorf("empty authTokenId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -115,12 +123,16 @@ func (c *Client) Delete(ctx context.Context, authTokenId string, opt ...Option)
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) List(ctx context.Context, opt ...Option) ([]*AuthToken, *api.Error, error) {
|
||||
func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) ([]*AuthToken, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into List request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "auth-tokens", nil, apiOpts...)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,24 +32,15 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
+8
-69
@@ -38,7 +38,6 @@ const EnvBoundaryMaxRetries = "BOUNDARY_MAX_RETRIES"
|
||||
const EnvBoundaryToken = "BOUNDARY_TOKEN"
|
||||
const EnvBoundaryRateLimit = "BOUNDARY_RATE_LIMIT"
|
||||
const EnvBoundarySRVLookup = "BOUNDARY_SRV_LOOKUP"
|
||||
const EnvBoundaryScopeId = "BOUNDARY_SCOPE_ID"
|
||||
|
||||
// Config is used to configure the creation of the client
|
||||
type Config struct {
|
||||
@@ -97,9 +96,6 @@ type Config struct {
|
||||
|
||||
// SRVLookup enables the client to lookup the host through DNS SRV lookup
|
||||
SRVLookup bool
|
||||
|
||||
// ScopeId is the ID of the scope to use if not overridden per-call
|
||||
ScopeId string
|
||||
}
|
||||
|
||||
// TLSConfig contains the parameters needed to configure TLS on the HTTP client
|
||||
@@ -140,7 +136,6 @@ func DefaultConfig() (*Config, error) {
|
||||
HttpClient: cleanhttp.DefaultPooledClient(),
|
||||
Timeout: time.Second * 60,
|
||||
TLSConfig: &TLSConfig{},
|
||||
ScopeId: "global",
|
||||
}
|
||||
|
||||
// We read the environment now; after DefaultClient returns we can override
|
||||
@@ -215,10 +210,9 @@ func (c *Config) ConfigureTLS() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// setAddr parses a given string and looks for scope info, setting the
|
||||
// actual address to the base. Note that if a very malformed URL is passed in,
|
||||
// this may not return what one expects. For now this is on purpose to avoid
|
||||
// requiring error handling.
|
||||
// setAddr parses a given string, setting the actual address to the base. Note
|
||||
// that if a very malformed URL is passed in, this may not return what one
|
||||
// expects. For now this is on purpose to avoid requiring error handling.
|
||||
//
|
||||
// This also removes any trailing "/v1"; we'll use that in our commands so we
|
||||
// don't require it from users.
|
||||
@@ -229,11 +223,12 @@ func (c *Config) setAddr(addr string) error {
|
||||
}
|
||||
c.Addr = fmt.Sprintf("%s://%s", u.Scheme, u.Host)
|
||||
|
||||
// If there is a scopes segment, elide everything after it. Do this only for
|
||||
// the last "scopes" segment in case it's part of the base path.
|
||||
if lastIndex := strings.LastIndex(u.Path, "scopes"); lastIndex != -1 {
|
||||
// If there is a v1 segment, elide everything after it. Do this only for
|
||||
// the last v1 segment in case it's part of the base path.
|
||||
if lastIndex := strings.LastIndex(u.Path, "v1"); lastIndex != -1 {
|
||||
u.Path = u.Path[:lastIndex]
|
||||
}
|
||||
|
||||
// Remove trailing or leading slashes
|
||||
path := strings.Trim(u.Path, "/")
|
||||
// Remove v1 in front or back (e.g. they could have
|
||||
@@ -270,10 +265,6 @@ func (c *Config) ReadEnvironment() error {
|
||||
c.Token = v
|
||||
}
|
||||
|
||||
if v := os.Getenv(EnvBoundaryScopeId); v != "" {
|
||||
c.ScopeId = v
|
||||
}
|
||||
|
||||
if v := os.Getenv(EnvBoundaryMaxRetries); v != "" {
|
||||
maxRetries, err := strconv.ParseUint(v, 10, 32)
|
||||
if err != nil {
|
||||
@@ -439,23 +430,6 @@ func (c *Client) SetAddr(addr string) error {
|
||||
return c.config.setAddr(addr)
|
||||
}
|
||||
|
||||
// ScopeId fetches the scope ID the client will use by default
|
||||
func (c *Client) ScopeId() string {
|
||||
c.modifyLock.RLock()
|
||||
defer c.modifyLock.RUnlock()
|
||||
|
||||
return c.config.ScopeId
|
||||
}
|
||||
|
||||
// Sets the scope ID to use when making calls. This will apply to all calls with
|
||||
// this client unless overridden per request via WithScopeId.
|
||||
func (c *Client) SetScopeId(scopeId string) {
|
||||
c.modifyLock.Lock()
|
||||
defer c.modifyLock.Unlock()
|
||||
|
||||
c.config.ScopeId = scopeId
|
||||
}
|
||||
|
||||
// SetTLSConfig sets the TLS parameters to use and calls ConfigureTLS
|
||||
func (c *Client) SetTLSConfig(conf *TLSConfig) error {
|
||||
c.modifyLock.Lock()
|
||||
@@ -564,7 +538,6 @@ func (c *Client) Clone() *Client {
|
||||
CheckRetry: config.CheckRetry,
|
||||
Limiter: config.Limiter,
|
||||
SRVLookup: config.SRVLookup,
|
||||
ScopeId: config.ScopeId,
|
||||
}
|
||||
if config.TLSConfig != nil {
|
||||
newConfig.TLSConfig = new(TLSConfig)
|
||||
@@ -632,7 +605,6 @@ func (c *Client) NewRequest(ctx context.Context, method, requestPath string, bod
|
||||
|
||||
c.modifyLock.RLock()
|
||||
addr := c.config.Addr
|
||||
scopeId := c.config.ScopeId
|
||||
srvLookup := c.config.SRVLookup
|
||||
token := c.config.Token
|
||||
httpClient := c.config.HttpClient
|
||||
@@ -677,46 +649,13 @@ func (c *Client) NewRequest(ctx context.Context, method, requestPath string, bod
|
||||
}
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
if opts.withScopeId != "" {
|
||||
scopeId = opts.withScopeId
|
||||
}
|
||||
if scopeId == "" {
|
||||
scopeId = "global"
|
||||
}
|
||||
|
||||
var finalPath string
|
||||
switch opts.withNewStyle {
|
||||
case true:
|
||||
// Do nothing. Eventually, remove the notion of a scoped client; calls
|
||||
// to specific resources won't need it, and calls to collections can
|
||||
// take care of it in the functions themselves as part of the api
|
||||
// parameters.
|
||||
finalPath = path.Join(u.Path, "/v1/", requestPath)
|
||||
default:
|
||||
scopedPath := strings.TrimPrefix(requestPath, "/")
|
||||
switch requestPath {
|
||||
case "scopes":
|
||||
// This is a special case for creating or listing scopes; don't do
|
||||
// anything
|
||||
|
||||
default:
|
||||
// If their path already has 'scopes/' in it, use the given request path
|
||||
// instead of building it from the client's scope information
|
||||
if !strings.HasPrefix(scopedPath, "scopes/") {
|
||||
scopedPath = path.Join("scopes", scopeId, scopedPath)
|
||||
}
|
||||
}
|
||||
finalPath = path.Join(u.Path, "/v1", scopedPath)
|
||||
}
|
||||
|
||||
req := &http.Request{
|
||||
Method: method,
|
||||
URL: &url.URL{
|
||||
User: u.User,
|
||||
Scheme: u.Scheme,
|
||||
Host: host,
|
||||
Path: finalPath,
|
||||
Path: path.Join(u.Path, "/v1/", requestPath),
|
||||
},
|
||||
Host: u.Host,
|
||||
}
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ func TestConfigSetAddress(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"longer path project",
|
||||
"http://127.0.0.1:9200/v1/scopes/orgid/auth-methods",
|
||||
"http://127.0.0.1:9200/v1/auth-methods",
|
||||
"http://127.0.0.1:9200",
|
||||
"",
|
||||
},
|
||||
|
||||
+26
-6
@@ -27,24 +27,42 @@ type Group struct {
|
||||
Members []*Member `json:"members,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, opt ...Option) (*Group, *api.Error, error) {
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Group, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts.postMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "groups", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
@@ -71,9 +89,8 @@ func (c *Client) Create(ctx context.Context, opt ...Option) (*Group, *api.Error,
|
||||
|
||||
func (c *Client) Read(ctx context.Context, groupId string, opt ...Option) (*Group, *api.Error, error) {
|
||||
if groupId == "" {
|
||||
return nil, nil, fmt.Errorf("empty groupId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty groupId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -171,7 +188,6 @@ func (c *Client) Delete(ctx context.Context, groupId string, opt ...Option) (boo
|
||||
if groupId == "" {
|
||||
return false, nil, fmt.Errorf("empty groupId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -210,12 +226,16 @@ func (c *Client) Delete(ctx context.Context, groupId string, opt ...Option) (boo
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) List(ctx context.Context, opt ...Option) ([]*Group, *api.Error, error) {
|
||||
func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) ([]*Group, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into List request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "groups", nil, apiOpts...)
|
||||
if err != nil {
|
||||
|
||||
+44
-65
@@ -14,52 +14,45 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGroup_List(t *testing.T) {
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeClient *api.Client
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeClient: client,
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeClient: projClient,
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
grps := groups.NewClient(tt.scopeClient)
|
||||
pl, apiErr, err := grps.List(tc.Context())
|
||||
grps := groups.NewClient(client)
|
||||
pl, apiErr, err := grps.List(tc.Context(), tt.scopeId)
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.Empty(pl)
|
||||
|
||||
expected := make([]*groups.Group, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
expected[i], apiErr, err = grps.Create(tc.Context(), groups.WithName(fmt.Sprint(i)))
|
||||
expected[i], apiErr, err = grps.Create(tc.Context(), tt.scopeId, groups.WithName(fmt.Sprint(i)))
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
}
|
||||
pl, apiErr, err = grps.List(tc.Context())
|
||||
pl, apiErr, err = grps.List(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
require.NotNil(pl)
|
||||
@@ -84,22 +77,15 @@ func comparableSlice(in []*groups.Group) []groups.Group {
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestGroup_Crud(t *testing.T) {
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
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, apiErr *api.Error, err error, wantedName string, wantedVersion uint32, expectedUserIds []string) {
|
||||
require.NoError(err, step)
|
||||
@@ -120,31 +106,31 @@ func TestGroup_Crud(t *testing.T) {
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeClient *api.Client
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeClient: client,
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeClient: projClient,
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
user1, apiErr, err := users.NewClient(client).Create(tc.Context())
|
||||
user1, apiErr, err := users.NewClient(client).Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
user2, apiErr, err := users.NewClient(client).Create(tc.Context())
|
||||
user2, apiErr, err := users.NewClient(client).Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
groupsClient := groups.NewClient(tt.scopeClient)
|
||||
g, apiErr, err := groupsClient.Create(tc.Context(), groups.WithName("foo"))
|
||||
groupsClient := groups.NewClient(client)
|
||||
g, apiErr, err := groupsClient.Create(tc.Context(), tt.scopeId, groups.WithName("foo"))
|
||||
checkGroup("create", g, apiErr, err, "foo", 1, nil)
|
||||
|
||||
g, apiErr, err = groupsClient.Read(tc.Context(), g.Id)
|
||||
@@ -177,48 +163,41 @@ func TestGroup_Crud(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroup_Errors(t *testing.T) {
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeClient *api.Client
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeClient: client,
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeClient: projClient,
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
groupClient := groups.NewClient(tt.scopeClient)
|
||||
groupClient := groups.NewClient(client)
|
||||
|
||||
g, apiErr, err := groupClient.Create(tc.Context(), groups.WithName("first"))
|
||||
g, apiErr, err := groupClient.Create(tc.Context(), tt.scopeId, groups.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.NotNil(g)
|
||||
|
||||
// Create another resource with the same name.
|
||||
_, apiErr, err = groupClient.Create(tc.Context(), groups.WithName("first"))
|
||||
_, apiErr, err = groupClient.Create(tc.Context(), tt.scopeId, groups.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,16 +27,31 @@ type HostCatalog struct {
|
||||
Attributes map[string]interface{} `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, resourceType string, opt ...Option) (*HostCatalog, *api.Error, error) {
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, resourceType string, scopeId string, opt ...Option) (*HostCatalog, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -46,10 +61,13 @@ func (c *Client) Create(ctx context.Context, resourceType string, opt ...Option)
|
||||
opts.postMap["type"] = resourceType
|
||||
}
|
||||
|
||||
opts.postMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "host-catalogs", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
@@ -76,9 +94,8 @@ func (c *Client) Create(ctx context.Context, resourceType string, opt ...Option)
|
||||
|
||||
func (c *Client) Read(ctx context.Context, hostCatalogId string, opt ...Option) (*HostCatalog, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -176,7 +193,6 @@ func (c *Client) Delete(ctx context.Context, hostCatalogId string, opt ...Option
|
||||
if hostCatalogId == "" {
|
||||
return false, nil, fmt.Errorf("empty hostCatalogId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -215,12 +231,16 @@ func (c *Client) Delete(ctx context.Context, hostCatalogId string, opt ...Option
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) List(ctx context.Context, opt ...Option) ([]*HostCatalog, *api.Error, error) {
|
||||
func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) ([]*HostCatalog, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into List request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "host-catalogs", nil, apiOpts...)
|
||||
if err != nil {
|
||||
|
||||
@@ -14,23 +14,18 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCatalog_List(t *testing.T) {
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
catalogClient := hostcatalogs.NewClient(client)
|
||||
|
||||
ul, apiErr, err := catalogClient.List(tc.Context())
|
||||
ul, apiErr, err := catalogClient.List(tc.Context(), proj.GetPublicId())
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.Empty(ul)
|
||||
@@ -40,21 +35,21 @@ func TestCatalog_List(t *testing.T) {
|
||||
expected = append(expected, &hostcatalogs.HostCatalog{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
expected[0], apiErr, err = catalogClient.Create(tc.Context(), "static", hostcatalogs.WithName(expected[0].Name))
|
||||
expected[0], apiErr, err = catalogClient.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName(expected[0].Name))
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
|
||||
ul, apiErr, err = catalogClient.List(tc.Context())
|
||||
ul, apiErr, err = catalogClient.List(tc.Context(), proj.GetPublicId())
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableCatalogSlice(expected[:1]), comparableCatalogSlice(ul))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
expected[i], apiErr, err = catalogClient.Create(tc.Context(), "static", hostcatalogs.WithName(expected[i].Name))
|
||||
expected[i], apiErr, err = catalogClient.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName(expected[i].Name))
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
}
|
||||
ul, apiErr, err = catalogClient.List(tc.Context())
|
||||
ul, apiErr, err = catalogClient.List(tc.Context(), proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableCatalogSlice(expected), comparableCatalogSlice(ul))
|
||||
@@ -75,22 +70,15 @@ func comparableCatalogSlice(in []*hostcatalogs.HostCatalog) []hostcatalogs.HostC
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestCatalogs_Crud(t *testing.T) {
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
checkCatalog := func(step string, hc *hostcatalogs.HostCatalog, apiErr *api.Error, err error, wantedName string, wantVersion uint32) {
|
||||
require.NoError(err, step)
|
||||
@@ -106,9 +94,9 @@ func TestCatalogs_Crud(t *testing.T) {
|
||||
assert.Equal(wantVersion, hc.Version)
|
||||
}
|
||||
|
||||
hcClient := hostcatalogs.NewClient(projClient)
|
||||
hcClient := hostcatalogs.NewClient(client)
|
||||
|
||||
hc, apiErr, err := hcClient.Create(tc.Context(), "static", hostcatalogs.WithName("foo"))
|
||||
hc, apiErr, err := hcClient.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName("foo"))
|
||||
checkCatalog("create", hc, apiErr, err, "foo", 1)
|
||||
|
||||
hc, apiErr, err = hcClient.Read(tc.Context(), hc.Id)
|
||||
@@ -131,28 +119,23 @@ func TestCatalogs_Crud(t *testing.T) {
|
||||
}
|
||||
|
||||
// TODO: Get better coverage for expected errors and error formats.
|
||||
func TestCatalogs_Errors(t *testing.T) {
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
pc := hostcatalogs.NewClient(client)
|
||||
|
||||
hc, apiErr, err := pc.Create(tc.Context(), "static", hostcatalogs.WithName("foo"))
|
||||
hc, apiErr, err := pc.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName("foo"))
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.NotNil(hc)
|
||||
|
||||
_, apiErr, err = pc.Create(tc.Context(), "static", hostcatalogs.WithName("foo"))
|
||||
_, apiErr, err = pc.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName("foo"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
-25
@@ -28,27 +28,42 @@ type Host struct {
|
||||
Attributes map[string]interface{} `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, hostCatalogId string, opt ...Option) (*Host, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("host-catalogs/%s/hosts", hostCatalogId), opts.postMap, apiOpts...)
|
||||
opts.postMap["host_catalog_id"] = hostCatalogId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "hosts", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
@@ -73,22 +88,17 @@ func (c *Client) Create(ctx context.Context, hostCatalogId string, opt ...Option
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Read(ctx context.Context, hostCatalogId string, hostId string, opt ...Option) (*Host, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Read request")
|
||||
}
|
||||
|
||||
func (c *Client) Read(ctx context.Context, hostId string, opt ...Option) (*Host, *api.Error, error) {
|
||||
if hostId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty hostId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("host-catalogs/%s/hosts/%s", hostCatalogId, hostId), nil, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("hosts/%s", hostId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Read request: %w", err)
|
||||
}
|
||||
@@ -117,10 +127,7 @@ func (c *Client) Read(ctx context.Context, hostCatalogId string, hostId string,
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Update(ctx context.Context, hostCatalogId string, hostId string, version uint32, opt ...Option) (*Host, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Update request")
|
||||
}
|
||||
func (c *Client) Update(ctx context.Context, hostId string, version uint32, opt ...Option) (*Host, *api.Error, error) {
|
||||
if hostId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostId value passed into Update request")
|
||||
}
|
||||
@@ -134,7 +141,7 @@ func (c *Client) Update(ctx context.Context, hostCatalogId string, hostId string
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostCatalogId, hostId, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -149,7 +156,7 @@ func (c *Client) Update(ctx context.Context, hostCatalogId string, hostId string
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "PATCH", fmt.Sprintf("host-catalogs/%s/hosts/%s", hostCatalogId, hostId), opts.postMap, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "PATCH", fmt.Sprintf("hosts/%s", hostId), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Update request: %w", err)
|
||||
}
|
||||
@@ -178,22 +185,17 @@ func (c *Client) Update(ctx context.Context, hostCatalogId string, hostId string
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Delete(ctx context.Context, hostCatalogId string, hostId string, opt ...Option) (bool, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return false, nil, fmt.Errorf("empty hostCatalogId value passed into Delete request")
|
||||
}
|
||||
|
||||
func (c *Client) Delete(ctx context.Context, hostId string, opt ...Option) (bool, *api.Error, error) {
|
||||
if hostId == "" {
|
||||
return false, nil, fmt.Errorf("empty hostId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("host-catalogs/%s/hosts/%s", hostCatalogId, hostId), nil, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("hosts/%s", hostId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("error creating Delete request: %w", err)
|
||||
}
|
||||
@@ -229,14 +231,14 @@ func (c *Client) List(ctx context.Context, hostCatalogId string, opt ...Option)
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into List request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["host_catalog_id"] = hostCatalogId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("host-catalogs/%s/hosts", hostCatalogId), nil, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "GET", "hosts", nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating List request: %w", err)
|
||||
}
|
||||
|
||||
+26
-43
@@ -15,22 +15,17 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHost_List(t *testing.T) {
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static")
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
@@ -82,24 +77,17 @@ func comparableHostSlice(in []*hosts.Host) []hosts.Host {
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestHost_Crud(t *testing.T) {
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, apiErr, err := hostcatalogs.NewClient(projClient).Create(tc.Context(), "static")
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
@@ -118,47 +106,42 @@ func TestHost_Crud(t *testing.T) {
|
||||
assert.Equal(wantVersion, h.Version)
|
||||
}
|
||||
|
||||
hClient := hosts.NewClient(projClient)
|
||||
hClient := hosts.NewClient(client)
|
||||
|
||||
h, apiErr, err := hClient.Create(tc.Context(), hc.Id, hosts.WithName("foo"), hosts.WithStaticHostAddress("someaddress"))
|
||||
checkHost("create", h, apiErr, err, "foo", 1)
|
||||
|
||||
h, apiErr, err = hClient.Read(tc.Context(), hc.Id, h.Id)
|
||||
h, apiErr, err = hClient.Read(tc.Context(), h.Id)
|
||||
checkHost("read", h, apiErr, err, "foo", 1)
|
||||
|
||||
h, apiErr, err = hClient.Update(tc.Context(), hc.Id, h.Id, h.Version, hosts.WithName("bar"))
|
||||
h, apiErr, err = hClient.Update(tc.Context(), h.Id, h.Version, hosts.WithName("bar"))
|
||||
checkHost("update", h, apiErr, err, "bar", 2)
|
||||
|
||||
h, apiErr, err = hClient.Update(tc.Context(), hc.Id, h.Id, h.Version, hosts.DefaultName())
|
||||
h, apiErr, err = hClient.Update(tc.Context(), h.Id, h.Version, hosts.DefaultName())
|
||||
checkHost("update", h, apiErr, err, "", 3)
|
||||
|
||||
existed, apiErr, err := hClient.Delete(tc.Context(), hc.Id, h.Id)
|
||||
existed, apiErr, err := hClient.Delete(tc.Context(), h.Id)
|
||||
assert.NoError(err)
|
||||
assert.True(existed, "Expected existing catalog when deleted, but it wasn't.")
|
||||
|
||||
existed, apiErr, err = hClient.Delete(tc.Context(), hc.Id, h.Id)
|
||||
existed, apiErr, err = hClient.Delete(tc.Context(), h.Id)
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusForbidden, apiErr.Status)
|
||||
}
|
||||
|
||||
// TODO: Get better coverage for expected errors and error formats.
|
||||
func TestHost_Errors(t *testing.T) {
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static")
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
@@ -174,12 +157,12 @@ func TestHost_Errors(t *testing.T) {
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
_, apiErr, err = hClient.Read(tc.Context(), hc.Id, static.HostPrefix+"_doesntexis")
|
||||
_, apiErr, err = hClient.Read(tc.Context(), static.HostPrefix+"_doesntexis")
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(apiErr.Status, http.StatusForbidden)
|
||||
|
||||
_, apiErr, err = hClient.Read(tc.Context(), hc.Id, "invalid id")
|
||||
_, apiErr, err = hClient.Read(tc.Context(), "invalid id")
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
|
||||
+2
-12
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-448
@@ -28,252 +28,31 @@ type HostSet struct {
|
||||
Attributes map[string]interface{} `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, hostCatalogId string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Create request")
|
||||
}
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("host-catalogs/%s/host-sets", hostCatalogId), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create 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, nil, fmt.Errorf("error performing client request during Create call: %w", err)
|
||||
}
|
||||
|
||||
target := new(HostSet)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding Create response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Read(ctx context.Context, hostCatalogId string, hostSetId string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Read request")
|
||||
}
|
||||
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("host-catalogs/%s/host-sets/%s", hostCatalogId, hostSetId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, 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, nil, fmt.Errorf("error performing client request during Read call: %w", err)
|
||||
}
|
||||
|
||||
target := new(HostSet)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding Read response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Update(ctx context.Context, hostCatalogId string, hostSetId string, version uint32, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Update request")
|
||||
}
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into Update request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostCatalogId, hostSetId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingApiErr != nil {
|
||||
return nil, nil, fmt.Errorf("error from controller when performing initial check-and-set read: %s", pretty.Sprint(existingApiErr))
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Version
|
||||
}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "PATCH", fmt.Sprintf("host-catalogs/%s/host-sets/%s", hostCatalogId, hostSetId), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, 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, nil, fmt.Errorf("error performing client request during Update call: %w", err)
|
||||
}
|
||||
|
||||
target := new(HostSet)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding Update response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Delete(ctx context.Context, hostCatalogId string, hostSetId string, opt ...Option) (bool, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return false, nil, fmt.Errorf("empty hostCatalogId value passed into Delete request")
|
||||
}
|
||||
|
||||
if hostSetId == "" {
|
||||
return false, nil, fmt.Errorf("empty hostSetId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("host-catalogs/%s/host-sets/%s", hostCatalogId, hostSetId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
return false, 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 false, nil, fmt.Errorf("error performing client request during Delete call: %w", err)
|
||||
}
|
||||
|
||||
type deleteResponse struct {
|
||||
Existed bool
|
||||
}
|
||||
target := &deleteResponse{}
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("error decoding Delete response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return false, apiErr, nil
|
||||
}
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) List(ctx context.Context, hostCatalogId string, opt ...Option) ([]*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into List request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("host-catalogs/%s/host-sets", hostCatalogId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating List 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, nil, fmt.Errorf("error performing client request during List call: %w", err)
|
||||
}
|
||||
|
||||
type listResponse struct {
|
||||
Items []*HostSet
|
||||
}
|
||||
target := &listResponse{}
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding List response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target.Items, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Create2(ctx context.Context, hostCatalogId string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into Create request")
|
||||
}
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -309,7 +88,7 @@ func (c *Client) Create2(ctx context.Context, hostCatalogId string, opt ...Optio
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Read2(ctx context.Context, hostSetId string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
func (c *Client) Read(ctx context.Context, hostSetId string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into Read request")
|
||||
}
|
||||
@@ -318,7 +97,6 @@ func (c *Client) Read2(ctx context.Context, hostSetId string, opt ...Option) (*H
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("host-sets/%s", hostSetId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
@@ -349,7 +127,7 @@ func (c *Client) Read2(ctx context.Context, hostSetId string, opt ...Option) (*H
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Update2(ctx context.Context, hostSetId string, version uint32, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
func (c *Client) Update(ctx context.Context, hostSetId string, version uint32, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into Update request")
|
||||
}
|
||||
@@ -358,13 +136,12 @@ func (c *Client) Update2(ctx context.Context, hostSetId string, version uint32,
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read2(ctx, hostSetId, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostSetId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -408,7 +185,7 @@ func (c *Client) Update2(ctx context.Context, hostSetId string, version uint32,
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) Delete2(ctx context.Context, hostSetId string, opt ...Option) (bool, *api.Error, error) {
|
||||
func (c *Client) Delete(ctx context.Context, hostSetId string, opt ...Option) (bool, *api.Error, error) {
|
||||
if hostSetId == "" {
|
||||
return false, nil, fmt.Errorf("empty hostSetId value passed into Delete request")
|
||||
}
|
||||
@@ -417,7 +194,6 @@ func (c *Client) Delete2(ctx context.Context, hostSetId string, opt ...Option) (
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("host-sets/%s", hostSetId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
@@ -451,7 +227,7 @@ func (c *Client) Delete2(ctx context.Context, hostSetId string, opt ...Option) (
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) List2(ctx context.Context, hostCatalogId string, opt ...Option) ([]*HostSet, *api.Error, error) {
|
||||
func (c *Client) List(ctx context.Context, hostCatalogId string, opt ...Option) ([]*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into List request")
|
||||
}
|
||||
@@ -460,7 +236,6 @@ func (c *Client) List2(ctx context.Context, hostCatalogId string, opt ...Option)
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
opts.queryMap["host_catalog_id"] = hostCatalogId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "host-sets", nil, apiOpts...)
|
||||
@@ -495,10 +270,7 @@ func (c *Client) List2(ctx context.Context, hostCatalogId string, opt ...Option)
|
||||
return target.Items, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) AddHosts(ctx context.Context, hostCatalogId string, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into AddHosts request")
|
||||
}
|
||||
func (c *Client) AddHosts(ctx context.Context, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into AddHosts request")
|
||||
}
|
||||
@@ -512,203 +284,7 @@ func (c *Client) AddHosts(ctx context.Context, hostCatalogId string, hostSetId s
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into AddHosts request")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostCatalogId, hostSetId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingApiErr != nil {
|
||||
return nil, nil, fmt.Errorf("error from controller when performing initial check-and-set read: %s", pretty.Sprint(existingApiErr))
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Version
|
||||
}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
if len(hostIds) > 0 {
|
||||
opts.postMap["host_ids"] = hostIds
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("host-catalogs/%s/host-sets/%s:add-hosts", hostCatalogId, hostSetId), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating AddHosts 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, nil, fmt.Errorf("error performing client request during AddHosts call: %w", err)
|
||||
}
|
||||
|
||||
target := new(HostSet)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding AddHosts response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) SetHosts(ctx context.Context, hostCatalogId string, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into SetHosts request")
|
||||
}
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into SetHosts request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into SetHosts request")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostCatalogId, hostSetId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingApiErr != nil {
|
||||
return nil, nil, fmt.Errorf("error from controller when performing initial check-and-set read: %s", pretty.Sprint(existingApiErr))
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Version
|
||||
}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
if len(hostIds) > 0 {
|
||||
opts.postMap["host_ids"] = hostIds
|
||||
} else if hostIds != nil {
|
||||
// In this function, a non-nil but empty list means clear out
|
||||
opts.postMap["host_ids"] = nil
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("host-catalogs/%s/host-sets/%s:set-hosts", hostCatalogId, hostSetId), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating SetHosts 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, nil, fmt.Errorf("error performing client request during SetHosts call: %w", err)
|
||||
}
|
||||
|
||||
target := new(HostSet)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding SetHosts response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) RemoveHosts(ctx context.Context, hostCatalogId string, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostCatalogId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostCatalogId value passed into RemoveHosts request")
|
||||
}
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into RemoveHosts request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into RemoveHosts request")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostCatalogId, hostSetId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingApiErr != nil {
|
||||
return nil, nil, fmt.Errorf("error from controller when performing initial check-and-set read: %s", pretty.Sprint(existingApiErr))
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Version
|
||||
}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
if len(hostIds) > 0 {
|
||||
opts.postMap["host_ids"] = hostIds
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("host-catalogs/%s/host-sets/%s:remove-hosts", hostCatalogId, hostSetId), opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating RemoveHosts 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, nil, fmt.Errorf("error performing client request during RemoveHosts call: %w", err)
|
||||
}
|
||||
|
||||
target := new(HostSet)
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding RemoveHosts response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) AddHosts2(ctx context.Context, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into AddHosts request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into AddHosts request")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read2(ctx, hostSetId, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostSetId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -756,7 +332,7 @@ func (c *Client) AddHosts2(ctx context.Context, hostSetId string, version uint32
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) SetHosts2(ctx context.Context, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
func (c *Client) SetHosts(ctx context.Context, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into SetHosts request")
|
||||
}
|
||||
@@ -765,13 +341,12 @@ func (c *Client) SetHosts2(ctx context.Context, hostSetId string, version uint32
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into SetHosts request")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read2(ctx, hostSetId, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostSetId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -822,7 +397,7 @@ func (c *Client) SetHosts2(ctx context.Context, hostSetId string, version uint32
|
||||
return target, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) RemoveHosts2(ctx context.Context, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
func (c *Client) RemoveHosts(ctx context.Context, hostSetId string, version uint32, hostIds []string, opt ...Option) (*HostSet, *api.Error, error) {
|
||||
if hostSetId == "" {
|
||||
return nil, nil, fmt.Errorf("empty hostSetId value passed into RemoveHosts request")
|
||||
}
|
||||
@@ -831,13 +406,12 @@ func (c *Client) RemoveHosts2(ctx context.Context, hostSetId string, version uin
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into RemoveHosts request")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read2(ctx, hostSetId, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, hostSetId, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
|
||||
+153
-236
@@ -18,129 +18,95 @@ import (
|
||||
)
|
||||
|
||||
func TestCustom(t *testing.T) {
|
||||
for _, newStyle := range []bool{false, true} {
|
||||
t.Run(fmt.Sprintf("custom_%t", newStyle), func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
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.SetScopeId(proj.GetPublicId())
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static")
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
hClient := hosts.NewClient(client)
|
||||
h1, apiErr, err := hClient.Create(tc.Context(), hc.Id, hosts.WithStaticHostAddress("someaddress"))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
h2, apiErr, err := hClient.Create(tc.Context(), hc.Id, hosts.WithStaticHostAddress("someaddress"))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
hClient := hosts.NewClient(client)
|
||||
h1, apiErr, err := hClient.Create(tc.Context(), hc.Id, hosts.WithStaticHostAddress("someaddress"))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
h2, apiErr, err := hClient.Create(tc.Context(), hc.Id, hosts.WithStaticHostAddress("someaddress"))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
hSetClient := hostsets.NewClient(client)
|
||||
var hSet *hostsets.HostSet
|
||||
if newStyle {
|
||||
hSet, apiErr, err = hSetClient.Create2(tc.Context(), hc.Id)
|
||||
} else {
|
||||
hSet, apiErr, err = hSetClient.Create(tc.Context(), hc.Id)
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
hSetClient := hostsets.NewClient(client)
|
||||
var hSet *hostsets.HostSet
|
||||
hSet, apiErr, err = hSetClient.Create(tc.Context(), hc.Id)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
if newStyle {
|
||||
hSet, apiErr, err = hSetClient.AddHosts2(tc.Context(), hSet.Id, hSet.Version, []string{h1.Id, h2.Id})
|
||||
} else {
|
||||
hSet, apiErr, err = hSetClient.AddHosts(tc.Context(), hc.Id, hSet.Id, hSet.Version, []string{h1.Id, h2.Id})
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.Contains(hSet.HostIds, h1.Id, h2.Id)
|
||||
hSet, apiErr, err = hSetClient.AddHosts(tc.Context(), hSet.Id, hSet.Version, []string{h1.Id, h2.Id})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.Contains(hSet.HostIds, h1.Id, h2.Id)
|
||||
|
||||
if newStyle {
|
||||
hSet, apiErr, err = hSetClient.SetHosts2(tc.Context(), hSet.Id, hSet.Version, []string{h1.Id})
|
||||
} else {
|
||||
hSet, apiErr, err = hSetClient.SetHosts(tc.Context(), hc.Id, hSet.Id, hSet.Version, []string{h1.Id})
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr, pretty.Sprint(apiErr))
|
||||
assert.ElementsMatch([]string{h1.Id}, hSet.HostIds)
|
||||
hSet, apiErr, err = hSetClient.SetHosts(tc.Context(), hSet.Id, hSet.Version, []string{h1.Id})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr, pretty.Sprint(apiErr))
|
||||
assert.ElementsMatch([]string{h1.Id}, hSet.HostIds)
|
||||
|
||||
if newStyle {
|
||||
hSet, apiErr, err = hSetClient.RemoveHosts2(tc.Context(), hSet.Id, hSet.Version, []string{h1.Id})
|
||||
} else {
|
||||
hSet, apiErr, err = hSetClient.RemoveHosts(tc.Context(), hc.Id, hSet.Id, hSet.Version, []string{h1.Id})
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.Empty(hSet.HostIds)
|
||||
})
|
||||
}
|
||||
hSet, apiErr, err = hSetClient.RemoveHosts(tc.Context(), hSet.Id, hSet.Version, []string{h1.Id})
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.Empty(hSet.HostIds)
|
||||
}
|
||||
|
||||
func TestSet_List(t *testing.T) {
|
||||
for _, newStyle := range []bool{false, true} {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
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()
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
client.SetScopeId(proj.GetPublicId())
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static")
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
|
||||
hClient := hostsets.NewClient(client)
|
||||
var ul []*hostsets.HostSet
|
||||
hClient := hostsets.NewClient(client)
|
||||
var ul []*hostsets.HostSet
|
||||
|
||||
if newStyle {
|
||||
ul, apiErr, err = hClient.List2(tc.Context(), hc.Id)
|
||||
} else {
|
||||
ul, apiErr, err = hClient.List(tc.Context(), hc.Id)
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.Empty(ul)
|
||||
ul, apiErr, err = hClient.List(tc.Context(), hc.Id)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.Empty(ul)
|
||||
|
||||
var expected []*hostsets.HostSet
|
||||
for i := 0; i < 10; i++ {
|
||||
expected = append(expected, &hostsets.HostSet{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
expected[0], apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName(expected[0].Name))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
if newStyle {
|
||||
ul, apiErr, err = hClient.List2(tc.Context(), hc.Id)
|
||||
} else {
|
||||
ul, apiErr, err = hClient.List(tc.Context(), hc.Id)
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSetSlice(expected[:1]), comparableSetSlice(ul))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
expected[i], apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName(expected[i].Name))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
}
|
||||
if newStyle {
|
||||
ul, apiErr, err = hClient.List2(tc.Context(), hc.Id)
|
||||
} else {
|
||||
ul, apiErr, err = hClient.List(tc.Context(), hc.Id)
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSetSlice(expected), comparableSetSlice(ul))
|
||||
var expected []*hostsets.HostSet
|
||||
for i := 0; i < 10; i++ {
|
||||
expected = append(expected, &hostsets.HostSet{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
expected[0], apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName(expected[0].Name))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
ul, apiErr, err = hClient.List(tc.Context(), hc.Id)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSetSlice(expected[:1]), comparableSetSlice(ul))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
expected[i], apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName(expected[i].Name))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
}
|
||||
ul, apiErr, err = hClient.List(tc.Context(), hc.Id)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSetSlice(expected), comparableSetSlice(ul))
|
||||
}
|
||||
|
||||
func comparableSetSlice(in []*hostsets.HostSet) []hostsets.HostSet {
|
||||
@@ -158,146 +124,97 @@ func comparableSetSlice(in []*hostsets.HostSet) []hostsets.HostSet {
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestSet_Crud(t *testing.T) {
|
||||
for _, newStyle := range []bool{false, true} {
|
||||
t.Run(fmt.Sprintf("crud_%t", newStyle), func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
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()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, apiErr, err := hostcatalogs.NewClient(projClient).Create(tc.Context(), "static")
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
|
||||
checkHost := func(t *testing.T, step string, h *hostsets.HostSet, apiErr *api.Error, err error, wantedName string, wantVersion uint32) {
|
||||
t.Helper()
|
||||
require.NoError(err, step)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != "" {
|
||||
t.Errorf("ApiError message: %q", apiErr.Message)
|
||||
}
|
||||
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(projClient)
|
||||
|
||||
var h *hostsets.HostSet
|
||||
if newStyle {
|
||||
h, apiErr, err = hClient.Create2(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
} else {
|
||||
h, apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
}
|
||||
checkHost(t, "create", h, apiErr, err, "foo", 1)
|
||||
|
||||
if newStyle {
|
||||
h, apiErr, err = hClient.Read2(tc.Context(), h.Id)
|
||||
} else {
|
||||
h, apiErr, err = hClient.Read(tc.Context(), hc.Id, h.Id)
|
||||
}
|
||||
checkHost(t, "read", h, apiErr, err, "foo", 1)
|
||||
|
||||
if newStyle {
|
||||
h, apiErr, err = hClient.Update2(tc.Context(), h.Id, h.Version, hostsets.WithName("bar"))
|
||||
} else {
|
||||
h, apiErr, err = hClient.Update(tc.Context(), hc.Id, h.Id, h.Version, hostsets.WithName("bar"))
|
||||
}
|
||||
checkHost(t, "update", h, apiErr, err, "bar", 2)
|
||||
|
||||
if newStyle {
|
||||
h, apiErr, err = hClient.Update2(tc.Context(), h.Id, h.Version, hostsets.DefaultName())
|
||||
} else {
|
||||
h, apiErr, err = hClient.Update(tc.Context(), hc.Id, h.Id, h.Version, hostsets.DefaultName())
|
||||
}
|
||||
checkHost(t, "update", h, apiErr, err, "", 3)
|
||||
|
||||
var existed bool
|
||||
if newStyle {
|
||||
existed, apiErr, err = hClient.Delete2(tc.Context(), h.Id)
|
||||
} else {
|
||||
existed, apiErr, err = hClient.Delete(tc.Context(), hc.Id, h.Id)
|
||||
}
|
||||
assert.NoError(err)
|
||||
assert.True(existed, "Expected existing catalog when deleted, but it wasn't.")
|
||||
|
||||
if newStyle {
|
||||
existed, apiErr, err = hClient.Delete2(tc.Context(), h.Id)
|
||||
} else {
|
||||
existed, apiErr, err = hClient.Delete(tc.Context(), hc.Id, h.Id)
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusForbidden, apiErr.Status)
|
||||
})
|
||||
checkHost := func(t *testing.T, step string, h *hostsets.HostSet, apiErr *api.Error, err error, wantedName string, wantVersion uint32) {
|
||||
t.Helper()
|
||||
require.NoError(err, step)
|
||||
if !assert.Nil(apiErr, step) && apiErr.Message != "" {
|
||||
t.Errorf("ApiError message: %q", apiErr.Message)
|
||||
}
|
||||
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)
|
||||
|
||||
var h *hostsets.HostSet
|
||||
h, apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
checkHost(t, "create", h, apiErr, err, "foo", 1)
|
||||
|
||||
h, apiErr, err = hClient.Read(tc.Context(), h.Id)
|
||||
checkHost(t, "read", h, apiErr, err, "foo", 1)
|
||||
|
||||
h, apiErr, err = hClient.Update(tc.Context(), h.Id, h.Version, hostsets.WithName("bar"))
|
||||
checkHost(t, "update", h, apiErr, err, "bar", 2)
|
||||
|
||||
h, apiErr, err = hClient.Update(tc.Context(), h.Id, h.Version, hostsets.DefaultName())
|
||||
checkHost(t, "update", h, apiErr, err, "", 3)
|
||||
|
||||
var existed bool
|
||||
existed, apiErr, err = hClient.Delete(tc.Context(), h.Id)
|
||||
assert.NoError(err)
|
||||
assert.True(existed, "Expected existing catalog when deleted, but it wasn't.")
|
||||
existed, apiErr, err = hClient.Delete(tc.Context(), h.Id)
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusForbidden, apiErr.Status)
|
||||
}
|
||||
|
||||
// TODO: Get better coverage for expected errors and error formats.
|
||||
func TestSet_Errors(t *testing.T) {
|
||||
for _, newStyle := range []bool{false, true} {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
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()
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
client.SetScopeId(proj.GetPublicId())
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static")
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hc)
|
||||
|
||||
hClient := hostsets.NewClient(client)
|
||||
hClient := hostsets.NewClient(client)
|
||||
|
||||
var h *hostsets.HostSet
|
||||
if newStyle {
|
||||
h, apiErr, err = hClient.Create2(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
} else {
|
||||
h, apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.NotNil(h)
|
||||
var h *hostsets.HostSet
|
||||
h, apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
assert.NotNil(h)
|
||||
|
||||
if newStyle {
|
||||
h, apiErr, err = hClient.Create2(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
} else {
|
||||
h, apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.Nil(h)
|
||||
h, apiErr, err = hClient.Create(tc.Context(), hc.Id, hostsets.WithName("foo"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.Nil(h)
|
||||
|
||||
if newStyle {
|
||||
_, apiErr, err = hClient.Read2(tc.Context(), static.HostSetPrefix+"_doesntexis")
|
||||
} else {
|
||||
_, apiErr, err = hClient.Read(tc.Context(), hc.Id, static.HostSetPrefix+"_doesntexis")
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusForbidden, apiErr.Status)
|
||||
_, apiErr, err = hClient.Read(tc.Context(), static.HostSetPrefix+"_doesntexis")
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusForbidden, apiErr.Status)
|
||||
|
||||
if newStyle {
|
||||
_, apiErr, err = hClient.Read2(tc.Context(), "invalid id")
|
||||
} else {
|
||||
_, apiErr, err = hClient.Read(tc.Context(), hc.Id, "invalid id")
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
_, apiErr, err = hClient.Read(tc.Context(), "invalid id")
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
|
||||
}
|
||||
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,10 @@ type structInfo struct {
|
||||
// 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
|
||||
@@ -76,10 +80,6 @@ type structInfo struct {
|
||||
// given type, e.g. arguments only valid for one call or purpose and not
|
||||
// conveyed within the item itself
|
||||
extraOptions []fieldInfo
|
||||
|
||||
useNewStyle bool
|
||||
|
||||
disableOldStyle bool
|
||||
}
|
||||
|
||||
var inputStructs = []*structInfo{
|
||||
@@ -231,7 +231,8 @@ var inputStructs = []*structInfo{
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"auth-method", "account"},
|
||||
pathArgs: []string{"account"},
|
||||
parentTypeName: "auth-method",
|
||||
versionEnabled: true,
|
||||
},
|
||||
{
|
||||
@@ -278,7 +279,8 @@ var inputStructs = []*structInfo{
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"host-catalog", "host"},
|
||||
pathArgs: []string{"host"},
|
||||
parentTypeName: "host-catalog",
|
||||
versionEnabled: true,
|
||||
},
|
||||
{
|
||||
@@ -296,18 +298,13 @@ var inputStructs = []*structInfo{
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
createTemplate2,
|
||||
readTemplate2,
|
||||
updateTemplate2,
|
||||
deleteTemplate2,
|
||||
listTemplate2,
|
||||
},
|
||||
pathArgs: []string{"host-catalog", "host-set"},
|
||||
pathArgs: []string{"host-set"},
|
||||
parentTypeName: "host-catalog",
|
||||
sliceSubTypes: map[string]string{
|
||||
"Hosts": "hostIds",
|
||||
},
|
||||
versionEnabled: true,
|
||||
useNewStyle: true,
|
||||
},
|
||||
{
|
||||
inProto: &targets.HostSet{},
|
||||
@@ -318,19 +315,17 @@ var inputStructs = []*structInfo{
|
||||
outFile: "targets/target.gen.go",
|
||||
templates: []*template.Template{
|
||||
clientTemplate,
|
||||
createTemplate2,
|
||||
readTemplate2,
|
||||
updateTemplate2,
|
||||
deleteTemplate2,
|
||||
listTemplate2,
|
||||
createTemplate,
|
||||
readTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
listTemplate,
|
||||
},
|
||||
pathArgs: []string{"target"},
|
||||
sliceSubTypes: map[string]string{
|
||||
"HostSets": "hostSetIds",
|
||||
},
|
||||
versionEnabled: true,
|
||||
typeOnCreate: true,
|
||||
useNewStyle: true,
|
||||
disableOldStyle: true,
|
||||
versionEnabled: true,
|
||||
typeOnCreate: true,
|
||||
},
|
||||
}
|
||||
@@ -39,32 +39,17 @@ func toPath(segments []string, action string) string {
|
||||
return fmt.Sprintf("fmt.Sprintf(\"%s%s\", %s)", strings.Join(printfString, "/"), action, strings.Join(printfArg, ", "))
|
||||
}
|
||||
|
||||
func getArgsAndPaths(in []string, action string) (colArgs, resArgs []string, colPath, resPath string) {
|
||||
var argNames, pathSegment []string
|
||||
for _, s := range in {
|
||||
varName := fmt.Sprintf("%sId", strcase.ToLowerCamel(strings.ReplaceAll(s, "-", "_")))
|
||||
collectionName := fmt.Sprintf("%ss", s)
|
||||
|
||||
argNames = append(argNames, varName)
|
||||
pathSegment = append(pathSegment, collectionName, varName)
|
||||
}
|
||||
|
||||
colArgs, resArgs, colPath, resPath = argNames[:len(argNames)-1], argNames, toPath(pathSegment[:len(pathSegment)-1], action), toPath(pathSegment, action)
|
||||
|
||||
// Scopes create and list operations always need scope ID
|
||||
if colPath == `"scopes"` {
|
||||
colArgs = append(colArgs, "scopeId")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getArgsAndPathsNewStyle(in []string, action string) (colArg, resArg string, colPath, resPath string) {
|
||||
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 {
|
||||
colArg = "scopeId"
|
||||
if parentTypeName != "" {
|
||||
strToReplace = parentTypeName
|
||||
}
|
||||
} else {
|
||||
colArg = fmt.Sprintf("%sId", strcase.ToLowerCamel(strings.ReplaceAll(in[len(in)-2], "-", "_")))
|
||||
strToReplace = in[len(in)-2]
|
||||
}
|
||||
colArg = fmt.Sprintf("%sId", strcase.ToLowerCamel(strings.ReplaceAll(strToReplace, "-", "_")))
|
||||
colPath = fmt.Sprintf("%ss", in[len(in)-1])
|
||||
|
||||
if action != "" {
|
||||
@@ -75,23 +60,19 @@ func getArgsAndPathsNewStyle(in []string, action string) (colArg, resArg string,
|
||||
}
|
||||
|
||||
type templateInput struct {
|
||||
Name string
|
||||
Package string
|
||||
Fields []fieldInfo
|
||||
PathArgs []string
|
||||
CollectionFunctionArgs []string
|
||||
ResourceFunctionArgs []string
|
||||
CollectionPath string
|
||||
ResourcePath string
|
||||
CollectionFunctionArg2 string
|
||||
ResourceFunctionArg2 string
|
||||
CollectionPath2 string
|
||||
ResourcePath2 string
|
||||
SliceSubTypes map[string]string
|
||||
ExtraOptions []fieldInfo
|
||||
VersionEnabled bool
|
||||
TypeOnCreate bool
|
||||
Two string
|
||||
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
|
||||
}
|
||||
|
||||
func fillTemplates() {
|
||||
@@ -103,19 +84,14 @@ func fillTemplates() {
|
||||
Package: in.generatedStructure.pkg,
|
||||
Fields: in.generatedStructure.fields,
|
||||
PathArgs: in.pathArgs,
|
||||
ParentTypeName: in.parentTypeName,
|
||||
ExtraOptions: in.extraOptions,
|
||||
VersionEnabled: in.versionEnabled,
|
||||
TypeOnCreate: in.typeOnCreate,
|
||||
Two: "2",
|
||||
}
|
||||
|
||||
if in.useNewStyle && in.disableOldStyle {
|
||||
input.Two = ""
|
||||
}
|
||||
|
||||
if len(in.pathArgs) > 0 {
|
||||
input.CollectionFunctionArgs, input.ResourceFunctionArgs, input.CollectionPath, input.ResourcePath = getArgsAndPaths(in.pathArgs, "")
|
||||
input.CollectionFunctionArg2, input.ResourceFunctionArg2, input.CollectionPath2, input.ResourcePath2 = getArgsAndPathsNewStyle(in.pathArgs, "")
|
||||
input.CollectionFunctionArg, input.ResourceFunctionArg, input.CollectionPath, input.ResourcePath = getArgsAndPaths(in.pathArgs, in.parentTypeName, "")
|
||||
}
|
||||
|
||||
if err := structTemplate.Execute(outBuf, input); err != nil {
|
||||
@@ -125,12 +101,7 @@ func fillTemplates() {
|
||||
|
||||
if len(in.sliceSubTypes) > 0 {
|
||||
input.SliceSubTypes = in.sliceSubTypes
|
||||
if !in.disableOldStyle {
|
||||
in.templates = append(in.templates, sliceSubTypeTemplate)
|
||||
}
|
||||
if in.useNewStyle {
|
||||
in.templates = append(in.templates, sliceSubTypeTemplate2)
|
||||
}
|
||||
in.templates = append(in.templates, sliceSubTypeTemplate)
|
||||
}
|
||||
|
||||
for _, t := range in.templates {
|
||||
@@ -229,24 +200,23 @@ func fillTemplates() {
|
||||
}
|
||||
}
|
||||
|
||||
var listTemplate2 = template.Must(template.New("").Funcs(
|
||||
var listTemplate = template.Must(template.New("").Funcs(
|
||||
template.FuncMap{
|
||||
"snakeCase": snakeCase,
|
||||
},
|
||||
).Parse(`
|
||||
func (c *Client) List{{ .Two }}(ctx context.Context, {{ .CollectionFunctionArg2 }} string, opt... Option) ([]*{{ .Name }}, *api.Error, error) {
|
||||
if {{ .CollectionFunctionArg2 }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ .CollectionFunctionArg2 }} value passed into List request")
|
||||
func (c *Client) List(ctx context.Context, {{ .CollectionFunctionArg }} string, opt... Option) ([]*{{ .Name }}, *api.Error, error) {
|
||||
if {{ .CollectionFunctionArg }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ .CollectionFunctionArg }} value passed into List request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
opts.queryMap["{{ snakeCase .CollectionFunctionArg2 }}"] = {{ .CollectionFunctionArg2 }}
|
||||
opts.queryMap["{{ snakeCase .CollectionFunctionArg }}"] = {{ .CollectionFunctionArg }}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "{{ .CollectionPath2 }}", nil, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "GET", "{{ .CollectionPath }}", nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating List request: %w", err)
|
||||
}
|
||||
@@ -281,101 +251,11 @@ func (c *Client) List{{ .Two }}(ctx context.Context, {{ .CollectionFunctionArg2
|
||||
}
|
||||
`))
|
||||
|
||||
var listTemplate = template.Must(template.New("").Parse(`
|
||||
func (c *Client) List(ctx context.Context, {{ range .CollectionFunctionArgs }} {{ . }} string, {{ end }}opt... Option) ([]*{{ .Name }}, *api.Error, error) { {{ range .CollectionFunctionArgs }}
|
||||
if {{ . }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ . }} value passed into List request")
|
||||
}
|
||||
{{ end }}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", {{ .CollectionPath }}, nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, 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, nil, fmt.Errorf("error performing client request during List call: %w", err)
|
||||
}
|
||||
|
||||
type listResponse struct {
|
||||
Items []*{{ .Name }}
|
||||
}
|
||||
target := &listResponse{}
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding List response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target.Items, apiErr, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var readTemplate2 = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Read{{ .Two }}(ctx context.Context, {{ .ResourceFunctionArg2 }} string, opt... Option) (*{{ .Name }}, *api.Error, error) {
|
||||
if {{ .ResourceFunctionArg2 }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ .ResourceFunctionArg2 }} value passed into Read request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", {{ .ResourcePath2 }}, nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, 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, nil, fmt.Errorf("error performing client request during Read call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ .Name }})
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding Read response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var readTemplate = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Read(ctx context.Context, {{ range .ResourceFunctionArgs }} {{ . }} string, {{ end }} opt... Option) (*{{ .Name }}, *api.Error, error) { {{ range .ResourceFunctionArgs }}
|
||||
if {{ . }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ . }} value passed into Read request")
|
||||
func (c *Client) Read(ctx context.Context, {{ .ResourceFunctionArg }} string, opt... Option) (*{{ .Name }}, *api.Error, error) {
|
||||
if {{ .ResourceFunctionArg }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ .ResourceFunctionArg }} value passed into Read request")
|
||||
}
|
||||
{{ end }}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -412,57 +292,11 @@ func (c *Client) Read(ctx context.Context, {{ range .ResourceFunctionArgs }} {{
|
||||
}
|
||||
`))
|
||||
|
||||
var deleteTemplate2 = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Delete{{ .Two }}(ctx context.Context, {{ .ResourceFunctionArg2 }} string, opt... Option) (bool, *api.Error, error) {
|
||||
if {{ .ResourceFunctionArg2 }} == "" {
|
||||
return false, nil, fmt.Errorf("empty {{ .ResourceFunctionArg2 }} value passed into Delete request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", {{ .ResourcePath2 }}, nil, apiOpts...)
|
||||
if err != nil {
|
||||
return false, 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 false, nil, fmt.Errorf("error performing client request during Delete call: %w", err)
|
||||
}
|
||||
|
||||
type deleteResponse struct {
|
||||
Existed bool
|
||||
}
|
||||
target := &deleteResponse{}
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("error decoding Delete response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return false, apiErr, nil
|
||||
}
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var deleteTemplate = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Delete(ctx context.Context, {{ range .ResourceFunctionArgs }} {{ . }} string, {{ end }} opt... Option) (bool, *api.Error, error) { {{ range .ResourceFunctionArgs }}
|
||||
if {{ . }} == "" {
|
||||
return false, nil, fmt.Errorf("empty {{ . }} value passed into Delete request")
|
||||
func (c *Client) Delete(ctx context.Context, {{ .ResourceFunctionArg }} string, opt... Option) (bool, *api.Error, error) {
|
||||
if {{ .ResourceFunctionArg }} == "" {
|
||||
return false, nil, fmt.Errorf("empty {{ .ResourceFunctionArg }} value passed into Delete request")
|
||||
}
|
||||
{{ end }}
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -502,17 +336,18 @@ func (c *Client) Delete(ctx context.Context, {{ range .ResourceFunctionArgs }} {
|
||||
}
|
||||
`))
|
||||
|
||||
var createTemplate2 = template.Must(template.New("").Funcs(
|
||||
var createTemplate = template.Must(template.New("").Funcs(
|
||||
template.FuncMap{
|
||||
"snakeCase": snakeCase,
|
||||
},
|
||||
).Parse(`
|
||||
func (c *Client) Create{{ .Two }} (ctx context.Context, {{ if .TypeOnCreate }} resourceType string, {{ end }} {{ .CollectionFunctionArg2 }} string, opt... Option) (*{{ .Name }}, *api.Error, error) {
|
||||
if {{ .CollectionFunctionArg2 }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ .CollectionFunctionArg2 }} value passed into Create request")
|
||||
func (c *Client) Create (ctx context.Context, {{ if .TypeOnCreate }} resourceType string, {{ end }} {{ .CollectionFunctionArg }} string, opt... Option) (*{{ .Name }}, *api.Error, error) {
|
||||
if {{ .CollectionFunctionArg }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ .CollectionFunctionArg }} value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -522,9 +357,9 @@ func (c *Client) Create{{ .Two }} (ctx context.Context, {{ if .TypeOnCreate }} r
|
||||
opts.postMap["type"] = resourceType
|
||||
}{{ end }}
|
||||
|
||||
opts.postMap["{{ snakeCase .CollectionFunctionArg2 }}"] = {{ .CollectionFunctionArg2 }}
|
||||
opts.postMap["{{ snakeCase .CollectionFunctionArg }}"] = {{ .CollectionFunctionArg }}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "{{ .CollectionPath2 }}", opts.postMap, apiOpts...)
|
||||
req, err := c.client.NewRequest(ctx, "POST", "{{ .CollectionPath }}", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
@@ -556,121 +391,11 @@ func (c *Client) Create{{ .Two }} (ctx context.Context, {{ if .TypeOnCreate }} r
|
||||
}
|
||||
`))
|
||||
|
||||
var createTemplate = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Create(ctx context.Context, {{ if .TypeOnCreate }} resourceType string, {{ end }} {{ range .CollectionFunctionArgs }} {{ . }} string, {{ end }} opt... Option) (*{{ .Name }}, *api.Error, error) { {{ range .CollectionFunctionArgs }}
|
||||
if {{ . }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ . }} value passed into Create request")
|
||||
}
|
||||
{{ end }}opts, apiOpts := getOpts(opt...)
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
{{ if .TypeOnCreate }} if resourceType == "" {
|
||||
return nil, nil, fmt.Errorf("empty resourceType value passed into Create request")
|
||||
} else {
|
||||
opts.postMap["type"] = resourceType
|
||||
}{{ end }}
|
||||
{{ if ( eq .CollectionPath "\"scopes\"" ) }}
|
||||
opts.postMap["scope_id"] = scopeId
|
||||
{{ end }}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", {{ .CollectionPath }}, opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create 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, nil, fmt.Errorf("error performing client request during Create call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ .Name }})
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding Create response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var updateTemplate2 = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Update{{ .Two }}(ctx context.Context, {{ .ResourceFunctionArg2 }} string, version uint32, opt... Option) (*{{ .Name }}, *api.Error, error) {
|
||||
if {{ .ResourceFunctionArg2 }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ .ResourceFunctionArg2 }} value passed into Update request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
{{ if .VersionEnabled }}
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read{{ .Two }}(ctx, {{ .ResourceFunctionArg2 }}, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingApiErr != nil {
|
||||
return nil, nil, fmt.Errorf("error from controller when performing initial check-and-set read: %s", pretty.Sprint(existingApiErr))
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Version
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
opts.postMap["version"] = version
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "PATCH", {{ .ResourcePath2 }}, opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, 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, nil, fmt.Errorf("error performing client request during Update call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ .Name }})
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding Update response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
`))
|
||||
|
||||
var updateTemplate = template.Must(template.New("").Parse(`
|
||||
func (c *Client) Update(ctx context.Context, {{ range .ResourceFunctionArgs }} {{ . }} string, {{ end }}version uint32, opt... Option) (*{{ .Name }}, *api.Error, error) { {{ range .ResourceFunctionArgs }}
|
||||
if {{ . }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ . }} value passed into Update request")
|
||||
}{{ end }}
|
||||
func (c *Client) Update(ctx context.Context, {{ .ResourceFunctionArg }} string, version uint32, opt... Option) (*{{ .Name }}, *api.Error, error) {
|
||||
if {{ .ResourceFunctionArg }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ .ResourceFunctionArg }} value passed into Update request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -682,7 +407,7 @@ func (c *Client) Update(ctx context.Context, {{ range .ResourceFunctionArgs }} {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into Update request and automatic versioning not specified")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, {{ range .ResourceFunctionArgs }} {{ . }}, {{ end }} opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, {{ .ResourceFunctionArg }}, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -741,11 +466,11 @@ var sliceSubTypeTemplate = template.Must(template.New("").Funcs(
|
||||
{{ range $key, $value := $input.SliceSubTypes }}
|
||||
{{ $fullName := print $op $key }}
|
||||
{{ $actionName := kebabCase $fullName }}
|
||||
{{ $resPath := getPathWithAction $input.PathArgs $actionName }}
|
||||
func (c *Client) {{ $fullName }}(ctx context.Context, {{ range $input.ResourceFunctionArgs }} {{ . }} string, {{ end }}version uint32, {{ $value }} []string, opt... Option) (*{{ $input.Name }}, *api.Error, error) { {{ range $input.ResourceFunctionArgs }}
|
||||
if {{ . }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ . }} value passed into {{ $fullName }} request")
|
||||
}{{ end }}
|
||||
{{ $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 }}, *api.Error, error) {
|
||||
if {{ $input.ResourceFunctionArg }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ $input.ResourceFunctionArg }} value passed into {{ $fullName }} request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -757,92 +482,7 @@ func (c *Client) {{ $fullName }}(ctx context.Context, {{ range $input.ResourceFu
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into {{ $fullName }} request")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, {{ range $input.ResourceFunctionArgs }} {{ . }}, {{ end }} opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
if existingApiErr != nil {
|
||||
return nil, nil, fmt.Errorf("error from controller when performing initial check-and-set read: %s", pretty.Sprint(existingApiErr))
|
||||
}
|
||||
if existingTarget == nil {
|
||||
return nil, nil, errors.New("nil resource found when performing initial check-and-set read")
|
||||
}
|
||||
version = existingTarget.Version
|
||||
}
|
||||
{{ end }}
|
||||
opts.postMap["version"] = version
|
||||
|
||||
if len({{ $value }}) > 0 {
|
||||
opts.postMap["{{ snakeCase $value }}"] = {{ $value }}
|
||||
}{{ if ( eq $op "Set" ) }} else if {{ $value }} != nil {
|
||||
// In this function, a non-nil but empty list means clear out
|
||||
opts.postMap["{{ snakeCase $value }}"] = nil
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", {{ $resPath }}, opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, 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, nil, fmt.Errorf("error performing client request during {{ $fullName }} call: %w", err)
|
||||
}
|
||||
|
||||
target := new({{ $input.Name }})
|
||||
apiErr, err := resp.Decode(target)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error decoding {{ $fullName }} response: %w", err)
|
||||
}
|
||||
if apiErr != nil {
|
||||
return nil, apiErr, nil
|
||||
}
|
||||
return target, apiErr, nil
|
||||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
`))
|
||||
|
||||
var sliceSubTypeTemplate2 = template.Must(template.New("").Funcs(
|
||||
template.FuncMap{
|
||||
"makeSlice": makeSlice,
|
||||
"snakeCase": snakeCase,
|
||||
"kebabCase": kebabCase,
|
||||
"getPathWithActionNewStyle": getPathWithActionNewStyle,
|
||||
},
|
||||
).Parse(`
|
||||
{{ $input := . }}
|
||||
{{ range $index, $op := makeSlice "Add" "Set" "Remove" }}
|
||||
{{ range $key, $value := $input.SliceSubTypes }}
|
||||
{{ $fullName := print $op $key }}
|
||||
{{ $actionName := kebabCase $fullName }}
|
||||
{{ $resPath := getPathWithActionNewStyle $input.PathArgs $actionName }}
|
||||
func (c *Client) {{ $fullName }}{{ $input.Two }}(ctx context.Context, {{ $input.ResourceFunctionArg2 }} string, version uint32, {{ $value }} []string, opt... Option) (*{{ $input.Name }}, *api.Error, error) {
|
||||
if {{ $input.ResourceFunctionArg2 }} == "" {
|
||||
return nil, nil, fmt.Errorf("empty {{ $input.ResourceFunctionArg2 }} value passed into {{ $fullName }} request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
{{ if $input.VersionEnabled }}
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
return nil, nil, errors.New("zero version number passed into {{ $fullName }} request")
|
||||
}
|
||||
existingTarget, existingApiErr, existingErr := c.Read{{ $input.Two }}(ctx, {{ $input.ResourceFunctionArg2 }}, opt...)
|
||||
existingTarget, existingApiErr, existingErr := c.Read(ctx, {{ $input.ResourceFunctionArg }}, opt...)
|
||||
if existingErr != nil {
|
||||
return nil, nil, fmt.Errorf("error performing initial check-and-set read: %w", existingErr)
|
||||
}
|
||||
@@ -918,12 +558,22 @@ type {{ .Name }} struct { {{ range .Fields }}
|
||||
`)))
|
||||
|
||||
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 }
|
||||
return &Client{ client: c.Clone() }
|
||||
}
|
||||
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
`))
|
||||
|
||||
@@ -950,7 +600,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -967,25 +616,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
{{ range .Fields }}
|
||||
@@ -1033,12 +673,7 @@ func kebabCase(in string) string {
|
||||
return strcase.ToKebab(in)
|
||||
}
|
||||
|
||||
func getPathWithAction(resArgs []string, action string) string {
|
||||
_, _, _, resPath := getArgsAndPaths(resArgs, action)
|
||||
return resPath
|
||||
}
|
||||
|
||||
func getPathWithActionNewStyle(resArgs []string, action string) string {
|
||||
_, _, _, resPath := getArgsAndPathsNewStyle(resArgs, action)
|
||||
func getPathWithAction(resArgs []string, parentTypeName, action string) string {
|
||||
_, _, _, resPath := getArgsAndPaths(resArgs, parentTypeName, action)
|
||||
return resPath
|
||||
}
|
||||
+1
-17
@@ -13,24 +13,8 @@ type Option func(*options)
|
||||
|
||||
// options = how options are represented
|
||||
type options struct {
|
||||
withScopeId string
|
||||
withNewStyle bool
|
||||
}
|
||||
|
||||
func getDefaultOptions() options {
|
||||
return options{
|
||||
withScopeId: "",
|
||||
}
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
func WithNewStyle() Option {
|
||||
return func(o *options) {
|
||||
o.withNewStyle = true
|
||||
}
|
||||
return options{}
|
||||
}
|
||||
+2
-12
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-6
@@ -30,24 +30,42 @@ type Role struct {
|
||||
Grants []*Grant `json:"grants,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, opt ...Option) (*Role, *api.Error, error) {
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Role, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts.postMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "roles", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
@@ -74,9 +92,8 @@ func (c *Client) Create(ctx context.Context, opt ...Option) (*Role, *api.Error,
|
||||
|
||||
func (c *Client) Read(ctx context.Context, roleId string, opt ...Option) (*Role, *api.Error, error) {
|
||||
if roleId == "" {
|
||||
return nil, nil, fmt.Errorf("empty roleId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty roleId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -174,7 +191,6 @@ func (c *Client) Delete(ctx context.Context, roleId string, opt ...Option) (bool
|
||||
if roleId == "" {
|
||||
return false, nil, fmt.Errorf("empty roleId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -213,12 +229,16 @@ func (c *Client) Delete(ctx context.Context, roleId string, opt ...Option) (bool
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) List(ctx context.Context, opt ...Option) ([]*Role, *api.Error, error) {
|
||||
func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) ([]*Role, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into List request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "roles", nil, apiOpts...)
|
||||
if err != nil {
|
||||
|
||||
+65
-91
@@ -18,36 +18,29 @@ import (
|
||||
|
||||
func TestCustom(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeClient *api.Client
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeClient: client,
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeClient: projClient,
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
user, apiErr, err := users.NewClient(client).Create(tc.Context())
|
||||
user, apiErr, err := users.NewClient(client).Create(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
@@ -69,15 +62,15 @@ func TestCustom(t *testing.T) {
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g, apiErr, err := groups.NewClient(tt.scopeClient).Create(tc.Context())
|
||||
g, apiErr, err := groups.NewClient(client).Create(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(g)
|
||||
|
||||
rc := roles.NewClient(tt.scopeClient)
|
||||
rc := roles.NewClient(client)
|
||||
var version uint32 = 1
|
||||
|
||||
r, apiErr, err := rc.Create(tc.Context(), roles.WithName("foo"))
|
||||
r, apiErr, err := rc.Create(tc.Context(), tt.scopeId, roles.WithName("foo"))
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(r)
|
||||
@@ -129,65 +122,60 @@ func TestCustom(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRole_List(t *testing.T) {
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeClient *api.Client
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeClient: client,
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeClient: projClient,
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
roleClient := roles.NewClient(tt.scopeClient)
|
||||
p1, apiErr, err := roleClient.List(tc.Context())
|
||||
var expected []*roles.Role
|
||||
|
||||
roleClient := roles.NewClient(client)
|
||||
p1, apiErr, err := roleClient.List(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
require.Len(p1, 0)
|
||||
require.Len(p1, 1)
|
||||
expected = append(expected, p1[0])
|
||||
|
||||
var expected []*roles.Role
|
||||
for i := 0; i < 10; i++ {
|
||||
for i := 1; i < 11; i++ {
|
||||
expected = append(expected, &roles.Role{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
expected[0], apiErr, err = roleClient.Create(tc.Context(), roles.WithName(expected[0].Name))
|
||||
expected[1], apiErr, err = roleClient.Create(tc.Context(), tt.scopeId, roles.WithName(expected[1].Name))
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
|
||||
p2, apiErr, err := roleClient.List(tc.Context())
|
||||
p2, apiErr, err := roleClient.List(tc.Context(), tt.scopeId)
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSlice(expected[:1]), comparableSlice(p2))
|
||||
assert.ElementsMatch(comparableSlice(expected[0:2]), comparableSlice(p2))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
expected[i], apiErr, err = roleClient.Create(tc.Context(), roles.WithName(expected[i].Name))
|
||||
for i := 2; i < 11; i++ {
|
||||
expected[i], apiErr, err = roleClient.Create(tc.Context(), tt.scopeId, roles.WithName(expected[i].Name))
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
}
|
||||
p3, apiErr, err := roleClient.List(tc.Context())
|
||||
p3, apiErr, err := roleClient.List(tc.Context(), tt.scopeId)
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(p3))
|
||||
@@ -210,34 +198,27 @@ func comparableSlice(in []*roles.Role) []roles.Role {
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestRole_Crud(t *testing.T) {
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeClient *api.Client
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeClient: client,
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeClient: projClient,
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -257,8 +238,8 @@ func TestRole_Crud(t *testing.T) {
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
roleClient := roles.NewClient(tt.scopeClient)
|
||||
g, apiErr, err := roleClient.Create(tc.Context(), roles.WithName("foo"))
|
||||
roleClient := roles.NewClient(client)
|
||||
g, apiErr, err := roleClient.Create(tc.Context(), tt.scopeId, roles.WithName("foo"))
|
||||
checkRole("create", g, apiErr, err, "foo", 1)
|
||||
|
||||
g, apiErr, err = roleClient.Read(tc.Context(), g.Id)
|
||||
@@ -278,47 +259,40 @@ func TestRole_Crud(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRole_Errors(t *testing.T) {
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
projClient := client.Clone()
|
||||
projClient.SetScopeId(proj.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
scopeClient *api.Client
|
||||
name string
|
||||
scopeId string
|
||||
}{
|
||||
{
|
||||
name: "org",
|
||||
scopeClient: client,
|
||||
name: "org",
|
||||
scopeId: org.GetPublicId(),
|
||||
},
|
||||
{
|
||||
name: "proj",
|
||||
scopeClient: projClient,
|
||||
name: "proj",
|
||||
scopeId: proj.GetPublicId(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
roleClient := roles.NewClient(tt.scopeClient)
|
||||
u, apiErr, err := roleClient.Create(tc.Context(), roles.WithName("first"))
|
||||
roleClient := roles.NewClient(client)
|
||||
u, apiErr, err := roleClient.Create(tc.Context(), tt.scopeId, roles.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.NotNil(u)
|
||||
|
||||
// Create another resource with the same name.
|
||||
_, apiErr, err = roleClient.Create(tc.Context(), roles.WithName("first"))
|
||||
_, apiErr, err = roleClient.Create(tc.Context(), tt.scopeId, roles.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -35,25 +34,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-30
@@ -13,20 +13,15 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestProjects_List(t *testing.T) {
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
scps := scopes.NewClient(client)
|
||||
|
||||
@@ -63,20 +58,15 @@ func comparableSlice(in []*scopes.Scope) []scopes.Scope {
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestProjects_Crud(t *testing.T) {
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, _ := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, _ := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
scps := scopes.NewClient(client)
|
||||
|
||||
@@ -116,20 +106,15 @@ func TestProjects_Crud(t *testing.T) {
|
||||
}
|
||||
|
||||
// TODO: Get better coverage for expected errors and error formats.
|
||||
func TestProject_Errors(t *testing.T) {
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org, _ := iam.TestScopes(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org, _ := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
scps := scopes.NewClient(client)
|
||||
|
||||
|
||||
+16
-7
@@ -24,19 +24,31 @@ type Scope struct {
|
||||
Version uint32 `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Scope, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -47,6 +59,7 @@ func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Sc
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
@@ -73,9 +86,8 @@ func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Sc
|
||||
|
||||
func (c *Client) Read(ctx context.Context, scopeId string, opt ...Option) (*Scope, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -173,7 +185,6 @@ func (c *Client) Delete(ctx context.Context, scopeId string, opt ...Option) (boo
|
||||
if scopeId == "" {
|
||||
return false, nil, fmt.Errorf("empty scopeId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -216,20 +227,18 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) ([]*Sc
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into List request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "scopes", nil, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating List request: %w", err)
|
||||
}
|
||||
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
|
||||
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,20 +29,31 @@ type Target struct {
|
||||
DefaultPort uint32 `json:"default_port,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, resourceType string, scopeId string, opt ...Option) (*Target, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -92,7 +103,6 @@ func (c *Client) Read(ctx context.Context, targetId string, opt ...Option) (*Tar
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("targets/%s", targetId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
@@ -132,7 +142,6 @@ func (c *Client) Update(ctx context.Context, targetId string, version uint32, op
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
@@ -191,7 +200,6 @@ func (c *Client) Delete(ctx context.Context, targetId string, opt ...Option) (bo
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("targets/%s", targetId), nil, apiOpts...)
|
||||
if err != nil {
|
||||
@@ -234,7 +242,6 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) ([]*Ta
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "targets", nil, apiOpts...)
|
||||
@@ -278,7 +285,6 @@ func (c *Client) AddHostSets(ctx context.Context, targetId string, version uint3
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
@@ -341,7 +347,6 @@ func (c *Client) SetHostSets(ctx context.Context, targetId string, version uint3
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
@@ -407,7 +412,6 @@ func (c *Client) RemoveHostSets(ctx context.Context, targetId string, version ui
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
apiOpts = append(apiOpts, api.WithNewStyle())
|
||||
|
||||
if version == 0 {
|
||||
if !opts.withAutomaticVersioning {
|
||||
|
||||
@@ -24,18 +24,18 @@ func TestCustom(t *testing.T) {
|
||||
token := tc.Token()
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
client := tc.Client().Clone()
|
||||
client.SetScopeId(proj.GetPublicId())
|
||||
client.SetToken(token.Token)
|
||||
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static")
|
||||
hc, apiErr, err := hostcatalogs.NewClient(client).Create(tc.Context(), "static", proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
|
||||
hSetClient := hostsets.NewClient(client)
|
||||
hSet, apiErr, err := hSetClient.Create2(tc.Context(), hc.Id)
|
||||
hSet, apiErr, err := hSetClient.Create(tc.Context(), hc.Id)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hSet)
|
||||
hSet2, apiErr, err := hSetClient.Create2(tc.Context(), hc.Id)
|
||||
hSet2, apiErr, err := hSetClient.Create(tc.Context(), hc.Id)
|
||||
require.NoError(err)
|
||||
require.Nil(apiErr)
|
||||
require.NotNil(hSet2)
|
||||
@@ -73,8 +73,8 @@ func TestList(t *testing.T) {
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
client.SetScopeId(proj.GetPublicId())
|
||||
|
||||
tarClient := targets.NewClient(client)
|
||||
ul, apiErr, err := tarClient.List(tc.Context(), proj.GetPublicId())
|
||||
@@ -129,6 +129,7 @@ func TestCrud(t *testing.T) {
|
||||
|
||||
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, apiErr *api.Error, err error, wantedName string, wantVersion uint32) {
|
||||
@@ -175,6 +176,7 @@ func TestSet_Errors(t *testing.T) {
|
||||
|
||||
client := tc.Client()
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
_, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
|
||||
tarClient := targets.NewClient(client)
|
||||
|
||||
+2
-12
@@ -16,7 +16,6 @@ type Option func(*options)
|
||||
type options struct {
|
||||
postMap map[string]interface{}
|
||||
queryMap map[string]string
|
||||
withScopeId string
|
||||
withAutomaticVersioning bool
|
||||
}
|
||||
|
||||
@@ -33,25 +32,16 @@ func getOpts(opt ...Option) (options, []api.Option) {
|
||||
o(&opts)
|
||||
}
|
||||
var apiOpts []api.Option
|
||||
if opts.withScopeId != "" {
|
||||
apiOpts = append(apiOpts, api.WithScopeId(opts.withScopeId))
|
||||
}
|
||||
return opts, apiOpts
|
||||
}
|
||||
|
||||
func WithScopeId(id string) Option {
|
||||
return func(o *options) {
|
||||
o.withScopeId = id
|
||||
}
|
||||
}
|
||||
|
||||
// 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() Option {
|
||||
func WithAutomaticVersioning(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.withAutomaticVersioning = true
|
||||
o.withAutomaticVersioning = enable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-6
@@ -25,24 +25,42 @@ type User struct {
|
||||
Version uint32 `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// 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}
|
||||
return &Client{client: c.Clone()}
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, opt ...Option) (*User, *api.Error, error) {
|
||||
// ApiClient returns the underlying API client
|
||||
func (c *Client) ApiClient() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*User, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into Create request")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts.postMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "POST", "users", opts.postMap, apiOpts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating Create request: %w", err)
|
||||
}
|
||||
|
||||
if len(opts.queryMap) > 0 {
|
||||
q := url.Values{}
|
||||
for k, v := range opts.queryMap {
|
||||
@@ -69,9 +87,8 @@ func (c *Client) Create(ctx context.Context, opt ...Option) (*User, *api.Error,
|
||||
|
||||
func (c *Client) Read(ctx context.Context, userId string, opt ...Option) (*User, *api.Error, error) {
|
||||
if userId == "" {
|
||||
return nil, nil, fmt.Errorf("empty userId value passed into Read request")
|
||||
return nil, nil, fmt.Errorf("empty userId value passed into Read request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -169,7 +186,6 @@ func (c *Client) Delete(ctx context.Context, userId string, opt ...Option) (bool
|
||||
if userId == "" {
|
||||
return false, nil, fmt.Errorf("empty userId value passed into Delete request")
|
||||
}
|
||||
|
||||
if c.client == nil {
|
||||
return false, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
@@ -208,12 +224,16 @@ func (c *Client) Delete(ctx context.Context, userId string, opt ...Option) (bool
|
||||
return target.Existed, apiErr, nil
|
||||
}
|
||||
|
||||
func (c *Client) List(ctx context.Context, opt ...Option) ([]*User, *api.Error, error) {
|
||||
func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) ([]*User, *api.Error, error) {
|
||||
if scopeId == "" {
|
||||
return nil, nil, fmt.Errorf("empty scopeId value passed into List request")
|
||||
}
|
||||
if c.client == nil {
|
||||
return nil, nil, fmt.Errorf("nil client")
|
||||
}
|
||||
|
||||
opts, apiOpts := getOpts(opt...)
|
||||
opts.queryMap["scope_id"] = scopeId
|
||||
|
||||
req, err := c.client.NewRequest(ctx, "GET", "users", nil, apiOpts...)
|
||||
if err != nil {
|
||||
|
||||
+23
-38
@@ -13,23 +13,18 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUsers_List(t *testing.T) {
|
||||
func TestList(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
userClient := users.NewClient(client)
|
||||
|
||||
ul, apiErr, err := userClient.List(tc.Context())
|
||||
ul, apiErr, err := userClient.List(tc.Context(), org.GetPublicId())
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.Empty(ul)
|
||||
@@ -39,21 +34,21 @@ func TestUsers_List(t *testing.T) {
|
||||
expected = append(expected, &users.User{Name: fmt.Sprint(i)})
|
||||
}
|
||||
|
||||
expected[0], apiErr, err = userClient.Create(tc.Context(), users.WithName(expected[0].Name))
|
||||
expected[0], apiErr, err = userClient.Create(tc.Context(), org.GetPublicId(), users.WithName(expected[0].Name))
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
|
||||
ul, apiErr, err = userClient.List(tc.Context())
|
||||
ul, apiErr, err = userClient.List(tc.Context(), org.GetPublicId())
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSlice(expected[:1]), comparableSlice(ul))
|
||||
|
||||
for i := 1; i < 10; i++ {
|
||||
expected[i], apiErr, err = userClient.Create(tc.Context(), users.WithName(expected[i].Name))
|
||||
expected[i], apiErr, err = userClient.Create(tc.Context(), org.GetPublicId(), users.WithName(expected[i].Name))
|
||||
assert.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
}
|
||||
ul, apiErr, err = userClient.List(tc.Context())
|
||||
ul, apiErr, err = userClient.List(tc.Context(), org.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(ul))
|
||||
@@ -74,20 +69,15 @@ func comparableSlice(in []*users.User) []users.User {
|
||||
return filtered
|
||||
}
|
||||
|
||||
func TestUser_Crud(t *testing.T) {
|
||||
func TestCrud(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
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, apiErr *api.Error, err error, wantedName string, wantedVersion uint32) {
|
||||
@@ -104,7 +94,7 @@ func TestUser_Crud(t *testing.T) {
|
||||
assert.EqualValues(wantedVersion, u.Version)
|
||||
}
|
||||
|
||||
u, apiErr, err := userClient.Create(tc.Context(), users.WithName("foo"))
|
||||
u, apiErr, err := userClient.Create(tc.Context(), org.GetPublicId(), users.WithName("foo"))
|
||||
checkUser("create", u, apiErr, err, "foo", 1)
|
||||
|
||||
u, apiErr, err = userClient.Read(tc.Context(), u.Id)
|
||||
@@ -127,29 +117,24 @@ func TestUser_Crud(t *testing.T) {
|
||||
assert.EqualValues(http.StatusForbidden, apiErr.Status)
|
||||
}
|
||||
|
||||
func TestUser_Errors(t *testing.T) {
|
||||
func TestErrors(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
amId := "ampw_1234567890"
|
||||
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
||||
DisableAuthorizationFailures: true,
|
||||
DefaultAuthMethodId: amId,
|
||||
DefaultLoginName: "user",
|
||||
DefaultPassword: "passpass",
|
||||
})
|
||||
tc := controller.NewTestController(t, nil)
|
||||
defer tc.Shutdown()
|
||||
|
||||
client := tc.Client()
|
||||
org := iam.TestOrg(t, tc.IamRepo())
|
||||
client.SetScopeId(org.GetPublicId())
|
||||
token := tc.Token()
|
||||
client.SetToken(token.Token)
|
||||
org := iam.TestOrg(t, tc.IamRepo(), iam.WithUserId(token.UserId))
|
||||
userClient := users.NewClient(client)
|
||||
|
||||
u, apiErr, err := userClient.Create(tc.Context(), users.WithName("first"))
|
||||
u, apiErr, err := userClient.Create(tc.Context(), org.GetPublicId(), users.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.Nil(apiErr)
|
||||
assert.NotNil(u)
|
||||
|
||||
// Create another resource with the same name.
|
||||
_, apiErr, err = userClient.Create(tc.Context(), users.WithName("first"))
|
||||
_, apiErr, err = userClient.Create(tc.Context(), org.GetPublicId(), users.WithName("first"))
|
||||
require.NoError(err)
|
||||
assert.NotNil(apiErr)
|
||||
|
||||
|
||||
Reference in new issue
Block a user