Repository navigation
Expand file tree
/
Copy pathsops_encryptor.go
More file actions
94 lines (79 loc) · 2.42 KB
/
Copy pathsops_encryptor.go
File metadata and controls
94 lines (79 loc) · 2.42 KB
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
// SPDX-License-Identifier: Apache-2.0
package git
import (
"bytes"
"context"
"fmt"
"os"
"os/exec"
"slices"
"strings"
"github.com/ConfigButler/gitops-reverser/internal/manifestanalyzer"
)
// SOPSEncryptor encrypts YAML by invoking the external sops binary.
type SOPSEncryptor struct {
binaryPath string
configPath string
workDir string
env map[string]string
}
// NewSOPSEncryptor creates an Encryptor that shells out to sops.
func NewSOPSEncryptor(binaryPath, configPath string) *SOPSEncryptor {
return NewSOPSEncryptorWithEnv(binaryPath, configPath, "", nil)
}
// NewSOPSEncryptorWithEnv creates an Encryptor that shells out to sops with additional environment variables.
func NewSOPSEncryptorWithEnv(binaryPath, configPath, workDir string, env map[string]string) *SOPSEncryptor {
copiedEnv := make(map[string]string, len(env))
for key, value := range env {
copiedEnv[key] = value
}
return &SOPSEncryptor{
binaryPath: binaryPath,
configPath: configPath,
workDir: workDir,
env: copiedEnv,
}
}
// Encrypt streams plaintext YAML to sops over stdin and returns encrypted YAML bytes.
func (e *SOPSEncryptor) Encrypt(ctx context.Context, plain []byte, meta ResourceMeta) ([]byte, error) {
args := []string{
"--encrypt",
"--input-type", "yaml",
"--output-type", "yaml",
"--filename-override", sopsFilenameOverride(meta),
"/dev/stdin",
}
if strings.TrimSpace(e.configPath) != "" {
args = append([]string{"--config", e.configPath}, args...)
}
cmd := newCommandContext(ctx, e.binaryPath, args...)
if strings.TrimSpace(e.workDir) != "" {
cmd.Dir = e.workDir
}
cmd.Env = buildCommandEnvironment(e.env)
cmd.Stdin = bytes.NewReader(plain)
out, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("sops encryption failed: %w: %s", err, strings.TrimSpace(string(out)))
}
return out, nil
}
func newCommandContext(ctx context.Context, name string, args ...string) *exec.Cmd {
return exec.CommandContext(ctx, name, args...)
}
func buildCommandEnvironment(extra map[string]string) []string {
environment := slices.Clone(os.Environ())
if len(extra) == 0 {
return environment
}
for key, value := range extra {
environment = append(environment, fmt.Sprintf("%s=%s", key, value))
}
return environment
}
func sopsFilenameOverride(meta ResourceMeta) string {
if meta.Identifier.Name == "" {
return "resource.sops.yaml"
}
return manifestanalyzer.BuiltinGitPath(meta.Identifier, true)
}