diff --git a/.changelog/26396.txt b/.changelog/26396.txt new file mode 100644 index 000000000..c8e60c7a1 --- /dev/null +++ b/.changelog/26396.txt @@ -0,0 +1,3 @@ +```release-note:bug +cli: Fixed a bug where `acl policy self` command would output all policies when used with a management token +``` diff --git a/command/acl_policy_self.go b/command/acl_policy_self.go index d39b22a60..d5f1528de 100644 --- a/command/acl_policy_self.go +++ b/command/acl_policy_self.go @@ -81,6 +81,18 @@ func (c *ACLPolicySelfCommand) Run(args []string) int { return 1 } + // Read the self token to check its type + token, _, err := client.ACLTokens().Self(nil) + if err != nil { + c.Ui.Error(fmt.Sprintf("Error fetching token: %s", err)) + return 1 + } + + if token.Type == "management" { + c.Ui.Output("This is a management token. No individual policies are assigned.") + return 0 + } + policies, _, err := client.ACLPolicies().Self(nil) if err != nil { c.Ui.Error(fmt.Sprintf("Error fetching WI policies: %s", err)) diff --git a/command/acl_policy_self_test.go b/command/acl_policy_self_test.go index 21fd17e7c..d9835cdac 100644 --- a/command/acl_policy_self_test.go +++ b/command/acl_policy_self_test.go @@ -10,70 +10,70 @@ import ( "github.com/hashicorp/nomad/command/agent" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" - "github.com/hashicorp/nomad/testutil" "github.com/shoenig/test/must" ) func TestACLPolicySelfCommand_ViaEnvVar(t *testing.T) { + const policyName = "nw" + config := func(c *agent.Config) { c.ACL.Enabled = true } - srv, _, url := testServer(t, true, config) - defer srv.Shutdown() + t.Cleanup(srv.Shutdown) - state := srv.Agent.Server().State() - - // Bootstrap an initial ACL token - token := srv.RootToken - must.NotNil(t, token) - - // Create a minimal job - job := mock.MinJob() - - // Add a job policy - polArgs := structs.ACLPolicyUpsertRequest{ - Policies: []*structs.ACLPolicy{ - { - Name: "nw", - Description: "test job can write to nodes", - Rules: `node { policy = "write" }`, - JobACL: &structs.JobACL{ - Namespace: job.Namespace, - JobID: job.ID, + createPolicy := func(t *testing.T, srv *agent.TestAgent, token *structs.ACLToken, job *structs.Job) { + args := structs.ACLPolicyUpsertRequest{ + Policies: []*structs.ACLPolicy{ + { + Name: policyName, + Description: "test job can write to nodes", + Rules: `node { policy = "write" }`, + JobACL: &structs.JobACL{ + Namespace: job.Namespace, + JobID: job.ID, + }, }, }, - }, - WriteRequest: structs.WriteRequest{ - Region: job.Region, - AuthToken: token.SecretID, - Namespace: job.Namespace, - }, + WriteRequest: structs.WriteRequest{ + Region: job.Region, + AuthToken: token.SecretID, + Namespace: job.Namespace, + }, + } + reply := structs.GenericResponse{} + must.NoError(t, srv.RPC("ACL.UpsertPolicies", &args, &reply)) } - polReply := structs.GenericResponse{} - must.NoError(t, srv.RPC("ACL.UpsertPolicies", &polArgs, &polReply)) - must.NonZero(t, polReply.WriteMeta.Index) - ui := cli.NewMockUi() - cmd := &ACLPolicySelfCommand{Meta: Meta{Ui: ui, flagAddress: url}} + runCommand := func(t *testing.T, url, token string) string { + ui := cli.NewMockUi() + cmd := &ACLPolicySelfCommand{Meta: Meta{Ui: ui, flagAddress: url}} + t.Setenv("NOMAD_TOKEN", token) + must.Zero(t, cmd.Run([]string{"-address=" + url})) + return ui.OutputWriter.String() + } - allocs := testutil.WaitForRunningWithToken(t, srv.RPC, job, token.SecretID) - must.Len(t, 1, allocs) + rootToken := srv.RootToken - alloc, err := state.AllocByID(nil, allocs[0].ID) - must.NoError(t, err) - must.MapContainsKey(t, alloc.SignedIdentities, "t") - wid := alloc.SignedIdentities["t"] + t.Run("SelfPolicy returns correct output for management token", func(t *testing.T) { + createPolicy(t, srv, rootToken, mock.MinJob()) - // Fetch info on policies with a JWT - t.Setenv("NOMAD_TOKEN", wid) - code := cmd.Run([]string{"-address=" + url}) - must.Zero(t, code) + out := runCommand(t, url, rootToken.SecretID) + must.StrContains(t, out, "This is a management token. No individual policies are assigned.") + }) - // Check the output - out := ui.OutputWriter.String() - must.StrContains(t, out, polArgs.Policies[0].Name) + t.Run("SelfPolicy returns correct output for client token", func(t *testing.T) { + job := mock.MinJob() + createPolicy(t, srv, rootToken, job) - // make sure we put the job ACLs in there, too - must.StrContains(t, out, polArgs.Policies[0].JobACL.JobID) + clientToken := mock.ACLToken() + clientToken.Policies = []string{policyName} + must.NoError(t, srv.Agent.Server().State().UpsertACLTokens( + structs.MsgTypeTestSetup, 1, []*structs.ACLToken{clientToken}, + )) + + out := runCommand(t, url, clientToken.SecretID) + must.StrContains(t, out, policyName) + must.StrContains(t, out, job.ID) + }) }