github.com/jpreese/tflint@v0.19.2-0.20200908152133-b01686250fb6/rules/awsrules/api/generator/main.go (about) 1 // +build generators 2 3 package main 4 5 import ( 6 "fmt" 7 "path/filepath" 8 "sort" 9 10 "github.com/hashicorp/hcl/v2/gohcl" 11 "github.com/hashicorp/hcl/v2/hclparse" 12 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 13 utils "github.com/terraform-linters/tflint/rules/awsrules/generator-utils" 14 "github.com/terraform-providers/terraform-provider-aws/aws" 15 ) 16 17 type definition struct { 18 Rules []rule `hcl:"rule,block"` 19 } 20 21 type rule struct { 22 Name string `hcl:"name,label"` 23 Resource string `hcl:"resource"` 24 Attribute string `hcl:"attribute"` 25 SourceAction string `hcl:"source_action"` 26 Template string `hcl:"template"` 27 } 28 29 type ruleMeta struct { 30 RuleName string 31 RuleNameCC string 32 ResourceType string 33 AttributeName string 34 DataType string 35 ActionName string 36 Template string 37 } 38 39 type providerMeta struct { 40 RuleNameCCList []string 41 } 42 43 var awsProvider = aws.Provider() 44 45 func main() { 46 files, err := filepath.Glob("./definitions/*.hcl") 47 if err != nil { 48 panic(err) 49 } 50 51 providerMeta := &providerMeta{} 52 for _, file := range files { 53 parser := hclparse.NewParser() 54 f, diags := parser.ParseHCLFile(file) 55 if diags.HasErrors() { 56 panic(diags) 57 } 58 59 var def definition 60 diags = gohcl.DecodeBody(f.Body, nil, &def) 61 if diags.HasErrors() { 62 panic(diags) 63 } 64 65 for _, rule := range def.Rules { 66 meta := &ruleMeta{ 67 RuleName: rule.Name, 68 RuleNameCC: utils.ToCamel(rule.Name), 69 ResourceType: rule.Resource, 70 AttributeName: rule.Attribute, 71 DataType: dataType(rule.Resource, rule.Attribute), 72 ActionName: rule.SourceAction, 73 Template: rule.Template, 74 } 75 76 utils.GenerateFile( 77 fmt.Sprintf("%s.go", rule.Name), 78 "rule.go.tmpl", 79 meta, 80 ) 81 82 providerMeta.RuleNameCCList = append(providerMeta.RuleNameCCList, meta.RuleNameCC) 83 } 84 } 85 86 sort.Strings(providerMeta.RuleNameCCList) 87 utils.GenerateFile( 88 "../../provider_api.go", 89 "../../provider_api.go.tmpl", 90 providerMeta, 91 ) 92 } 93 94 func dataType(resource, attribute string) string { 95 resourceSchema, ok := awsProvider.ResourcesMap[resource] 96 if !ok { 97 panic(fmt.Sprintf("resource `%s` not found in the Terraform schema", resource)) 98 } 99 attrSchema, ok := resourceSchema.Schema[attribute] 100 if !ok { 101 panic(fmt.Sprintf("`%s.%s` not found in the Terraform schema", resource, attribute)) 102 } 103 104 switch attrSchema.Type { 105 case schema.TypeString: 106 return "string" 107 case schema.TypeSet: 108 return "list" 109 default: 110 panic(fmt.Errorf("Unexpected data type: %#v", attrSchema.Type)) 111 } 112 }