Do not cache or allow searching for old controllers (#4136)

* Do not cache or allow searching for old controllers

* Identify resourceless responses as coming from supported or unsupported controllers

* Do not report refresh token status info for unsupported controllers
This commit is contained in:
Todd authored and Johan Brandhorst-Satzkorn committed 2024-01-05 07:43:21 -08:00
1 parent d94a25bbd2
commit e429e91bc4
21 files changed
+855 -322

No files matched your search

+23 -30
View File
@@ -50,7 +50,7 @@ type StartCommand struct {
*base.Command
flagRefreshInterval time.Duration
flagFullFetchInterval time.Duration
flagRecheckSupportInterval time.Duration
flagMaxSearchStaleness time.Duration
flagMaxSearchRefreshTimeout time.Duration
flagDatabaseUrl string
@@ -104,25 +104,26 @@ func (c *StartCommand) Flags() *base.FlagSets {
f.DurationVar(&base.DurationVar{
Name: "refresh-interval",
Target: &c.flagRefreshInterval,
Usage: `Specifies the interval between refresh token supported cache refreshes. Default: 1 minute`,
Usage: `Specifies the interval between refresh token supported cache refreshes.`,
Default: daemon.DefaultRefreshInterval,
})
f.DurationVar(&base.DurationVar{
Name: "full-fetch-interval",
Target: &c.flagFullFetchInterval,
Usage: `Specifies the interval between full cache refresh for boundary instances which do not support refresh tokens. Default: 5 minutes`,
Default: daemon.DefaultFullFetchInterval,
Name: "recheck-support-interval",
Target: &c.flagRecheckSupportInterval,
Usage: `Specifies the interval between checking if a boundary instances is supported when it previously was not.`,
Default: daemon.DefaultRecheckSupportInterval,
Hidden: true,
})
f.DurationVar(&base.DurationVar{
Name: "max-search-staleness",
Target: &c.flagMaxSearchStaleness,
Usage: `Specifies the duration of time that can pass since the resource was last updated before performing a search waits for the resources being refreshed first. Default: 1 minute`,
Usage: `Specifies the duration of time that can pass since the resource was last updated before performing a search waits for the resources being refreshed first.`,
Default: daemon.DefaultSearchStaleness,
})
f.DurationVar(&base.DurationVar{
Name: "max-search-refresh-timeout",
Target: &c.flagMaxSearchRefreshTimeout,
Usage: `If a search request triggers a best effort refresh, this specifies how long the refresh should run before timing out. Default: 1 second`,
Usage: `If a search request triggers a best effort refresh, this specifies how long the refresh should run before timing out.`,
Default: daemon.DefaultSearchRefreshTimeout,
})
f.BoolVar(&base.BoolVar{
@@ -196,16 +197,16 @@ func (c *StartCommand) Run(args []string) int {
writers = append(writers, lf)
cfg := &daemon.Config{
ContextCancel: cancel,
RefreshInterval: c.flagRefreshInterval,
FullFetchInterval: c.flagFullFetchInterval,
MaxSearchStaleness: c.flagMaxSearchStaleness,
DatabaseUrl: c.flagDatabaseUrl,
StoreDebug: c.flagStoreDebug,
LogLevel: c.flagLogLevel,
LogFormat: c.flagLogFormat,
LogWriter: io.MultiWriter(writers...),
DotDirectory: dotDir,
ContextCancel: cancel,
RefreshInterval: c.flagRefreshInterval,
RecheckSupportInterval: c.flagRecheckSupportInterval,
MaxSearchStaleness: c.flagMaxSearchStaleness,
DatabaseUrl: c.flagDatabaseUrl,
StoreDebug: c.flagStoreDebug,
LogLevel: c.flagLogLevel,
LogFormat: c.flagLogFormat,
LogWriter: io.MultiWriter(writers...),
DotDirectory: dotDir,
}
srv, err := daemon.New(ctx, cfg)
@@ -307,6 +308,10 @@ func (c *StartCommand) makeBackground(ctx context.Context, dotDir string) (bool,
env := os.Environ()
env = append(env, fmt.Sprintf("%s=%s", backgroundEnvName, backgroundEnvVal))
args := []string{"daemon", "start"}
args = append(args, "-refresh-interval", c.flagRefreshInterval.String())
args = append(args, "-max-search-staleness", c.flagMaxSearchStaleness.String())
args = append(args, "-max-search-refresh-timeout", c.flagMaxSearchRefreshTimeout.String())
args = append(args, "-recheck-support-interval", c.flagRecheckSupportInterval.String())
if c.flagLogLevel != "" {
args = append(args, "-log-level", c.flagLogLevel)
}
@@ -316,18 +321,6 @@ func (c *StartCommand) makeBackground(ctx context.Context, dotDir string) (bool,
if c.flagDatabaseUrl != "" {
args = append(args, "-database-url", c.flagDatabaseUrl)
}
if c.flagRefreshInterval > 0 && c.flagRefreshInterval != daemon.DefaultRefreshInterval {
args = append(args, "-refresh-interval", c.flagRefreshInterval.String())
}
if c.flagFullFetchInterval > 0 && c.flagFullFetchInterval != daemon.DefaultFullFetchInterval {
args = append(args, "-full-fetch-interval", c.flagFullFetchInterval.String())
}
if c.flagMaxSearchStaleness > 0 && c.flagMaxSearchStaleness != daemon.DefaultSearchStaleness {
args = append(args, "-max-search-staleness", c.flagMaxSearchStaleness.String())
}
if c.flagMaxSearchRefreshTimeout > 0 && c.flagMaxSearchRefreshTimeout != daemon.DefaultSearchRefreshTimeout {
args = append(args, "-max-search-refresh-timeout", c.flagMaxSearchRefreshTimeout.String())
}
if c.flagStoreDebug {
args = append(args, "-store-debug")
}
+6 -2
View File
@@ -168,8 +168,12 @@ func printUsersTable(us []daemon.UserStatus) []string {
ret = append(ret, " User:")
nonAttributeMap := map[string]any{
"Id": u.Id,
"Address": u.Address,
"Address": u.BoundaryInstance.Address,
"AuthToken Count": len(u.AuthTokens),
"Search Support": u.BoundaryInstance.CacheSupport,
}
if u.BoundaryInstance.LastSupportCheck > 0 {
nonAttributeMap["Since Search Support Check"] = u.BoundaryInstance.LastSupportCheck.Round(time.Second)
}
maxLength := base.MaxAttributesLength(nonAttributeMap, nil, nil)
ret = append(ret,
@@ -196,7 +200,7 @@ func printUsersTable(us []daemon.UserStatus) []string {
}
if r.RefreshToken != nil {
nonAttributeMap["Since Last Refresh"] = r.RefreshToken.LastUsed.Round(time.Second)
nonAttributeMap["Since Full Fetch"] = r.RefreshToken.Age.Round(time.Second)
nonAttributeMap["Since Initial Fetch"] = r.RefreshToken.Age.Round(time.Second)
}
if r.LastError != nil {
nonAttributeMap["Since Last Error"] = r.LastError.LastReturned.Round(time.Second)
+40 -5
View File
@@ -22,7 +22,7 @@ import (
type testCommander struct {
t *testing.T
at *authtokens.AuthToken
at map[string]*authtokens.AuthToken
}
func (r *testCommander) Client(opt ...base.Option) (*api.Client, error) {
@@ -32,7 +32,7 @@ func (r *testCommander) Client(opt ...base.Option) (*api.Client, error) {
}
func (r *testCommander) ReadTokenFromKeyring(k, a string) *authtokens.AuthToken {
return r.at
return r.at[a]
}
func TestSearch(t *testing.T) {
@@ -43,10 +43,19 @@ func TestSearch(t *testing.T) {
Token: "at_1_token",
ExpirationTime: time.Now().Add(time.Minute),
}
cmd := &testCommander{t: t, at: at}
unsupportedAt := &authtokens.AuthToken{
Id: "at_2",
UserId: "user_2",
Token: "at_2_token",
ExpirationTime: time.Now().Add(time.Minute),
}
cmd := &testCommander{t: t, at: map[string]*authtokens.AuthToken{"tokenname": at, "unsupported": unsupportedAt}}
boundaryTokenReaderFn := func(ctx context.Context, addr, authToken string) (*authtokens.AuthToken, error) {
if authToken == at.Token {
switch authToken {
case at.Token:
return at, nil
case unsupportedAt.Token:
return unsupportedAt, nil
}
return nil, errors.New("test not found error")
}
@@ -61,6 +70,7 @@ func TestSearch(t *testing.T) {
// Give the store some time to get initialized
time.Sleep(100 * time.Millisecond)
srv.AddKeyringToken(t, "address", "keyringtype", "tokenname", at.Id, boundaryTokenReaderFn)
srv.AddKeyringToken(t, "address", "keyringtype", "unsupported", unsupportedAt.Id, boundaryTokenReaderFn)
errorCases := []struct {
name string
@@ -142,7 +152,21 @@ func TestSearch(t *testing.T) {
assert.EqualValues(t, r, &daemon.SearchResult{})
})
srv.AddResources(t, cmd.at, []*targets.Target{
t.Run("unsupported boundary instance", func(t *testing.T) {
srv.AddUnsupportedCachingData(t, unsupportedAt, boundaryTokenReaderFn)
resp, r, apiErr, err := search(ctx, srv.BaseDotDir(), filterBy{
authTokenId: unsupportedAt.Id,
resource: "targets",
})
assert.NoError(t, err)
require.NotNil(t, apiErr)
assert.NotNil(t, resp)
assert.Nil(t, r)
assert.Contains(t, apiErr.Message, "doesn't support search")
})
srv.AddResources(t, at, []*targets.Target{
{Id: "ttcp_1234567890", Name: "name1", Description: "description1"},
{Id: "ttcp_0987654321", Name: "name2", Description: "description2"},
}, []*sessions.Session{
@@ -151,6 +175,17 @@ func TestSearch(t *testing.T) {
}, boundaryTokenReaderFn)
t.Run("target response from list", func(t *testing.T) {
resp, r, apiErr, err := search(ctx, srv.BaseDotDir(), filterBy{
authTokenId: at.Id,
resource: "targets",
})
require.NoError(t, err)
assert.Nil(t, apiErr)
assert.NotNil(t, resp)
assert.NotNil(t, r)
assert.Len(t, r.Targets, 2)
})
t.Run("search for unsupported controller", func(t *testing.T) {
resp, r, apiErr, err := search(ctx, srv.BaseDotDir(), filterBy{
authTokenId: at.Id,
resource: "targets",