diff --git a/client/allocrunner/taskrunner/sids_hook.go b/client/allocrunner/taskrunner/sids_hook.go index d66723556..7cc59ee55 100644 --- a/client/allocrunner/taskrunner/sids_hook.go +++ b/client/allocrunner/taskrunner/sids_hook.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/nomad/client/allocrunner/interfaces" ti "github.com/hashicorp/nomad/client/allocrunner/taskrunner/interfaces" "github.com/hashicorp/nomad/client/consul" + cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/nomad/structs" ) @@ -46,11 +47,12 @@ const ( ) type sidsHookConfig struct { - alloc *structs.Allocation - task *structs.Task - sidsClient consul.ServiceIdentityAPI - lifecycle ti.TaskLifecycle - logger hclog.Logger + alloc *structs.Allocation + task *structs.Task + sidsClient consul.ServiceIdentityAPI + lifecycle ti.TaskLifecycle + logger hclog.Logger + allocHookResources *cstructs.AllocHookResources } // Service Identities hook for managing SI tokens of connect enabled tasks. @@ -80,17 +82,22 @@ type sidsHook struct { // firstRun keeps track of whether the hook is being called for the first // time (for this task) during the lifespan of the Nomad Client process. firstRun bool + + // allocHookResources gives us access to Consul tokens that may have been + // set by the consul_hook + allocHookResources *cstructs.AllocHookResources } func newSIDSHook(c sidsHookConfig) *sidsHook { return &sidsHook{ - alloc: c.alloc, - task: c.task, - sidsClient: c.sidsClient, - lifecycle: c.lifecycle, - derivationTimeout: sidsDerivationTimeout, - logger: c.logger.Named(sidsHookName), - firstRun: true, + alloc: c.alloc, + task: c.task, + sidsClient: c.sidsClient, + lifecycle: c.lifecycle, + derivationTimeout: sidsDerivationTimeout, + logger: c.logger.Named(sidsHookName), + firstRun: true, + allocHookResources: c.allocHookResources, } } @@ -118,6 +125,32 @@ func (h *sidsHook) Prestart( return err } + // if we're using Workload Identities then this Connect task should already + // have a token stored under the cluster + service ID. + tokens := h.allocHookResources.GetConsulTokens() + + // Find the group-level service that this task belongs to + tg := h.alloc.Job.LookupTaskGroup(h.alloc.TaskGroup) + serviceName := h.task.Kind.Value() + var serviceIdentityName string + var cluster string + for _, service := range tg.Services { + if service.Name == serviceName { + serviceIdentityName = service.MakeUniqueIdentityName() + cluster = service.Cluster + break + } + } + if cluster != "" && serviceIdentityName != "" { + if token, ok := tokens[cluster][serviceIdentityName]; ok { + if err := h.writeToken(req.TaskDir.SecretsDir, token); err != nil { + return err + } + resp.Done = true + return nil + } + } + // need to ask for a new SI token & persist it to disk if token == "" { if token, err = h.deriveSIToken(ctx); err != nil { diff --git a/client/allocrunner/taskrunner/task_runner_hooks.go b/client/allocrunner/taskrunner/task_runner_hooks.go index 74e62f008..20fc82f34 100644 --- a/client/allocrunner/taskrunner/task_runner_hooks.go +++ b/client/allocrunner/taskrunner/task_runner_hooks.go @@ -142,11 +142,12 @@ func (tr *TaskRunner) initHooks() { // with a consul token, indicating that Consul ACLs are enabled if tr.clientConfig.ConsulConfig.Token != "" { tr.runnerHooks = append(tr.runnerHooks, newSIDSHook(sidsHookConfig{ - alloc: tr.Alloc(), - task: tr.Task(), - sidsClient: tr.siClient, - lifecycle: tr, - logger: hookLogger, + alloc: tr.Alloc(), + task: tr.Task(), + sidsClient: tr.siClient, + lifecycle: tr, + logger: hookLogger, + allocHookResources: tr.allocHookResources, })) } diff --git a/client/allocrunner/taskrunner/task_runner_test.go b/client/allocrunner/taskrunner/task_runner_test.go index 8fc5e42ae..1c011a40f 100644 --- a/client/allocrunner/taskrunner/task_runner_test.go +++ b/client/allocrunner/taskrunner/task_runner_test.go @@ -28,6 +28,7 @@ import ( regMock "github.com/hashicorp/nomad/client/serviceregistration/mock" "github.com/hashicorp/nomad/client/serviceregistration/wrapper" cstate "github.com/hashicorp/nomad/client/state" + cstructs "github.com/hashicorp/nomad/client/structs" ctestutil "github.com/hashicorp/nomad/client/testutil" "github.com/hashicorp/nomad/client/vaultclient" "github.com/hashicorp/nomad/client/widmgr" @@ -146,6 +147,7 @@ func testTaskRunnerConfig(t *testing.T, alloc *structs.Allocation, taskName stri Getter: getter.TestSandbox(t), Wranglers: proclib.MockWranglers(t), WIDMgr: widmgr.NewWIDMgr(widsigner, alloc, logger), + AllocHookResources: cstructs.NewAllocHookResources(), } return conf, trCleanup