Skip to content

Commit

Permalink
api: add Token field to ServiceRegisterOpts
Browse files Browse the repository at this point in the history
Ongoing work to support Nomad Workload Identity for authenticating with Consul
will mean that Nomad's service registration sync with Consul will want to use
Consul tokens scoped to individual workloads for registering services and
checks. The `ServiceRegisterOpts` type in the API doesn't have an option to pass
the token in, which prevent us from sharing the same Consul connection for all
workloads. Add a `Token` field to match the behavior of `ServiceDeregisterOpts`.
  • Loading branch information
tgross committed Sep 25, 2023
1 parent ca75338 commit 5f81d98
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/18983.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
api: added `Token` field to `ServiceRegisterOpts` type in Agent API
```
7 changes: 7 additions & 0 deletions api/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ type ServiceRegisterOpts struct {
// having to manually deregister checks.
ReplaceExistingChecks bool

// Token is used to provide a per-request ACL token
// which overrides the agent's default token.
Token string

// ctx is an optional context pass through to the underlying HTTP
// request layer. Use WithContext() to set the context.
ctx context.Context
Expand Down Expand Up @@ -835,6 +839,9 @@ func (a *Agent) serviceRegister(service *AgentServiceRegistration, opts ServiceR
if opts.ReplaceExistingChecks {
r.params.Set("replace-existing-checks", "true")
}
if opts.Token != "" {
r.header.Set("X-Consul-Token", opts.Token)
}
_, resp, err := a.c.doRequest(r)
if err != nil {
return err
Expand Down
15 changes: 15 additions & 0 deletions api/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,21 @@ func TestAgent_ServiceRegisterOpts_WithContextTimeout(t *testing.T) {
require.True(t, errors.Is(err, context.DeadlineExceeded), "expected timeout")
}

func TestAgent_ServiceRegisterOpts_Token(t *testing.T) {
c, s := makeACLClient(t)
defer s.Stop()

reg := &AgentServiceRegistration{Name: "example"}
opts := &ServiceRegisterOpts{}
opts.Token = "invalid"
err := c.Agent().ServiceRegisterOpts(reg, *opts)
require.EqualError(t, err, "Unexpected response code: 403 (ACL not found)")

opts.Token = "root"
err = c.Agent().ServiceRegisterOpts(reg, *opts)
require.NoError(t, err)
}

func TestAPI_NewClient_TokenFileCLIFirstPriority(t *testing.T) {
os.Setenv("CONSUL_HTTP_TOKEN_FILE", "httpTokenFile.txt")
os.Setenv("CONSUL_HTTP_TOKEN", "httpToken")
Expand Down

0 comments on commit 5f81d98

Please sign in to comment.