From eff3dc09b6444e47497ac0240184de7995d3256a Mon Sep 17 00:00:00 2001 From: Dan Upton Date: Thu, 2 Dec 2021 17:05:27 +0000 Subject: [PATCH] Rename `agent_master` ACL token in the API and CLI (#11669) --- .changelog/11669.txt | 6 +++ agent/agent_endpoint.go | 2 +- agent/agent_endpoint_test.go | 20 +++++++++- api/agent.go | 37 ++++++++++++++----- api/agent_test.go | 7 ++++ command/acl/agenttokens/agent_tokens.go | 8 ++-- command/acl/agenttokens/agent_tokens_test.go | 6 +-- website/content/api-docs/agent/index.mdx | 23 ++++++++---- .../content/commands/acl/set-agent-token.mdx | 5 ++- 9 files changed, 87 insertions(+), 27 deletions(-) create mode 100644 .changelog/11669.txt diff --git a/.changelog/11669.txt b/.changelog/11669.txt new file mode 100644 index 000000000..9cd63035e --- /dev/null +++ b/.changelog/11669.txt @@ -0,0 +1,6 @@ +```release-note:deprecation +api: `/v1/agent/token/agent_master` is deprecated and will be removed in a future major release - use `/v1/agent/token/agent_recovery` instead +``` +```release-note:breaking-change +cli: `consul acl set-agent-token master` has been replaced with `consul acl set-agent-token recovery` +``` diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go index e1ad1f2a1..0222950f4 100644 --- a/agent/agent_endpoint.go +++ b/agent/agent_endpoint.go @@ -1444,7 +1444,7 @@ func (s *HTTPHandlers) AgentToken(resp http.ResponseWriter, req *http.Request) ( triggerAntiEntropySync = true } - case "acl_agent_master_token", "agent_master": + case "acl_agent_master_token", "agent_master", "agent_recovery": s.agent.tokens.UpdateAgentMasterToken(args.Token, token_store.TokenSourceAPI) case "acl_replication_token", "replication": diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go index 9c2da7a9e..a1984c946 100644 --- a/agent/agent_endpoint_test.go +++ b/agent/agent_endpoint_test.go @@ -5308,7 +5308,7 @@ func TestAgent_Token(t *testing.T) { effective: tokens{master: "M"}, }, { - name: "set master ", + name: "set master", method: "PUT", url: "agent_master?token=root", body: body("M"), @@ -5316,6 +5316,15 @@ func TestAgent_Token(t *testing.T) { raw: tokens{master: "M", masterSource: tokenStore.TokenSourceAPI}, effective: tokens{master: "M"}, }, + { + name: "set recovery", + method: "PUT", + url: "agent_recovery?token=root", + body: body("R"), + code: http.StatusOK, + raw: tokens{master: "R", masterSource: tokenStore.TokenSourceAPI}, + effective: tokens{master: "R", masterSource: tokenStore.TokenSourceAPI}, + }, { name: "set repl legacy", method: "PUT", @@ -5388,6 +5397,15 @@ func TestAgent_Token(t *testing.T) { init: tokens{master: "M"}, raw: tokens{masterSource: tokenStore.TokenSourceAPI}, }, + { + name: "clear recovery", + method: "PUT", + url: "agent_recovery?token=root", + body: body(""), + code: http.StatusOK, + init: tokens{master: "R"}, + raw: tokens{masterSource: tokenStore.TokenSourceAPI}, + }, { name: "clear repl legacy", method: "PUT", diff --git a/api/agent.go b/api/agent.go index c4efa0efe..785c9e2cc 100644 --- a/api/agent.go +++ b/api/agent.go @@ -1287,25 +1287,33 @@ func (a *Agent) UpdateACLReplicationToken(token string, q *WriteOptions) (*Write // UpdateDefaultACLToken updates the agent's "default" token. See updateToken // for more details func (a *Agent) UpdateDefaultACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback("default", "acl_token", token, q) + return a.updateTokenFallback(token, q, "default", "acl_token") } // UpdateAgentACLToken updates the agent's "agent" token. See updateToken // for more details func (a *Agent) UpdateAgentACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback("agent", "acl_agent_token", token, q) + return a.updateTokenFallback(token, q, "agent", "acl_agent_token") +} + +// UpdateAgentRecoveryACLToken updates the agent's "agent_recovery" token. See updateToken +// for more details. +func (a *Agent) UpdateAgentRecoveryACLToken(token string, q *WriteOptions) (*WriteMeta, error) { + return a.updateTokenFallback(token, q, "agent_recovery", "agent_master", "acl_agent_master_token") } // UpdateAgentMasterACLToken updates the agent's "agent_master" token. See updateToken -// for more details +// for more details. +// +// DEPRECATED - Prefer UpdateAgentRecoveryACLToken for v1.11 and above. func (a *Agent) UpdateAgentMasterACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback("agent_master", "acl_agent_master_token", token, q) + return a.updateTokenFallback(token, q, "agent_master", "acl_agent_master_token") } // UpdateReplicationACLToken updates the agent's "replication" token. See updateToken // for more details func (a *Agent) UpdateReplicationACLToken(token string, q *WriteOptions) (*WriteMeta, error) { - return a.updateTokenFallback("replication", "acl_replication_token", token, q) + return a.updateTokenFallback(token, q, "replication", "acl_replication_token") } // updateToken can be used to update one of an agent's ACL tokens after the agent has @@ -1316,10 +1324,21 @@ func (a *Agent) updateToken(target, token string, q *WriteOptions) (*WriteMeta, return meta, err } -func (a *Agent) updateTokenFallback(target, fallback, token string, q *WriteOptions) (*WriteMeta, error) { - meta, status, err := a.updateTokenOnce(target, token, q) - if err != nil && status == 404 { - meta, _, err = a.updateTokenOnce(fallback, token, q) +func (a *Agent) updateTokenFallback(token string, q *WriteOptions, targets ...string) (*WriteMeta, error) { + if len(targets) == 0 { + panic("targets must not be empty") + } + + var ( + meta *WriteMeta + err error + ) + for _, target := range targets { + var status int + meta, status, err = a.updateTokenOnce(target, token, q) + if err == nil && status != http.StatusNotFound { + return meta, err + } } return meta, err } diff --git a/api/agent_test.go b/api/agent_test.go index f87509251..16fc066ff 100644 --- a/api/agent_test.go +++ b/api/agent_test.go @@ -1518,6 +1518,10 @@ func TestAPI_AgentUpdateToken(t *testing.T) { t.Fatalf("err: %v", err) } + if _, err := agent.UpdateAgentRecoveryACLToken("root", nil); err != nil { + t.Fatalf("err: %v", err) + } + if _, err := agent.UpdateReplicationACLToken("root", nil); err != nil { t.Fatalf("err: %v", err) } @@ -1570,6 +1574,9 @@ func TestAPI_AgentUpdateToken(t *testing.T) { _, err = agent.UpdateAgentMasterACLToken("root", nil) require.NoError(t, err) + _, err = agent.UpdateAgentRecoveryACLToken("root", nil) + require.NoError(t, err) + _, err = agent.UpdateReplicationACLToken("root", nil) require.NoError(t, err) }) diff --git a/command/acl/agenttokens/agent_tokens.go b/command/acl/agenttokens/agent_tokens.go index 914efb2c2..974c8e613 100644 --- a/command/acl/agenttokens/agent_tokens.go +++ b/command/acl/agenttokens/agent_tokens.go @@ -54,8 +54,8 @@ func (c *cmd) Run(args []string) int { _, err = client.Agent().UpdateDefaultACLToken(token, nil) case "agent": _, err = client.Agent().UpdateAgentACLToken(token, nil) - case "master": - _, err = client.Agent().UpdateAgentMasterACLToken(token, nil) + case "recovery": + _, err = client.Agent().UpdateAgentRecoveryACLToken(token, nil) case "replication": _, err = client.Agent().UpdateReplicationACLToken(token, nil) default: @@ -78,7 +78,7 @@ func (c *cmd) dataFromArgs(args []string) (string, string, error) { return "", "", fmt.Errorf("Missing TYPE and TOKEN arguments") case 1: switch args[0] { - case "default", "agent", "master", "replication": + case "default", "agent", "recovery", "replication": return "", "", fmt.Errorf("Missing TOKEN argument") default: return "", "", fmt.Errorf("MISSING TYPE argument") @@ -121,7 +121,7 @@ Usage: consul acl set-agent-token [options] TYPE TOKEN agent The token that the agent will use for internal agent operations. If not given then the default token is used for these operations. - master This sets the token that can be used to access the Agent APIs in + recovery This sets the token that can be used to access the Agent APIs in the event that the ACL datacenter cannot be reached. replication This is the token that the agent will use for replication diff --git a/command/acl/agenttokens/agent_tokens_test.go b/command/acl/agenttokens/agent_tokens_test.go index e5d20d047..5e6430a9b 100644 --- a/command/acl/agenttokens/agent_tokens_test.go +++ b/command/acl/agenttokens/agent_tokens_test.go @@ -33,7 +33,7 @@ func TestAgentTokensCommand(t *testing.T) { enabled = true tokens { - master = "root" + initial_management = "root" } }`) @@ -78,11 +78,11 @@ func TestAgentTokensCommand(t *testing.T) { assert.Empty(ui.ErrorWriter.String()) } - // master token + // recovery token { args := []string{ "-http-addr=" + a.HTTPAddr(), - "master", + "recovery", token.SecretID, } diff --git a/website/content/api-docs/agent/index.mdx b/website/content/api-docs/agent/index.mdx index cc4d90369..8062593f9 100644 --- a/website/content/api-docs/agent/index.mdx +++ b/website/content/api-docs/agent/index.mdx @@ -727,18 +727,27 @@ only if the [`acl.enable_token_persistence`](/docs/agent/options#acl_enable_toke configuration is `true`. When not being persisted, they will need to be reset if the agent is restarted. -| Method | Path | Produces | -| ------ | --------------------------- | ------------------ | -| `PUT` | `/agent/token/default` | `application/json` | -| `PUT` | `/agent/token/agent` | `application/json` | -| `PUT` | `/agent/token/agent_master` | `application/json` | -| `PUT` | `/agent/token/replication` | `application/json` | +| Method | Path | Produces | +| ------ | ----------------------------- | ------------------ | +| `PUT` | `/agent/token/default` | `application/json` | +| `PUT` | `/agent/token/agent` | `application/json` | +| `PUT` | `/agent/token/agent_recovery` | `application/json` | +| `PUT` | `/agent/token/replication` | `application/json` | The paths above correspond to the token names as found in the agent configuration: [`default`](/docs/agent/options#acl_tokens_default), [`agent`](/docs/agent/options#acl_tokens_agent), -[`agent_master`](/docs/agent/options#acl_tokens_agent_master), and +[`agent_recovery`](/docs/agent/options#acl_tokens_agent_recovery), and [`replication`](/docs/agent/options#acl_tokens_replication). +-> **Deprecation Note:** The following paths were deprecated in version 1.11 + +| Method | Path | Produces | +| ------ | --------------------------- | ------------------ | +| `PUT` | `/agent/token/agent_master` | `application/json` | + +The paths above correspond to the token names as found in the agent configuration: +[`agent_master`](/docs/agent/options#acl_tokens_agent_master). + -> **Deprecation Note:** The following paths were deprecated in version 1.4.3 | Method | Path | Produces | diff --git a/website/content/commands/acl/set-agent-token.mdx b/website/content/commands/acl/set-agent-token.mdx index da2717573..d5caa308c 100644 --- a/website/content/commands/acl/set-agent-token.mdx +++ b/website/content/commands/acl/set-agent-token.mdx @@ -28,8 +28,9 @@ Usage: `consul acl set-agent-token [options] TYPE TOKEN` - `agent` - The token that the agent will use for internal agent operations. If not given then the default token is used for these operations. -- `master` - This sets the token that can be used to access the Agent APIs in - the event that the ACL datacenter cannot be reached. +- `recovery` - This sets the token that can be used to access the Agent APIs + in the event that the ACL datacenter cannot be reached. In Consul versions + prior to 1.11, this token type was called `master`. - `replication` - This is the token that the agent will use for replication operations. This token will need to be configured with read access to