/
dopplertemplatefuncs.go
102 lines (88 loc) · 2.89 KB
/
dopplertemplatefuncs.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
92
93
94
95
96
97
98
99
100
101
102
package cmd
import (
"encoding/json"
"fmt"
"os"
"os/exec"
"slices"
"strings"
"github.com/twpayne/chezmoi/v2/internal/chezmoilog"
)
type dopplerConfig struct {
Command string `json:"command" mapstructure:"command" yaml:"command"`
Args []string `json:"args" mapstructure:"args" yaml:"args"`
Project string `json:"project" mapstructure:"project" yaml:"project"`
Config string `json:"config" mapstructure:"config" yaml:"config"`
outputCache map[string][]byte
}
func (c *Config) dopplerTemplateFunc(key string, additionalArgs ...string) any {
if len(additionalArgs) > 2 {
// Add one to the number of received arguments as the key
// is the first argument.
panic(fmt.Errorf("expected 1 to 3 arguments, got %d", len(additionalArgs)+1))
}
args := c.appendDopplerAdditionalArgs([]string{"secrets", "download", "--json", "--no-file"}, additionalArgs)
data, err := c.dopplerOutput(args)
if err != nil {
panic(err)
}
var value map[string]any
if err := json.Unmarshal(data, &value); err != nil {
panic(err)
}
secret, ok := value[key]
if !ok {
panic(fmt.Errorf("could not find requested secret: %s", key))
}
return secret
}
func (c *Config) dopplerProjectJSONTemplateFunc(additionalArgs ...string) any {
if len(additionalArgs) > 2 {
panic(fmt.Errorf("expected 0 to 2 arguments, got %d", len(additionalArgs)))
}
args := c.appendDopplerAdditionalArgs([]string{"secrets", "download", "--json", "--no-file"}, additionalArgs)
data, err := c.dopplerOutput(args)
if err != nil {
panic(err)
}
var value any
if err := json.Unmarshal(data, &value); err != nil {
panic(err)
}
return value
}
func (c *Config) appendDopplerAdditionalArgs(args, additionalArgs []string) []string {
if len(additionalArgs) > 0 && additionalArgs[0] != "" {
args = append(args, "--project", additionalArgs[0])
} else if c.Doppler.Project != "" {
args = append(args, "--project", c.Doppler.Project)
}
if len(additionalArgs) > 1 && additionalArgs[1] != "" {
args = append(args, "--config", additionalArgs[1])
} else if c.Doppler.Config != "" {
args = append(args, "--config", c.Doppler.Config)
}
return args
}
func (c *Config) dopplerOutput(args []string) ([]byte, error) {
args = append(slices.Clone(c.Doppler.Args), args...)
key := strings.Join(args, "\x00")
if data, ok := c.Doppler.outputCache[key]; ok {
return data, nil
}
cmd := exec.Command(c.Doppler.Command, args...) //nolint:gosec
// Always run the doppler command in the destination path because doppler uses
// relative paths to find its .doppler.json config file.
cmd.Dir = c.DestDirAbsPath.String()
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
output, err := chezmoilog.LogCmdOutput(c.logger, cmd)
if err != nil {
return nil, newCmdOutputError(cmd, output, err)
}
if c.Doppler.outputCache == nil {
c.Doppler.outputCache = make(map[string][]byte)
}
c.Doppler.outputCache[key] = output
return output, nil
}