From d6757609dc2d608fd5ad1c463d532efe3786396b Mon Sep 17 00:00:00 2001 From: James Rasell Date: Thu, 3 Jul 2025 14:50:42 +0200 Subject: [PATCH] cli: Fix a bug where self token lookups via token CLI flag failed. (#26183) The meta client looks for both an environment variable and a CLI flag when generating a client. The CLI UUID checker needs to do this also, so we account for users using both env vars and CLI flag tokens. --- .changelog/26183.txt | 3 +++ command/acl_token_self.go | 21 ++++++++++++++++----- command/acl_token_self_test.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 .changelog/26183.txt diff --git a/.changelog/26183.txt b/.changelog/26183.txt new file mode 100644 index 000000000..2965fbf03 --- /dev/null +++ b/.changelog/26183.txt @@ -0,0 +1,3 @@ +```release-note:bug +cli: Fixed a bug where the `acl token self` command only performed lookups for tokens set as environment variables and not by the `-token` flag. +``` diff --git a/command/acl_token_self.go b/command/acl_token_self.go index deaa717f7..261482e8d 100644 --- a/command/acl_token_self.go +++ b/command/acl_token_self.go @@ -65,15 +65,26 @@ func (c *ACLTokenSelfCommand) Run(args []string) int { return 1 } - // Check what kind of token we have available - envToken := os.Getenv("NOMAD_TOKEN") - if envToken == "" { - c.Ui.Error("No token present in the environment") + // To get the authentication token, we must perform the same steps as the + // command meta and API client perform. This is because the token may be set + // as an environment variable or as a CLI flag. + // + // The environment variable is grabbed first. If this is not set, the + // resulting string is empty. + authToken := os.Getenv("NOMAD_TOKEN") + + // If the CLI flag is set, it will override the environment variable. + if c.token != "" { + authToken = c.token + } + + if authToken == "" { + c.Ui.Error("No token present in the environment or set via the CLI flag") return 1 } // Does this look like a Nomad ACL token? - if helper.IsUUID(envToken) { + if helper.IsUUID(authToken) { token, _, err := client.ACLTokens().Self(nil) if err != nil { c.Ui.Error(fmt.Sprintf("Error fetching self token: %s", err)) diff --git a/command/acl_token_self_test.go b/command/acl_token_self_test.go index c3e1b3de5..81b42fd77 100644 --- a/command/acl_token_self_test.go +++ b/command/acl_token_self_test.go @@ -53,3 +53,34 @@ func TestACLTokenSelfCommand_ViaEnvVar(t *testing.T) { out := ui.OutputWriter.String() must.StrContains(t, out, mockToken.AccessorID) } + +func TestACLTokenSelfCommand_ViaFlag(t *testing.T) { + config := func(c *agent.Config) { + c.ACL.Enabled = true + } + + srv, _, url := testServer(t, true, config) + defer srv.Shutdown() + + state := srv.Agent.Server().State() + + // Bootstrap an initial ACL token + token := srv.RootToken + must.NotNil(t, token) + + ui := cli.NewMockUi() + cmd := &ACLTokenSelfCommand{Meta: Meta{Ui: ui, flagAddress: url}} + + // Create a valid token + mockToken := mock.ACLToken() + mockToken.Policies = []string{acl.PolicyWrite} + mockToken.SetHash() + must.NoError(t, state.UpsertACLTokens(structs.MsgTypeTestSetup, 1000, []*structs.ACLToken{mockToken})) + + // Fetch info on a token with a valid token + code := cmd.Run([]string{"-address=" + url, "-token=" + mockToken.SecretID}) + must.Zero(t, code) + + // Check the output + must.StrContains(t, ui.OutputWriter.String(), mockToken.AccessorID) +}