Skip to content

Instantly share code, notes, and snippets.

@kapilt
Forked from harsh-98/cloudflare-generator.go
Last active January 22, 2020 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kapilt/7536944b608bd691ec2934ed4b56e369 to your computer and use it in GitHub Desktop.
Save kapilt/7536944b608bd691ec2934ed4b56e369 to your computer and use it in GitHub Desktop.
Jsonschema generator for cloudflare
package main
import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
tf "github.com/hashicorp/terraform-plugin-sdk/terraform"
aws "github.com/terraform-providers/terraform-provider-aws/aws"
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
)
// Export should be called to export the structure
// of the provider.
func Export(p *schema.Provider) *ResourceProviderSchema {
result := new(ResourceProviderSchema)
result.Name = "aws"
result.Type = "provider"
result.Version = "v2.9.0"
result.Provider = schemaMap(p.Schema).Export()
result.Resources = make(map[string]SchemaInfo)
result.DataSources = make(map[string]SchemaInfo)
for k, r := range p.ResourcesMap {
result.Resources[k] = ExportResource(r)
}
for k, ds := range p.DataSourcesMap {
result.DataSources[k] = ExportResource(ds)
}
return result
}
// ExportResource export schema
func ExportResource(r *schema.Resource) SchemaInfo {
return schemaMap(r.Schema).Export()
}
// schemaMap is a wrapper that adds nice functions on top of schemas.
type schemaMap map[string]*schema.Schema
// Export exports the format of this schema.
func (m schemaMap) Export() SchemaInfo {
result := make(SchemaInfo)
for k, v := range m {
item := export(v)
result[k] = item
}
return result
}
func export(v *schema.Schema) SchemaDefinition {
item := SchemaDefinition{}
item.Type = fmt.Sprintf("%s", v.Type)
item.Optional = v.Optional
item.Required = v.Required
item.Description = v.Description
item.InputDefault = v.InputDefault
item.Computed = v.Computed
item.MaxItems = v.MaxItems
item.MinItems = v.MinItems
item.PromoteSingle = v.PromoteSingle
item.ComputedWhen = v.ComputedWhen
item.ConflictsWith = v.ConflictsWith
item.Deprecated = v.Deprecated
item.Removed = v.Removed
if v.Elem != nil {
item.Elem = exportValue(v.Elem, fmt.Sprintf("%T", v.Elem))
}
// TODO: Find better solution
if defValue, err := v.DefaultValue(); err == nil && defValue != nil && !reflect.DeepEqual(defValue, v.Default) {
item.Default = exportValue(defValue, fmt.Sprintf("%T", defValue))
}
return item
}
func exportValue(value interface{}, t string) SchemaElement {
s2, ok := value.(*schema.Schema)
if ok {
return SchemaElement{Type: "SchemaElements", ElementsType: fmt.Sprintf("%s", s2.Type)}
}
r2, ok := value.(*schema.Resource)
if ok {
return SchemaElement{Type: "SchemaInfo", Info: ExportResource(r2)}
}
return SchemaElement{Type: t, Value: fmt.Sprintf("%v", value)}
}
func Generate(provider *schema.Provider, name string, outputPath string) {
outputFilePath := filepath.Join(outputPath, fmt.Sprintf("%s.json", name))
if err := DoGenerate(provider, name, outputFilePath); err != nil {
fmt.Fprintln(os.Stderr, "Error: ", err.Error())
os.Exit(255)
}
}
func DoGenerate(provider *schema.Provider, providerName string, outputFilePath string) error {
providerJson, err := json.MarshalIndent(Export(provider), "", " ")
if err != nil {
return err
}
file, err := os.Create(outputFilePath)
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(providerJson)
if err != nil {
return err
}
return file.Sync()
}
type SchemaElement struct {
// One of ValueType or "SchemaElements" or "SchemaInfo"
Type string `json:",omitempty"`
// Set for simple types (from ValueType)
Value string `json:",omitempty"`
// Set if Type == "SchemaElements"
ElementsType string `json:",omitempty"`
// Set if Type == "SchemaInfo"
Info SchemaInfo `json:",omitempty"`
}
type SchemaDefinition struct {
Type string `json:",omitempty"`
Optional bool `json:",omitempty"`
Required bool `json:",omitempty"`
Description string `json:",omitempty"`
InputDefault string `json:",omitempty"`
Computed bool `json:",omitempty"`
MaxItems int `json:",omitempty"`
MinItems int `json:",omitempty"`
//deprecated
//PromoteSingle bool `json:",omitempty"`
//Default string `json:",omitempty"`
//ForceNew bool `json:",omitempty"`
//SchemaConfigMode string `json:",omitempty"`
ComputedWhen []string `json:",omitempty"`
ConflictsWith []string `json:",omitempty"`
// ExactlyOneOf []string `json:",omitempty"`
// AtLeastOneOf []string `json:",omitempty"`
Deprecated string `json:",omitempty"`
Removed string `json:",omitempty"`
Default SchemaElement `json:",omitempty"`
Elem SchemaElement `json:",omitempty"`
}
type SchemaInfo map[string]SchemaDefinition
// ResourceProviderSchema xyz
type ResourceProviderSchema struct {
Name string `json:"name"`
Type string `json:"type"`
Version string `json:"version"`
Provider SchemaInfo `json:"provider"`
Resources map[string]SchemaInfo `json:"resources"`
DataSources map[string]SchemaInfo `json:"data-sources"`
}
func main() {
var provider tf.ResourceProvider
provider = aws.Provider()
Generate(provider.(*schema.Provider), "aws", "schemas")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment