diff --git a/pkg/iac/scanners/terraform/parser/resolvers/cache.go b/pkg/iac/scanners/terraform/parser/resolvers/cache.go index e08c43ff3ba0..c8b2f660ed33 100644 --- a/pkg/iac/scanners/terraform/parser/resolvers/cache.go +++ b/pkg/iac/scanners/terraform/parser/resolvers/cache.go @@ -51,7 +51,7 @@ func (r *cacheResolver) Resolve(_ context.Context, _ fs.FS, opt Options) (filesy return nil, "", "", false, nil } - src := removeSubdirFromSource(opt.Source) + src, subdir := splitPackageSubdirRaw(opt.Source) key := cacheKey(src, opt.Version) opt.Debug("Trying to resolve: %s", key) @@ -62,7 +62,7 @@ func (r *cacheResolver) Resolve(_ context.Context, _ fs.FS, opt Options) (filesy return nil, "", "", true, err } - return os.DirFS(filepath.Join(cacheDir, key)), opt.OriginalSource, ".", true, nil + return os.DirFS(filepath.Join(cacheDir, key)), opt.OriginalSource, subdir, true, nil } return nil, "", "", false, nil } diff --git a/pkg/iac/scanners/terraform/parser/resolvers/cache_integration_test.go b/pkg/iac/scanners/terraform/parser/resolvers/cache_integration_test.go index a7c6704b6708..43ad7f06b15b 100644 --- a/pkg/iac/scanners/terraform/parser/resolvers/cache_integration_test.go +++ b/pkg/iac/scanners/terraform/parser/resolvers/cache_integration_test.go @@ -21,9 +21,10 @@ func TestResolveModuleFromCache(t *testing.T) { } tests := []struct { - name string - opts resolvers.Options - firstResolver moduleResolver + name string + opts resolvers.Options + firstResolver moduleResolver + expectedSubdir string }{ { name: "registry", @@ -32,7 +33,8 @@ func TestResolveModuleFromCache(t *testing.T) { Source: "terraform-aws-modules/s3-bucket/aws", Version: "4.1.2", }, - firstResolver: resolvers.Registry, + firstResolver: resolvers.Registry, + expectedSubdir: ".", }, { name: "registry with subdir", @@ -41,7 +43,8 @@ func TestResolveModuleFromCache(t *testing.T) { Source: "terraform-aws-modules/s3-bucket/aws//modules/object", Version: "4.1.2", }, - firstResolver: resolvers.Registry, + firstResolver: resolvers.Registry, + expectedSubdir: "modules/object", }, { name: "remote", @@ -49,7 +52,8 @@ func TestResolveModuleFromCache(t *testing.T) { Name: "bucket", Source: "git::https://github.com/terraform-aws-modules/terraform-aws-s3-bucket.git?ref=v4.1.2", }, - firstResolver: resolvers.Remote, + firstResolver: resolvers.Remote, + expectedSubdir: ".", }, { name: "remote with subdir", @@ -57,7 +61,8 @@ func TestResolveModuleFromCache(t *testing.T) { Name: "object", Source: "git::https://github.com/terraform-aws-modules/terraform-aws-s3-bucket.git//modules/object?ref=v4.1.2", }, - firstResolver: resolvers.Remote, + firstResolver: resolvers.Remote, + expectedSubdir: "modules/object", }, } diff --git a/pkg/iac/scanners/terraform/parser/resolvers/registry.go b/pkg/iac/scanners/terraform/parser/resolvers/registry.go index bcdd4734974a..8f2ab2ecdde1 100644 --- a/pkg/iac/scanners/terraform/parser/resolvers/registry.go +++ b/pkg/iac/scanners/terraform/parser/resolvers/registry.go @@ -45,7 +45,7 @@ func (r *registryResolver) Resolve(ctx context.Context, target fs.FS, opt Option } inputVersion := opt.Version - source := removeSubdirFromSource(opt.Source) + source, _ := splitPackageSubdirRaw(opt.Source) parts := strings.Split(source, "/") if len(parts) < 3 || len(parts) > 4 { return diff --git a/pkg/iac/scanners/terraform/parser/resolvers/remote.go b/pkg/iac/scanners/terraform/parser/resolvers/remote.go index df94c775da78..790b3509fd33 100644 --- a/pkg/iac/scanners/terraform/parser/resolvers/remote.go +++ b/pkg/iac/scanners/terraform/parser/resolvers/remote.go @@ -38,7 +38,7 @@ func (r *remoteResolver) Resolve(ctx context.Context, _ fs.FS, opt Options) (fil return nil, "", "", false, nil } - src := removeSubdirFromSource(opt.OriginalSource) + src, subdir := splitPackageSubdirRaw(opt.OriginalSource) key := cacheKey(src, opt.OriginalVersion) opt.Debug("Storing with cache key %s", key) @@ -54,7 +54,7 @@ func (r *remoteResolver) Resolve(ctx context.Context, _ fs.FS, opt Options) (fil r.incrementCount(opt) opt.Debug("Successfully downloaded %s from %s", opt.Name, opt.Source) opt.Debug("Module '%s' resolved via remote download.", opt.Name) - return os.DirFS(cacheDir), opt.Source, filepath.Join(".", opt.RelativePath), true, nil + return os.DirFS(cacheDir), opt.Source, subdir, true, nil } func (r *remoteResolver) download(ctx context.Context, opt Options, dst string) error { diff --git a/pkg/iac/scanners/terraform/parser/resolvers/source.go b/pkg/iac/scanners/terraform/parser/resolvers/source.go index d7637ffaf8a5..ee5662d6c7d0 100644 --- a/pkg/iac/scanners/terraform/parser/resolvers/source.go +++ b/pkg/iac/scanners/terraform/parser/resolvers/source.go @@ -2,7 +2,7 @@ package resolvers import "strings" -func removeSubdirFromSource(src string) string { +func splitPackageSubdirRaw(src string) (string, string) { stop := len(src) if idx := strings.Index(src, "?"); idx > -1 { stop = idx @@ -18,7 +18,7 @@ func removeSubdirFromSource(src string) string { // First see if we even have an explicit subdir idx := strings.Index(src[offset:stop], "//") if idx == -1 { - return src + return src, "." } idx += offset @@ -29,8 +29,9 @@ func removeSubdirFromSource(src string) string { // URL. if idx = strings.Index(subdir, "?"); idx > -1 { query := subdir[idx:] + subdir = subdir[:idx] src += query } - return src + return src, subdir } diff --git a/pkg/iac/scanners/terraform/parser/resolvers/source_test.go b/pkg/iac/scanners/terraform/parser/resolvers/source_test.go index 3f57ab68b6d3..46df7db700dc 100644 --- a/pkg/iac/scanners/terraform/parser/resolvers/source_test.go +++ b/pkg/iac/scanners/terraform/parser/resolvers/source_test.go @@ -6,39 +6,45 @@ import ( "github.com/stretchr/testify/assert" ) -func TestRemoveSubdirFromSource(t *testing.T) { +func TestSplitPackageSubdirRaw(t *testing.T) { tests := []struct { - name string - source string - expected string + name string + source string + expectedPkg string + expectedSubdir string }{ { - name: "address with scheme and query string", - source: "git::https://github.com/aquasecurity/terraform-modules.git//modules/ecs-service?ref=v0.1.0", - expected: "git::https://github.com/aquasecurity/terraform-modules.git?ref=v0.1.0", + name: "address with scheme and query string", + source: "git::https://github.com/aquasecurity/terraform-modules.git//modules/ecs-service?ref=v0.1.0", + expectedPkg: "git::https://github.com/aquasecurity/terraform-modules.git?ref=v0.1.0", + expectedSubdir: "modules/ecs-service", }, { - name: "address with scheme", - source: "git::https://github.com/aquasecurity/terraform-modules.git//modules/ecs-service", - expected: "git::https://github.com/aquasecurity/terraform-modules.git", + name: "address with scheme", + source: "git::https://github.com/aquasecurity/terraform-modules.git//modules/ecs-service", + expectedPkg: "git::https://github.com/aquasecurity/terraform-modules.git", + expectedSubdir: "modules/ecs-service", }, { - name: "registry address", - source: "hashicorp/consul/aws//modules/consul-cluster", - expected: "hashicorp/consul/aws", + name: "registry address", + source: "hashicorp/consul/aws//modules/consul-cluster", + expectedPkg: "hashicorp/consul/aws", + expectedSubdir: "modules/consul-cluster", }, { - name: "without subdir", - source: `hashicorp/consul/aws`, - expected: `hashicorp/consul/aws`, + name: "without subdir", + source: `hashicorp/consul/aws`, + expectedPkg: `hashicorp/consul/aws`, + expectedSubdir: ".", }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got := removeSubdirFromSource(test.source) - assert.Equal(t, test.expected, got) + pkgAddr, subdir := splitPackageSubdirRaw(test.source) + assert.Equal(t, test.expectedPkg, pkgAddr) + assert.Equal(t, test.expectedSubdir, subdir) }) } }