Skip to content

Commit

Permalink
fix(terraform): Attribute and fileset fixes (#6544)
Browse files Browse the repository at this point in the history
  • Loading branch information
fwereade authored Apr 23, 2024
1 parent 63c9469 commit 7c2017f
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 7 deletions.
10 changes: 4 additions & 6 deletions pkg/iac/scanners/terraform/parser/funcs/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,9 @@ func MakeFileSetFunc(target fs.FS, baseDir string) function.Function {
path = filepath.Join(baseDir, path)
}

// Join the path to the glob pattern, while ensuring the full
// pattern is canonical for the host OS. The joined path is
// automatically cleaned during this operation.
pattern = filepath.Join(path, pattern)
// Trivy uses a virtual file system
// Join the path to the glob pattern, and ensure both path and pattern
// agree on path separators, so the globbing works as expected.
pattern = filepath.ToSlash(filepath.Join(path, pattern))
path = filepath.ToSlash(path)

matches, err := doublestar.Glob(target, pattern)
Expand All @@ -263,7 +261,7 @@ func MakeFileSetFunc(target fs.FS, baseDir string) function.Function {

var matchVals []cty.Value
for _, match := range matches {
fi, err := os.Stat(match)
fi, err := fs.Stat(target, match)

if err != nil {
return cty.UnknownVal(cty.Set(cty.String)), fmt.Errorf("failed to stat (%s): %s", match, err)
Expand Down
68 changes: 68 additions & 0 deletions pkg/iac/scanners/terraform/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1631,3 +1631,71 @@ output "test_out" {
assert.Equal(t, "test_value", attr.GetRawValue())
}
}

func TestExtractSetValue(t *testing.T) {
files := map[string]string{
"main.tf": `
resource "test" "set-value" {
value = toset(["x", "y", "x"])
}
`,
}

resources := parse(t, files).GetResourcesByType("test")
require.Len(t, resources, 1)
attr := resources[0].GetAttribute("value")
require.NotNil(t, attr)
assert.Equal(t, []string{"x", "y"}, attr.GetRawValue())
}

func TestFunc_fileset(t *testing.T) {
files := map[string]string{
"main.tf": `
resource "test" "fileset-func" {
value = fileset(path.module, "**/*.py")
}
`,
"a.py": ``,
"path/b.py": ``,
}

resources := parse(t, files).GetResourcesByType("test")
require.Len(t, resources, 1)
attr := resources[0].GetAttribute("value")
require.NotNil(t, attr)
assert.Equal(t, []string{"a.py", "path/b.py"}, attr.GetRawValue())
}

func TestVarTypeShortcut(t *testing.T) {
files := map[string]string{
"main.tf": `
variable "magic_list" {
type = list
default = ["x", "y"]
}
variable "magic_map" {
type = map
default = {a = 1, b = 2}
}
resource "test" "values" {
l = var.magic_list
m = var.magic_map
}
`,
}

resources := parse(t, files).GetResourcesByType("test")
require.Len(t, resources, 1)

list_attr := resources[0].GetAttribute("l")
require.NotNil(t, list_attr)
assert.Equal(t, []string{"x", "y"}, list_attr.GetRawValue())

map_attr := resources[0].GetAttribute("m")
require.NotNil(t, map_attr)
assert.True(t, map_attr.Value().RawEquals(cty.MapVal(map[string]cty.Value{
"a": cty.NumberIntVal(1), "b": cty.NumberIntVal(2),
})))
}
10 changes: 9 additions & 1 deletion pkg/iac/terraform/attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ type Attribute struct {
}

func (a *Attribute) DecodeVarType() (cty.Type, *typeexpr.Defaults, error) {
// Special-case the shortcuts for list(any) and map(any) which aren't hcl.
switch hcl.ExprAsKeyword(a.hclAttribute.Expr) {
case "list":
return cty.List(cty.DynamicPseudoType), nil, nil
case "map":
return cty.Map(cty.DynamicPseudoType), nil, nil
}

t, def, diag := typeexpr.TypeConstraintWithDefaults(a.hclAttribute.Expr)
if diag.HasErrors() {
return cty.NilType, nil, diag
Expand Down Expand Up @@ -68,7 +76,7 @@ func (a *Attribute) GetRawValue() interface{} {
return float
default:
switch {
case typ.IsTupleType(), typ.IsListType():
case typ.IsTupleType(), typ.IsListType(), typ.IsSetType():
values := a.Value().AsValueSlice()
if len(values) == 0 {
return []string{}
Expand Down

0 comments on commit 7c2017f

Please sign in to comment.