diff --git a/internal/decryptor/decryptor.go b/internal/decryptor/decryptor.go index d2bcde94..e2d366d7 100644 --- a/internal/decryptor/decryptor.go +++ b/internal/decryptor/decryptor.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "io/fs" + "net/url" "os" "path/filepath" "strings" @@ -571,6 +572,11 @@ func (d *Decryptor) decryptKustomizationSources(visited map[string]struct{}) vis if patch.Path == "" { continue } + + if isRemoteURL(patch.Path) { + continue + } + // Determine the format for the patch, defaulting to YAML if not specified. format := formatForPath(patch.Path) // Visit the patch reference and attempt to decrypt it. @@ -836,6 +842,17 @@ func recurseKustomizationFiles(root, path string, visit visitKustomization, visi return nil } +func isRemoteURL(path string) bool { + u, err := url.Parse(path) + if err != nil { + return false + } + + // A remote URL will have a scheme (like "http", "https", "ssh") + // AND a host (like "example.com"). + return u.Scheme != "" && u.Host != "" +} + // isSOPSEncryptedResource detects if the given resource is a SOPS' encrypted // resource by looking for ".sops" and ".sops.mac" fields. func isSOPSEncryptedResource(res *resource.Resource) bool { diff --git a/internal/decryptor/decryptor_test.go b/internal/decryptor/decryptor_test.go index 9fa82206..764ab495 100644 --- a/internal/decryptor/decryptor_test.go +++ b/internal/decryptor/decryptor_test.go @@ -818,6 +818,7 @@ func TestDecryptor_decryptKustomizationSources(t *testing.T) { wordirSuffix string path string files []file + patch []kustypes.Patch secretGenerator []kustypes.SecretArgs expectVisited []string wantErr error @@ -922,6 +923,34 @@ func TestDecryptor_decryptKustomizationSources(t *testing.T) { wantErr: &fs.PathError{Op: "lstat", Path: "data.env", Err: fmt.Errorf("")}, expectVisited: []string{}, }, + { + name: "ignore remote patches", + path: "subdir", + files: []file{ + {name: "subdir/file.txt", data: []byte("file"), encrypt: true, expectData: true}, + {name: "subdir/patch.yaml", data: []byte("op: add\n"), encrypt: true, expectData: true}, + }, + patch: []kustypes.Patch{ + { + Path: "patch.yaml", + }, + { + // this patch gets ignored due to being remote + Path: "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/examples/wordpress/patch.yaml", + }, + }, + secretGenerator: []kustypes.SecretArgs{ + { + GeneratorArgs: kustypes.GeneratorArgs{ + Name: "envSecret", + KvPairSources: kustypes.KvPairSources{ + FileSources: []string{"file.txt"}, + }, + }, + }, + }, + expectVisited: []string{"subdir/patch.yaml", "subdir/file.txt"}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -967,7 +996,10 @@ func TestDecryptor_decryptKustomizationSources(t *testing.T) { visited := make(map[string]struct{}, 0) visit := d.decryptKustomizationSources(visited) - kus := &kustypes.Kustomization{SecretGenerator: tt.secretGenerator} + kus := &kustypes.Kustomization{ + Patches: tt.patch, + SecretGenerator: tt.secretGenerator, + } err = visit(root, tt.path, kus) if tt.wantErr == nil {