Created
August 25, 2022 02:57
-
-
Save pj/687745e85f4d5ed104b292cebd1cd426 to your computer and use it in GitHub Desktop.
Simple go program for generating terraform variables.tf files from cue definitions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Apply @generate_terraform_variables(filename="variables.tf") to a definition you want to output as a variables file. | |
package main | |
import ( | |
"fmt" | |
"os" | |
"strings" | |
"text/template" | |
"cuelang.org/go/cue" | |
"cuelang.org/go/cue/cuecontext" | |
"cuelang.org/go/cue/load" | |
) | |
const VARIABLES_TEMPLATE = ` | |
variable "{{ .Name }}" { | |
type = "{{ .Type }}" | |
{{- if .Default }} | |
default = {{ .Default }} | |
{{- end}} | |
} | |
` | |
type VariableDetails struct { | |
Type string | |
Default string | |
Name string | |
} | |
func getType(val cue.Value) (string, error) { | |
asdf := fmt.Sprintf("%v", val) | |
switch asdf { | |
case "string": | |
return "string", nil | |
case "int": | |
return "number", nil | |
case "float": | |
return "number", nil | |
case "bool": | |
return "boolean", nil | |
default: | |
return "", fmt.Errorf("Unknown type: %s", asdf) | |
} | |
} | |
func outputVariables(val cue.Value) error { | |
if val.Kind() == cue.StructKind { | |
iterator, err := val.Fields(cue.Definitions(true)) | |
if err != nil { | |
return err | |
} | |
for iterator.Next() { | |
definition := iterator.Value() | |
att := definition.Attributes(cue.FieldAttr) | |
for _, x := range att { | |
if x.Name() == "generate_terraform_variables" { | |
var builder strings.Builder | |
builder.WriteString("// Generated by Cue\n") | |
template := template.New("generate_terraform_variables") | |
template.Parse(VARIABLES_TEMPLATE) | |
fieldIterator, err := definition.Fields(cue.Optional(true)) | |
if err != nil { | |
return err | |
} | |
for fieldIterator.Next() { | |
field := fieldIterator.Value() | |
label, _ := field.Label() | |
kind, err := getType(field) | |
if err != nil { | |
return err | |
} | |
details := VariableDetails{ | |
Name: label, | |
Type: kind, | |
} | |
template.Execute(&builder, details) | |
} | |
filename, found, err := x.Lookup(0, "filename") | |
if err != nil { | |
return err | |
} | |
if !found { | |
return fmt.Errorf("filename not found") | |
} | |
file, err := os.Create(filename) | |
if err != nil { | |
return err | |
} | |
file.WriteString(builder.String()) | |
} | |
} | |
} | |
} | |
return nil | |
} | |
func main() { | |
c := cuecontext.New() | |
instances := load.Instances([]string{}, &load.Config{Module: "lazytest.io/config", Package: "config"}) | |
for _, bi := range instances { | |
if bi.Err != nil { | |
fmt.Println("Error during load:", bi.Err) | |
continue | |
} | |
value := c.BuildInstance(bi) | |
if value.Err() != nil { | |
fmt.Println("Error during build:", value.Err()) | |
continue | |
} | |
err := outputVariables(value) | |
if err != nil { | |
fmt.Printf("Error: %v", err) | |
os.Exit(1) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment