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:
1 parent
d94a25bbd2
commit
e429e91bc4
21 files changed
+855
-322
No files matched your search
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in new issue
Block a user