Skip to content

Commit

Permalink
Add aliases to the client cache daemon and make them searchable (#4418)
Browse files Browse the repository at this point in the history
* Add aliases to the client cache daemon and make them searchable
  • Loading branch information
talanknight committed Feb 28, 2024
1 parent cca3673 commit 2c24d09
Show file tree
Hide file tree
Showing 16 changed files with 1,359 additions and 18 deletions.
72 changes: 72 additions & 0 deletions internal/clientcache/cmd/search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/aliases"
"github.com/hashicorp/boundary/api/sessions"
"github.com/hashicorp/boundary/api/targets"
daemoncmd "github.com/hashicorp/boundary/internal/clientcache/cmd/daemon"
Expand All @@ -29,6 +30,7 @@ var (
_ cli.CommandAutocomplete = (*SearchCommand)(nil)

supportedResourceTypes = []string{
"aliases",
"targets",
"sessions",
}
Expand Down Expand Up @@ -163,6 +165,8 @@ func (c *SearchCommand) Run(args []string) int {
}
default:
switch {
case len(result.Aliases) > 0:
c.UI.Output(printAliasListTable(result.Aliases))
case len(result.Targets) > 0:
c.UI.Output(printTargetListTable(result.Targets))
case len(result.Sessions) > 0:
Expand Down Expand Up @@ -241,6 +245,74 @@ func search(ctx context.Context, daemonPath string, fb filterBy, opt ...client.O
return resp, res, nil, nil
}

func printAliasListTable(items []*aliases.Alias) string {
if len(items) == 0 {
return "No aliases found"
}
var output []string
output = []string{
"",
"Alias information:",
}
for i, item := range items {
if i > 0 {
output = append(output, "")
}
if item.Id != "" {
output = append(output,
fmt.Sprintf(" ID: %s", item.Id),
)
} else {
output = append(output,
fmt.Sprintf(" ID: %s", "(not available)"),
)
}
if item.ScopeId != "" {
output = append(output,
fmt.Sprintf(" Scope ID: %s", item.ScopeId),
)
}
if item.Version > 0 {
output = append(output,
fmt.Sprintf(" Version: %d", item.Version),
)
}
if item.Type != "" {
output = append(output,
fmt.Sprintf(" Type: %s", item.Type),
)
}
if item.Name != "" {
output = append(output,
fmt.Sprintf(" Name: %s", item.Name),
)
}
if item.Description != "" {
output = append(output,
fmt.Sprintf(" Description: %s", item.Description),
)
}
if item.DestinationId != "" {
output = append(output,
fmt.Sprintf(" DestinationId: %s", item.DestinationId),
)
}
if item.Value != "" {
output = append(output,
fmt.Sprintf(" Value: %s", item.Value),
)
}
if len(item.AuthorizedActions) > 0 {
output = append(output,
" Authorized Actions:",
base.WrapSlice(6, item.AuthorizedActions),
)
}
}

return base.WrapForHelpText(output)
}

func printTargetListTable(items []*targets.Target) string {
if len(items) == 0 {
return "No targets found"
Expand Down
6 changes: 5 additions & 1 deletion internal/clientcache/cmd/search/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/aliases"
"github.com/hashicorp/boundary/api/authtokens"
"github.com/hashicorp/boundary/api/sessions"
"github.com/hashicorp/boundary/api/targets"
Expand Down Expand Up @@ -166,7 +167,10 @@ func TestSearch(t *testing.T) {
assert.Contains(t, apiErr.Message, "doesn't support search")
})

srv.AddResources(t, at, []*targets.Target{
srv.AddResources(t, at, []*aliases.Alias{
{Id: "alt_1234567890", Value: "value1", DestinationId: "ttcp_1234567890"},
{Id: "alt_0987654321", Name: "value2", DestinationId: "ttcp_0987654321"},
}, []*targets.Target{
{Id: "ttcp_1234567890", Name: "name1", Description: "description1"},
{Id: "ttcp_0987654321", Name: "name2", Description: "description2"},
}, []*sessions.Session{
Expand Down
9 changes: 9 additions & 0 deletions internal/clientcache/internal/cache/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type options struct {
withDbType dbw.DbType
withAuthTokenId string
withUserId string
withAliasRetrievalFunc AliasRetrievalFunc
withTargetRetrievalFunc TargetRetrievalFunc
withSessionRetrievalFunc SessionRetrievalFunc
withIgnoreSearchStaleness bool
Expand Down Expand Up @@ -61,6 +62,14 @@ func withUserId(id string) Option {
}
}

// WithAliasRetrievalFunc provides an option for specifying an aliasRetrievalFunc
func WithAliasRetrievalFunc(fn AliasRetrievalFunc) Option {
return func(o *options) error {
o.withAliasRetrievalFunc = fn
return nil
}
}

// WithTargetRetrievalFunc provides an option for specifying a targetRetrievalFunc
func WithTargetRetrievalFunc(fn TargetRetrievalFunc) Option {
return func(o *options) error {
Expand Down
14 changes: 14 additions & 0 deletions internal/clientcache/internal/cache/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"testing"

"github.com/hashicorp/boundary/api/aliases"
"github.com/hashicorp/boundary/api/sessions"
"github.com/hashicorp/boundary/api/targets"
"github.com/hashicorp/go-dbw"
Expand Down Expand Up @@ -72,6 +73,19 @@ func Test_GetOpts(t *testing.T) {
testOpts := getDefaultOptions()
assert.Equal(t, opts, testOpts)
})
t.Run("WithAliasRetrievalFunc", func(t *testing.T) {
var f AliasRetrievalFunc = func(ctx context.Context, addr, authTok string, refreshTok RefreshTokenValue) ([]*aliases.Alias, []string, RefreshTokenValue, error) {
return nil, nil, "", nil
}
opts, err := getOpts(WithAliasRetrievalFunc(f))
require.NoError(t, err)

assert.NotNil(t, opts.withAliasRetrievalFunc)
opts.withAliasRetrievalFunc = nil

testOpts := getDefaultOptions()
assert.Equal(t, opts, testOpts)
})
t.Run("withIgnoreSearchStaleness", func(t *testing.T) {
opts, err := getOpts(WithIgnoreSearchStaleness(true))
require.NoError(t, err)
Expand Down
20 changes: 20 additions & 0 deletions internal/clientcache/internal/cache/refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,16 @@ func (r *RefreshService) RefreshForSearch(ctx context.Context, authTokenid strin
}

switch resourceType {
case Aliases:
rtv, err := r.repo.lookupRefreshToken(ctx, u, aliasResourceType)
if err != nil {
return errors.Wrap(ctx, err, op)
}
if opts.withIgnoreSearchStaleness || rtv != nil && time.Since(rtv.UpdateTime) > r.maxSearchStaleness {
if err := r.repo.refreshAliases(ctx, u, tokens, opt...); err != nil {
return errors.Wrap(ctx, err, op)
}
}
case Targets:
rtv, err := r.repo.lookupRefreshToken(ctx, u, targetResourceType)
if err != nil {
Expand Down Expand Up @@ -260,6 +270,9 @@ func (r *RefreshService) Refresh(ctx context.Context, opt ...Option) error {
continue
}

if err := r.repo.refreshAliases(ctx, u, tokens, opt...); err != nil {
retErr = stderrors.Join(retErr, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for user id %s", u.Id))))
}
if err := r.repo.refreshTargets(ctx, u, tokens, opt...); err != nil {
retErr = stderrors.Join(retErr, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for user id %s", u.Id))))
}
Expand Down Expand Up @@ -327,6 +340,13 @@ func (r *RefreshService) RecheckCachingSupport(ctx context.Context, opt ...Optio
}
retErr = stderrors.Join(retErr, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for user id %s", u.Id))))
}
if err := r.repo.checkCachingAliases(ctx, u, tokens, opt...); err != nil {
if err == ErrRefreshNotSupported {
// This is expected so no need to propogate the error up
continue
}
retErr = stderrors.Join(retErr, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("for user id %s", u.Id))))
}

}
return retErr
Expand Down
Loading

0 comments on commit 2c24d09

Please sign in to comment.