Skip to content

Commit

Permalink
Merge pull request #636 from seh/revise-sops-format-detection-for-gen…
Browse files Browse the repository at this point in the history
…erated-secrets

Use Secret generator keys for SOPS format hint
  • Loading branch information
stefanprodan authored Apr 27, 2022
2 parents ef77093 + e6beca1 commit ac4594d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 27 deletions.
27 changes: 15 additions & 12 deletions controllers/kustomization_decryptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,21 +369,16 @@ func (d *KustomizeDecryptor) DecryptEnvSources(path string) error {

// decryptKustomizationEnvSources returns a visitKustomization implementation
// which attempts to decrypt any EnvSources entry it finds in the Kustomization
// file it is called with.
// After a successful decrypt, the absolute path of the file is added to the
// file with which it is called.
// After decrypting successfully, it adds the absolute path of the file to the
// given map.
func (d *KustomizeDecryptor) decryptKustomizationEnvSources(visited map[string]struct{}) visitKustomization {
return func(root, path string, kus *kustypes.Kustomization) error {
visitRef := func(ref string, format formats.Format) error {
refParts := strings.Split(ref, "=")
if len(refParts) > 1 {
ref = refParts[1]
visitRef := func(sourcePath string, format formats.Format) error {
if !filepath.IsAbs(sourcePath) {
sourcePath = filepath.Join(path, sourcePath)
}
if !filepath.IsAbs(ref) {
ref = filepath.Join(path, ref)
}

absRef, _, err := securePaths(root, ref)
absRef, _, err := securePaths(root, sourcePath)
if err != nil {
return err
}
Expand All @@ -403,7 +398,15 @@ func (d *KustomizeDecryptor) decryptKustomizationEnvSources(visited map[string]s

for _, gen := range kus.SecretGenerator {
for _, fileSrc := range gen.FileSources {
if err := visitRef(fileSrc, formats.FormatForPath(fileSrc)); err != nil {
parts := strings.SplitN(fileSrc, "=", 2)
key := parts[0]
var filePath string
if len(parts) > 1 {
filePath = parts[1]
} else {
filePath = key
}
if err := visitRef(filePath, formats.FormatForPath(key)); err != nil {
return err
}
}
Expand Down
36 changes: 23 additions & 13 deletions controllers/kustomization_decryptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ func TestKustomizeDecryptor_DecryptResource(t *testing.T) {
},
}

t.Run("SOPS encrypted resource", func(t *testing.T) {
t.Run("SOPS-encrypted Secret resource", func(t *testing.T) {
g := NewWithT(t)

kus := kustomization.DeepCopy()
Expand Down Expand Up @@ -736,7 +736,7 @@ func TestKustomizeDecryptor_DecryptResource(t *testing.T) {
g.Expect(got.MarshalJSON()).To(Equal(secretData))
})

t.Run("SOPS encrypted binary Secret data field", func(t *testing.T) {
t.Run("SOPS-encrypted binary-format Secret data field", func(t *testing.T) {
g := NewWithT(t)

kus := kustomization.DeepCopy()
Expand Down Expand Up @@ -771,7 +771,7 @@ func TestKustomizeDecryptor_DecryptResource(t *testing.T) {
g.Expect(got.GetDataMap()).To(HaveKeyWithValue("file.ini", base64.StdEncoding.EncodeToString(plainData)))
})

t.Run("SOPS encrypted YAML Secret data field", func(t *testing.T) {
t.Run("SOPS-encrypted YAML-format Secret data field", func(t *testing.T) {
g := NewWithT(t)

kus := kustomization.DeepCopy()
Expand Down Expand Up @@ -849,12 +849,14 @@ func TestKustomizeDecryptor_DecryptResource(t *testing.T) {

func TestKustomizeDecryptor_decryptKustomizationEnvSources(t *testing.T) {
type file struct {
name string
symlink string
data []byte
encrypt bool
expectData bool
name string
symlink string
data []byte
originalFormat *formats.Format
encrypt bool
expectData bool
}
binaryFormat := formats.Binary
tests := []struct {
name string
wordirSuffix string
Expand All @@ -869,6 +871,9 @@ func TestKustomizeDecryptor_decryptKustomizationEnvSources(t *testing.T) {
path: "subdir",
files: []file{
{name: "subdir/app.env", data: []byte("var1=value1\n"), encrypt: true, expectData: true},
// NB: Despite the file extension representing the SOPS-encrypted JSON output
// format, the original data is plain text, or "binary."
{name: "subdir/combination.json", data: []byte("The safe combination is ..."), originalFormat: &binaryFormat, encrypt: true, expectData: true},
{name: "subdir/file.txt", data: []byte("file"), encrypt: true, expectData: true},
{name: "secret.env", data: []byte("var2=value2\n"), encrypt: true, expectData: true},
},
Expand All @@ -877,13 +882,13 @@ func TestKustomizeDecryptor_decryptKustomizationEnvSources(t *testing.T) {
GeneratorArgs: kustypes.GeneratorArgs{
Name: "envSecret",
KvPairSources: kustypes.KvPairSources{
FileSources: []string{"file.txt"},
EnvSources: []string{"app.env", "key=../secret.env"},
FileSources: []string{"file.txt", "combo=combination.json"},
EnvSources: []string{"app.env", "../secret.env"},
},
},
},
},
expectVisited: []string{"subdir/app.env", "subdir/file.txt", "secret.env"},
expectVisited: []string{"subdir/app.env", "subdir/combination.json", "subdir/file.txt", "secret.env"},
},
{
name: "decryption error",
Expand Down Expand Up @@ -987,7 +992,12 @@ func TestKustomizeDecryptor_decryptKustomizationEnvSources(t *testing.T) {
}
data := f.data
if f.encrypt {
format := formats.FormatForPath(f.name)
var format formats.Format
if f.originalFormat != nil {
format = *f.originalFormat
} else {
format = formats.FormatForPath(f.name)
}
data, err = d.sopsEncryptWithFormat(sops.Metadata{
KeyGroups: []sops.KeyGroup{
{&sopsage.MasterKey{Recipient: id.Recipient().String()}},
Expand Down Expand Up @@ -1159,7 +1169,7 @@ func TestKustomizeDecryptor_decryptSopsFile(t *testing.T) {

b, err := os.ReadFile(filepath.Join(tmpDir, f.name))
g.Expect(err).ToNot(HaveOccurred())
g.Expect(bytes.Compare(f.data, b) == 0).To(Equal(f.expectData))
g.Expect(bytes.Equal(f.data, b)).To(Equal(f.expectData))
}
})
}
Expand Down
2 changes: 0 additions & 2 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/kubernetes/scheme"
kuberecorder "k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
Expand All @@ -68,7 +67,6 @@ var (
k8sClient client.Client
testEnv *testenv.Environment
testServer *testserver.ArtifactServer
testEventsH kuberecorder.EventRecorder
testMetricsH controller.Metrics
ctx = ctrl.SetupSignalHandler()
kubeConfig []byte
Expand Down

0 comments on commit ac4594d

Please sign in to comment.