Rebrand user-visible CLI text; add legacy fallbacks for keyring, cache dir and version prefix

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
shadowdaoandClaude Sonnet 5.5 committed 2026-10-12 10:20:06 -07:00
1 parent 4cb3bda43a
commit ab4ed3c9e5
184 files changed
+934 -851

No files matched your search

+4 -4
View File
@@ -28,16 +28,16 @@ type AddTokenCommand struct {
}
func (c *AddTokenCommand) Synopsis() string {
return "Add an auth token to a running boundary cache"
return "Add an auth token to a running threshold cache"
}
func (c *AddTokenCommand) Help() string {
helpText := `
Usage: boundary cache add-token [options]
Usage: threshold cache add-token [options]
Add an auth token to the cache:
$ boundary cache add-token
$ threshold cache add-token
For a full list of examples, please see the documentation.
@@ -54,7 +54,7 @@ func (c *AddTokenCommand) Flags() *base.FlagSets {
Target: &c.FlagAddr,
EnvVar: api.EnvBoundaryAddr,
Completion: complete.PredictAnything,
Usage: "Addr of the Boundary controller, as a complete URL (e.g. https://boundary.example.com:9200).",
Usage: "Addr of the Threshold controller, as a complete URL (e.g. https://threshold.example.com:9200).",
})
f = set.NewFlagSet("Client Options")
+5 -5
View File
@@ -21,18 +21,18 @@ type CacheCommand struct {
}
func (c *CacheCommand) Synopsis() string {
return "Manages the client side Boundary cache"
return "Manages the client side Threshold cache"
}
func (c *CacheCommand) Help() string {
helpText := `
Usage: boundary cache [sub command] [options]
Usage: threshold cache [sub command] [options]
This command allows interacting with the Boundary cache.
This command allows interacting with the Threshold cache.
Start a cache:
$ boundary cache start
$ threshold cache start
For a full list of examples, please see the documentation.
@@ -54,7 +54,7 @@ func (c *CacheCommand) AutocompleteFlags() complete.Flags {
func (c *CacheCommand) Run(args []string) int {
if len(args) >= 2 && args[1] == "daemon" {
c.UI.Warn("The `boundary daemon` command is deprecated, use `boundary cache` instead")
c.UI.Warn("The `threshold daemon` command is deprecated, use `threshold cache` instead")
}
return cli.RunResultHelp
}
+5 -6
View File
@@ -24,7 +24,6 @@ import (
)
const (
dotDirname = ".boundary"
pidFileName = "cache.pid"
logFileName = "cache.log"
@@ -54,16 +53,16 @@ type StartCommand struct {
}
func (c *StartCommand) Synopsis() string {
return "Start a Boundary cache"
return "Start a Threshold cache"
}
func (c *StartCommand) Help() string {
helpText := `
Usage: boundary cache start [options]
Usage: threshold cache start [options]
Start a cache:
$ boundary cache start
$ threshold cache start
For a full list of examples, please see the documentation.
@@ -78,7 +77,7 @@ func (c *StartCommand) Flags() *base.FlagSets {
f.StringVar(&base.StringVar{
Name: "log-level",
Target: &c.flagLogLevel,
EnvVar: "BOUNDARY_LOG_LEVEL",
EnvVar: "THRESHOLD_LOG_LEVEL",
Completion: complete.PredictSet("trace", "debug", "info", "warn", "err"),
Usage: "Log verbosity level, mostly as a fallback for events. Supported values (in order of more detail to less) are " +
"\"trace\", \"debug\", \"info\", \"warn\", and \"err\".",
@@ -255,7 +254,7 @@ func DefaultDotDirectory(ctx context.Context) (string, error) {
if err != nil {
return "", errors.Wrap(ctx, err, op)
}
return filepath.Join(homeDir, dotDirname), nil
return daemon.DotDirectory(homeDir), nil
}
// logFile returns a log file which is rotated after it reaches the provided
+4 -4
View File
@@ -34,16 +34,16 @@ type StatusCommand struct {
}
func (c *StatusCommand) Synopsis() string {
return "Get the status information of the running boundary cache"
return "Get the status information of the running threshold cache"
}
func (c *StatusCommand) Help() string {
helpText := `
Usage: boundary cache status [options]
Usage: threshold cache status [options]
Get the status of the boundary cache:
Get the status of the threshold cache:
$ boundary cache status
$ threshold cache status
For a full list of examples, please see the documentation.
+3 -3
View File
@@ -17,16 +17,16 @@ type StopCommand struct {
}
func (c *StopCommand) Synopsis() string {
return "Stop the Boundary cache"
return "Stop the Threshold cache"
}
func (c *StopCommand) Help() string {
helpText := `
Usage: boundary cache stop
Usage: threshold cache stop
Stop a cache:
$ boundary cache stop
$ threshold cache stop
For a full list of examples, please see the documentation.
+2 -2
View File
@@ -76,7 +76,7 @@ func startDaemon(ctx context.Context, baseCmd *base.Command) (started bool, _ er
cmdName, err := os.Executable()
if err != nil {
baseCmd.UI.Error(fmt.Sprintf("unable to find boundary binary for cache startup: %s", err.Error()))
baseCmd.UI.Error(fmt.Sprintf("unable to find threshold binary for cache startup: %s", err.Error()))
return false, err
}
@@ -113,7 +113,7 @@ func stopDaemon(ctx context.Context, baseCmd *base.Command) error {
cmdName, err := os.Executable()
if err != nil {
baseCmd.UI.Error(fmt.Sprintf("unable to find boundary binary for cache startup: %s", err.Error()))
baseCmd.UI.Error(fmt.Sprintf("unable to find threshold binary for cache startup: %s", err.Error()))
return err
}
cmd := exec.Command(cmdName, "cache", "stop")
+4 -4
View File
@@ -54,16 +54,16 @@ type SearchCommand struct {
}
func (c *SearchCommand) Synopsis() string {
return "Search Boundary resources using client cache"
return "Search Threshold resources using client cache"
}
func (c *SearchCommand) Help() string {
helpText := `
Usage: boundary search [options]
Usage: threshold search [options]
Search a boundary resource:
Search a threshold resource:
$ boundary search -resource targets -query 'name="foo"'
$ threshold search -resource targets -query 'name="foo"'
For a full list of examples, please see the documentation.
+5 -5
View File
@@ -284,7 +284,7 @@ func TestCleanAndPickTokens(t *testing.T) {
assert.ElementsMatch(t, maps.Values(got), []string{at1a.Token, at1b.Token})
})
t.Run("boundary in memory auth token expires", func(t *testing.T) {
t.Run("threshold in memory auth token expires", func(t *testing.T) {
require.NoError(t, r.AddRawToken(ctx, boundaryAddr, at1a.Token))
require.NoError(t, r.AddRawToken(ctx, boundaryAddr, at1b.Token))
@@ -302,7 +302,7 @@ func TestCleanAndPickTokens(t *testing.T) {
assert.ElementsMatch(t, maps.Values(got), []string{at1a.Token})
})
t.Run("boundary in memory auth token not found", func(t *testing.T) {
t.Run("threshold in memory auth token not found", func(t *testing.T) {
require.NoError(t, r.AddRawToken(ctx, boundaryAddr, at1a.Token))
require.NoError(t, r.AddRawToken(ctx, boundaryAddr, at1b.Token))
@@ -320,7 +320,7 @@ func TestCleanAndPickTokens(t *testing.T) {
assert.ElementsMatch(t, maps.Values(got), []string{at1a.Token})
})
t.Run("boundary keyring auths token expires", func(t *testing.T) {
t.Run("threshold keyring auths token expires", func(t *testing.T) {
key1 := ringToken{"k1", "t1"}
atMap[key1] = keyringAuthToken1
require.NoError(t, r.AddKeyringToken(ctx, boundaryAddr, KeyringToken{
@@ -350,7 +350,7 @@ func TestCleanAndPickTokens(t *testing.T) {
assert.ElementsMatch(t, maps.Values(got), []string{keyringAuthToken1.Token})
})
t.Run("boundary in memory auth token check errors", func(t *testing.T) {
t.Run("threshold in memory auth token check errors", func(t *testing.T) {
require.NoError(t, r.AddRawToken(ctx, boundaryAddr, at1a.Token))
require.NoError(t, r.AddRawToken(ctx, boundaryAddr, at1b.Token))
@@ -368,7 +368,7 @@ func TestCleanAndPickTokens(t *testing.T) {
assert.ElementsMatch(t, maps.Values(got), []string{at1a.Token})
})
t.Run("boundary keyring auths token check errors", func(t *testing.T) {
t.Run("threshold keyring auths token check errors", func(t *testing.T) {
key1 := ringToken{"k1", "t1"}
atMap[key1] = keyringAuthToken1
require.NoError(t, r.AddKeyringToken(ctx, boundaryAddr, KeyringToken{
@@ -23,7 +23,7 @@ var ErrRefreshNotSupported = stderrors.New("refresh tokens are not supported for
type RefreshTokenValue string
// sentinelNoRefreshToken is the value set in the refresh token table when
// Boundary returns resources but no refresh tokens. The presence of this value
// Threshold returns resources but no refresh tokens. The presence of this value
// indicates that the boundary instance queried does not support refresh tokens.
const sentinelNoRefreshToken RefreshTokenValue = "__no_refresh_token_supported__"
+6 -6
View File
@@ -37,7 +37,7 @@ func upsertUserAndAuthToken(ctx context.Context, reader db.Reader, writer db.Wri
case util.IsNil(at):
return errors.New(ctx, errors.InvalidParameter, op, "auth token is nil")
case bAddr == "":
return errors.New(ctx, errors.InvalidParameter, op, "boundary address is empty")
return errors.New(ctx, errors.InvalidParameter, op, "threshold address is empty")
case at.Id == "":
return errors.New(ctx, errors.InvalidParameter, op, "auth token id is empty")
case at.UserId == "":
@@ -114,15 +114,15 @@ func (r *Repository) AddRawToken(ctx context.Context, bAddr string, rawToken str
const op = "cache.(Repository).AddRawToken"
switch {
case rawToken == "":
return errors.New(ctx, errors.InvalidParameter, op, "boundary auth token is empty", errors.WithoutEvent())
return errors.New(ctx, errors.InvalidParameter, op, "threshold auth token is empty", errors.WithoutEvent())
case bAddr == "":
return errors.New(ctx, errors.InvalidParameter, op, "boundary address is empty", errors.WithoutEvent())
return errors.New(ctx, errors.InvalidParameter, op, "threshold address is empty", errors.WithoutEvent())
}
// rawToken should look something like at_1234567890_someencryptedpayload
atIdParts := strings.SplitN(rawToken, "_", 4)
if len(atIdParts) != 3 {
return errors.New(ctx, errors.InvalidParameter, op, "boundary auth token is is malformed", errors.WithoutEvent())
return errors.New(ctx, errors.InvalidParameter, op, "threshold auth token is is malformed", errors.WithoutEvent())
}
atId := strings.Join(atIdParts[:AuthTokenIdSegmentCount], "_")
@@ -192,9 +192,9 @@ func (r *Repository) AddKeyringToken(ctx context.Context, bAddr string, token Ke
case token.KeyringType == "":
return errors.New(ctx, errors.InvalidParameter, op, "keyring type is empty", errors.WithoutEvent())
case token.AuthTokenId == "":
return errors.New(ctx, errors.InvalidParameter, op, "boundary auth token id is empty", errors.WithoutEvent())
return errors.New(ctx, errors.InvalidParameter, op, "threshold auth token id is empty", errors.WithoutEvent())
case bAddr == "":
return errors.New(ctx, errors.InvalidParameter, op, "boundary address is empty", errors.WithoutEvent())
return errors.New(ctx, errors.InvalidParameter, op, "threshold address is empty", errors.WithoutEvent())
}
kt := token.clone()
keyringStoredAt, err := r.tokenKeyringFn(kt.KeyringType, kt.TokenName)
@@ -103,7 +103,7 @@ func TestRepository_AddKeyringToken(t *testing.T) {
TokenName: tokenName,
AuthTokenId: at.Id,
},
errorContains: "boundary address is empty",
errorContains: "threshold address is empty",
},
{
name: "missing token",
@@ -130,7 +130,7 @@ func TestRepository_AddKeyringToken(t *testing.T) {
KeyringType: keyring,
TokenName: tokenName,
},
errorContains: "boundary auth token id is empty",
errorContains: "threshold auth token id is empty",
},
{
name: "unmatching auth token id",
@@ -218,7 +218,7 @@ func TestRepository_AddRawToken(t *testing.T) {
{
name: "missing address",
rawAt: at.Token,
errorContains: "boundary address is empty",
errorContains: "threshold address is empty",
},
{
name: "missing token",
@@ -229,7 +229,7 @@ func TestRepository_AddRawToken(t *testing.T) {
name: "malformed auth token",
addr: "address",
rawAt: fmt.Sprintf("%s_extraunderscore", at.Token),
errorContains: "boundary auth token is is malformed",
errorContains: "threshold auth token is is malformed",
},
{
name: "not found in boundary",
@@ -1079,7 +1079,7 @@ func TestUpsertUserAndAuthToken(t *testing.T) {
writer: txWriter,
addr: "",
at: defaultAt,
errorContains: "boundary address is empty",
errorContains: "threshold address is empty",
},
{
name: "auth token is nil",
@@ -256,7 +256,7 @@ func toApiResult(sr *cache.SearchResult) *SearchResult {
var errSearchNotSupported = &api.Error{
Kind: "Unsupported Search Request",
Message: "The request is for a Boundary instance that doesn't support search. The Boundary instance must support refresh tokens for search to be supported.",
Message: "The request is for a Threshold instance that doesn't support search. The Threshold instance must support refresh tokens for search to be supported.",
}
func writeUnsupportedError(w http.ResponseWriter) {
+22 -5
View File
@@ -191,7 +191,7 @@ func defaultBoundaryTokenReader(ctx context.Context, cp ClientProvider) (cache.B
at, err := atClient.Read(ctx, atId)
if err != nil {
if api.ErrPermissionDenied.Is(err) {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("Failed to get auth token from Boundary"), errors.WithCode(errors.Forbidden), errors.WithoutEvent())
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("Failed to get auth token from Threshold"), errors.WithCode(errors.Forbidden), errors.WithoutEvent())
}
return nil, errors.Wrap(ctx, err, op, errors.WithoutEvent())
}
@@ -360,7 +360,7 @@ func (s *CacheServer) printInfo(ctx context.Context) {
verInfo := version.Get()
if verInfo.Version != "" {
s.infoKeys = append(s.infoKeys, "version")
s.info["version"] = verInfo.FullVersionNumber(false)
s.info["version"] = verInfo.DisplayVersionNumber(false)
}
if verInfo.Revision != "" {
s.info["version sha"] = strings.Trim(verInfo.Revision, "'")
@@ -506,7 +506,7 @@ func setupEventing(ctx context.Context, logger hclog.Logger, serializationLock *
// openStore will open the underlying store for the db. If no options are
// provided, it will default to an on disk store using the user's home dir +
// ".boundary/cache.db". If a url is provided, it will use that as the store.
// ".threshold/cache.db". If a url is provided, it will use that as the store.
// Supported options: WithUrl, WithLogger, WithHomeDir
func openStore(ctx context.Context, opt ...Option) (*db.DB, error) {
const op = "daemon.openStore"
@@ -562,7 +562,7 @@ func defaultDbUrl(ctx context.Context, opt ...Option) (string, error) {
return "", errors.Wrap(ctx, err, op)
}
}
dotDir := filepath.Join(opts.withHomeDir, dotDirname)
dotDir := DotDirectory(opts.withHomeDir)
if err := os.MkdirAll(dotDir, 0o700); err != nil {
return "", errors.Wrap(ctx, err, op)
}
@@ -584,8 +584,25 @@ func defaultDbUrl(ctx context.Context, opt ...Option) (string, error) {
return fmt.Sprintf("%s%s", fileName, fkPragma), nil
}
// DotDirectory returns the path of the client cache dot directory inside the
// given home directory. The Threshold directory is preferred; if it does not
// exist but the legacy directory used by upstream HashiCorp Boundary does, the
// legacy directory is used so existing state keeps being found.
func DotDirectory(homeDir string) string {
preferred := filepath.Join(homeDir, dotDirname)
if _, err := os.Stat(preferred); err == nil {
return preferred
}
legacy := filepath.Join(homeDir, legacyDotDirname)
if fi, err := os.Stat(legacy); err == nil && fi.IsDir() {
return legacy
}
return preferred
}
const (
dotDirname = ".boundary"
dotDirname = ".threshold"
legacyDotDirname = ".boundary"
dbFileName = "cache.db"
fkPragma = "?_pragma=foreign_keys(1)"
)
@@ -49,7 +49,7 @@ type BoundaryStatus struct {
Address string `json:"address,omitempty"`
// Whether the controller responses are supported by the cache
CacheSupport string `json:"cache_support,omitempty"`
// How long ago the Boundary instance was checked for cache compatibility
// How long ago the Threshold instance was checked for cache compatibility
LastSupportCheck time.Duration `json:"last_support_check,omitempty"`
}
@@ -131,7 +131,7 @@ func toApiStatus(in *cache.Status, started time.Time, socketAddr, logLocation st
// sleeps.
Uptime: time.Since(started.Round(0)),
SocketAddress: socketAddr,
Version: version.Get().FullVersionNumber(true),
Version: version.Get().DisplayVersionNumber(true),
LogLocation: logLocation,
}