-
Notifications
You must be signed in to change notification settings - Fork 2k
/
consul_hook.go
91 lines (75 loc) · 2.27 KB
/
consul_hook.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package taskrunner
import (
"context"
"fmt"
"os"
"path/filepath"
"slices"
"strings"
log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/nomad/client/allocrunner/interfaces"
cstructs "github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/nomad/structs"
)
const (
// consulTokenFilename is the name of the file holding the Consul SI token
// inside the task's secret directory.
consulTokenFilename = "consul_token"
// consulTokenFilePerms is the level of file permissions granted on the file in
// the secrets directory for the task
consulTokenFilePerms = 0640
)
type consulHook struct {
task *structs.Task
tokenDir string
hookResources *cstructs.AllocHookResources
logger log.Logger
}
func newConsulHook(logger log.Logger, tr *TaskRunner) *consulHook {
h := &consulHook{
task: tr.Task(),
tokenDir: tr.taskDir.SecretsDir,
hookResources: tr.allocHookResources,
}
h.logger = logger.Named(h.Name())
return h
}
func (*consulHook) Name() string {
return "consul_task"
}
func (h *consulHook) Prestart(ctx context.Context, req *interfaces.TaskPrestartRequest, resp *interfaces.TaskPrestartResponse) error {
mErr := multierror.Error{}
tokens := h.hookResources.GetConsulTokens()
// Write tokens to tasks' secret dirs
for _, t := range tokens {
for tokenName, token := range t {
s := strings.SplitN(tokenName, "/", 2)
if len(s) < 2 {
continue
}
identity := s[0]
taskName := s[1]
// do not write tokens that do not belong to any of this task's
// identities
if taskName != h.task.Name || !slices.ContainsFunc(
h.task.Identities,
func(id *structs.WorkloadIdentity) bool { return id.Name == identity }) &&
identity != h.task.Identity.Name {
continue
}
tokenPath := filepath.Join(h.tokenDir, consulTokenFilename)
if err := os.WriteFile(tokenPath, []byte(token.SecretID), consulTokenFilePerms); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("failed to write Consul SI token: %w", err))
}
env := map[string]string{
"CONSUL_TOKEN": token.SecretID,
"CONSUL_HTTP_TOKEN": token.SecretID,
}
resp.Env = env
}
}
return mErr.ErrorOrNil()
}