github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/rego/convert/struct.go (about) 1 package convert 2 3 import ( 4 "reflect" 5 "strings" 6 7 "github.com/khulnasoft-lab/defsec/pkg/types" 8 ) 9 10 type metadataProvider interface { 11 GetMetadata() types.Metadata 12 } 13 14 var metadataInterface = reflect.TypeOf((*metadataProvider)(nil)).Elem() 15 16 func StructToRego(inputValue reflect.Value) map[string]interface{} { 17 18 // make sure we have a struct literal 19 for inputValue.Type().Kind() == reflect.Ptr || inputValue.Type().Kind() == reflect.Interface { 20 if inputValue.IsNil() { 21 return nil 22 } 23 inputValue = inputValue.Elem() 24 } 25 if inputValue.Type().Kind() != reflect.Struct { 26 panic("not a struct") 27 } 28 29 output := make(map[string]interface{}, inputValue.NumField()) 30 31 for i := 0; i < inputValue.NumField(); i++ { 32 field := inputValue.Field(i) 33 typ := inputValue.Type().Field(i) 34 name := typ.Name 35 if !typ.IsExported() { 36 continue 37 } 38 if field.Interface() == nil { 39 continue 40 } 41 val := anonymousToRego(reflect.ValueOf(field.Interface())) 42 if val == nil { 43 continue 44 } 45 key := strings.ToLower(name) 46 if _, ok := field.Interface().(types.Metadata); key == "metadata" && ok { 47 continue 48 } 49 output[strings.ToLower(name)] = val 50 } 51 52 if inputValue.Type().Implements(metadataInterface) { 53 returns := inputValue.MethodByName("GetMetadata").Call(nil) 54 if metadata, ok := returns[0].Interface().(types.Metadata); ok { 55 output["__defsec_metadata"] = metadata.ToRego() 56 } 57 } else { 58 metaVal := inputValue.FieldByName("Metadata") 59 if metaVal.Kind() == reflect.Struct { 60 if meta, ok := metaVal.Interface().(types.Metadata); ok { 61 output["__defsec_metadata"] = meta.ToRego() 62 } 63 } 64 65 } 66 67 return output 68 }