Skip to content

Commit

Permalink
feat(misconf): add metadata to Cloud schema (#6831)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikpivkin authored Jun 5, 2024
1 parent 8dd076a commit 02d5404
Show file tree
Hide file tree
Showing 4 changed files with 1,253 additions and 26 deletions.
13 changes: 7 additions & 6 deletions pkg/iac/rego/convert/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,21 @@ func StructToRego(inputValue reflect.Value) map[string]any {
field := inputValue.Field(i)
typ := inputValue.Type().Field(i)
name := typ.Name
if !typ.IsExported() {

if !typ.IsExported() || field.Interface() == nil {
continue
}
if field.Interface() == nil {

if _, ok := field.Interface().(types.Metadata); ok && name == "Metadata" {
continue
}

val := anonymousToRego(reflect.ValueOf(field.Interface()))

if val == nil {
continue
}
key := strings.ToLower(name)
if _, ok := field.Interface().(types.Metadata); key == "metadata" && ok {
continue
}

output[strings.ToLower(name)] = val
}

Expand Down
59 changes: 49 additions & 10 deletions pkg/iac/rego/convert/struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,56 @@ import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/aquasecurity/trivy/pkg/iac/types"
)

func Test_StructConversion(t *testing.T) {
input := struct {
X string
Y int
Z struct {
A float64
}
}{}
input.Z.A = 123
converted := StructToRego(reflect.ValueOf(input))
assert.Equal(t, map[string]any{"z": make(map[string]any)}, converted)
tests := []struct {
name string
inp any
expected any
}{
{
name: "struct with nested struct",
inp: struct {
X string
Y int
Z struct {
A float64
}
}{
X: "test",
Z: struct {
A float64
}{
A: 123,
},
},
expected: map[string]any{"z": make(map[string]any)},
},
{
name: "struct with metadata",
inp: struct {
X string
Metadata types.Metadata
}{
X: "test",
Metadata: types.NewTestMetadata(),
},
expected: map[string]any{
"__defsec_metadata": func() any {
meta := types.NewTestMetadata().GetMetadata()
return meta.ToRego()
}(),
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
converted := StructToRego(reflect.ValueOf(tt.inp))
assert.Equal(t, tt.expected, converted)
})
}
}
12 changes: 8 additions & 4 deletions pkg/iac/rego/schemas/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,12 @@ func sanitize(s string) string {
}

func (b *builder) readProperty(name string, parent, inputType reflect.Type, indent int) (*Property, error) {

if inputType.Kind() == reflect.Ptr {
inputType = inputType.Elem()
}

switch inputType.String() {
case "types.Metadata", "types.Range", "types.Reference":
case "types.Range", "types.Reference":
return nil, nil
}

Expand Down Expand Up @@ -181,7 +180,8 @@ func (b *builder) readStruct(name string, parent, inputType reflect.Type, indent
b.schema.Defs[refName(name, parent, inputType)] = def
}

if inputType.Implements(converterInterface) {
if inputType.Implements(converterInterface) ||
inputType.String() == "types.Metadata" {
if inputType.Kind() == reflect.Ptr {
inputType = inputType.Elem()
}
Expand All @@ -192,6 +192,7 @@ func (b *builder) readStruct(name string, parent, inputType reflect.Type, indent
} else {

for i := 0; i < inputType.NumField(); i++ {

field := inputType.Field(i)
prop, err := b.readProperty(field.Name, inputType, field.Type, indent+1)
if err != nil {
Expand All @@ -201,9 +202,12 @@ func (b *builder) readStruct(name string, parent, inputType reflect.Type, indent
continue
}
key := strings.ToLower(field.Name)

// metadata exported as "__defsec_metadata"
if key == "metadata" {
continue
key = "__defsec_metadata"
}

def.Properties[key] = *prop
}
}
Expand Down
Loading

0 comments on commit 02d5404

Please sign in to comment.