master
go 48 lines 1.19 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package secretresolver
4
5 import (
6 "context"
7 "errors"
8 "fmt"
9 "io"
10 "os/exec"
11 "path/filepath"
12 "strings"
13 "time"
14 )
15
16 func (r *Resolver) resolveCmd(ctx context.Context, cmdLine, original string) (string, error) {
17 parts := strings.Fields(cmdLine)
18 if len(parts) == 0 {
19 return "", fmt.Errorf("resolving secret '%s': empty command", original)
20 }
21 if !filepath.IsAbs(parts[0]) {
22 return "", fmt.Errorf("resolving secret '%s': command path must be absolute, got '%s'", original, parts[0])
23 }
24
25 if ctx == nil {
26 ctx = context.Background()
27 }
28 timeout := r.cmdTimeout
29 if timeout <= 0 {
30 timeout = 10 * time.Second
31 }
32 ctx, cancel := context.WithTimeout(ctx, timeout)
33 defer cancel()
34
35 cmd := exec.CommandContext(ctx, parts[0], parts[1:]...)
36 cmd.Stderr = io.Discard
37 out, err := cmd.Output()
38 if err != nil {
39 if errors.Is(ctx.Err(), context.DeadlineExceeded) {
40 return "", fmt.Errorf("resolving secret '%s': command timed out after %s", original, timeout)
41 }
42 return "", fmt.Errorf("resolving secret '%s': command failed: %w", original, err)
43 }
44
45 value := strings.TrimSpace(string(out))
46 logResolved(ctx, "resolved secret via command '%s'", parts[0])
47 return value, nil
48 }