Skip to content

Instantly share code, notes, and snippets.

@benosman
Last active September 19, 2019 14:01
Show Gist options
  • Save benosman/1c7c6826ec45dfc8292f090056d63ef4 to your computer and use it in GitHub Desktop.
Save benosman/1c7c6826ec45dfc8292f090056d63ef4 to your computer and use it in GitHub Desktop.
Ansible Provisioner schema and generator (for https://github.com/radekg/terraform-provisioner-ansible)
{
"name": "ansible",
"type": "provisioner",
"version": "v2.3.0",
"schema": {
"ansible_ssh_settings": {
"Type": "TypeSet",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaInfo",
"Info": {
"bastion_user_known_hosts_file": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"connect_timeout_seconds": {
"Type": "TypeInt",
"Optional": true,
"Default": {
"Type": "int",
"Value": "10"
},
"Elem": {}
},
"connection_attempts": {
"Type": "TypeInt",
"Optional": true,
"Default": {
"Type": "int",
"Value": "10"
},
"Elem": {}
},
"insecure_bastion_no_strict_host_key_checking": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"insecure_no_strict_host_key_checking": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"ssh_keyscan_timeout": {
"Type": "TypeInt",
"Optional": true,
"Default": {
"Type": "int",
"Value": "60"
},
"Elem": {}
},
"user_known_hosts_file": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
}
}
}
},
"defaults": {
"Type": "TypeSet",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaInfo",
"Info": {
"become_method": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"become_user": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"extra_vars": {
"Type": "TypeMap",
"Optional": true,
"Computed": true,
"Default": {},
"Elem": {}
},
"forks": {
"Type": "TypeInt",
"Optional": true,
"Default": {},
"Elem": {}
},
"groups": {
"Type": "TypeList",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
},
"hosts": {
"Type": "TypeList",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
},
"inventory_file": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"limit": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"vault_id": {
"Type": "TypeList",
"Optional": true,
"ConflictsWith": [
"defaults.vault_password_file"
],
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
},
"vault_password_file": {
"Type": "TypeString",
"Optional": true,
"ConflictsWith": [
"defaults.vault_id"
],
"Default": {},
"Elem": {}
}
}
}
},
"plays": {
"Type": "TypeList",
"Optional": true,
"Computed": true,
"Default": {},
"Elem": {
"Type": "SchemaInfo",
"Info": {
"become": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"become_method": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"become_user": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"check": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"diff": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"enabled": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"extra_vars": {
"Type": "TypeMap",
"Optional": true,
"Computed": true,
"Default": {},
"Elem": {}
},
"forks": {
"Type": "TypeInt",
"Optional": true,
"Default": {},
"Elem": {}
},
"groups": {
"Type": "TypeList",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
},
"hosts": {
"Type": "TypeList",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
},
"inventory_file": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"limit": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"module": {
"Type": "TypeSet",
"Optional": true,
"ConflictsWith": [
"plays.playbook"
],
"Default": {},
"Elem": {
"Type": "SchemaInfo",
"Info": {
"args": {
"Type": "TypeMap",
"Optional": true,
"Computed": true,
"Default": {},
"Elem": {}
},
"background": {
"Type": "TypeInt",
"Optional": true,
"Default": {},
"Elem": {}
},
"host_pattern": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"module": {
"Type": "TypeString",
"Required": true,
"Default": {},
"Elem": {}
},
"one_line": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"poll": {
"Type": "TypeInt",
"Optional": true,
"Default": {},
"Elem": {}
}
}
}
},
"playbook": {
"Type": "TypeSet",
"Optional": true,
"ConflictsWith": [
"plays.module"
],
"Default": {},
"Elem": {
"Type": "SchemaInfo",
"Info": {
"file_path": {
"Type": "TypeString",
"Required": true,
"Default": {},
"Elem": {}
},
"force_handlers": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"roles_path": {
"Type": "TypeList",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
},
"skip_tags": {
"Type": "TypeList",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
},
"start_at_task": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"tags": {
"Type": "TypeList",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
}
}
}
},
"vault_id": {
"Type": "TypeList",
"Optional": true,
"ConflictsWith": [
"plays.vault_password_file"
],
"Default": {},
"Elem": {
"Type": "SchemaElements",
"ElementsType": "TypeString"
}
},
"vault_password_file": {
"Type": "TypeString",
"Optional": true,
"ConflictsWith": [
"plays.vault_id"
],
"Default": {},
"Elem": {}
},
"verbose": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
}
}
}
},
"remote": {
"Type": "TypeSet",
"Optional": true,
"Default": {},
"Elem": {
"Type": "SchemaInfo",
"Info": {
"bootstrap_directory": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"install_version": {
"Type": "TypeString",
"Optional": true,
"ConflictsWith": [
"remote.local_installer_path"
],
"Default": {},
"Elem": {}
},
"local_installer_path": {
"Type": "TypeString",
"Optional": true,
"ConflictsWith": [
"remote.install_version"
],
"Default": {},
"Elem": {}
},
"remote_installer_directory": {
"Type": "TypeString",
"Optional": true,
"Default": {},
"Elem": {}
},
"skip_cleanup": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"skip_install": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
},
"use_sudo": {
"Type": "TypeBool",
"Optional": true,
"Default": {},
"Elem": {}
}
}
}
}
}
}
package main
import (
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
"github.com/radekg/terraform-provisioner-ansible/ansible"
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
)
// ExportSchema should be called to export the structure
// of the provisioner.
func Export(p *schema.Provisioner) *ResourceProvisionerSchema {
result := new(ResourceProvisionerSchema)
result.Name = "ansible"
result.Type = "provisioner"
result.Version = "v2.3.0"
result.Schema = schemaMap(p.Schema).Export()
return result
}
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(provisioner *schema.Provisioner, name string, outputPath string) {
outputFilePath := filepath.Join(outputPath, fmt.Sprintf("%s.json", name))
if err := DoGenerate(provisioner, name, outputFilePath); err != nil {
fmt.Fprintln(os.Stderr, "Error: ", err.Error())
os.Exit(255)
}
}
func DoGenerate(provisioner *schema.Provisioner, provisionerName string, outputFilePath string) error {
provisionerJson, err := json.MarshalIndent(Export(provisioner), "", " ")
if err != nil {
return err
}
file, err := os.Create(outputFilePath)
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(provisionerJson)
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"`
PromoteSingle bool `json:",omitempty"`
ComputedWhen []string `json:",omitempty"`
ConflictsWith []string `json:",omitempty"`
Deprecated string `json:",omitempty"`
Removed string `json:",omitempty"`
Default SchemaElement `json:",omitempty"`
Elem SchemaElement `json:",omitempty"`
}
type SchemaInfo map[string]SchemaDefinition
// ResourceProvisionerSchema
type ResourceProvisionerSchema struct {
Name string `json:"name"`
Type string `json:"type"`
Version string `json:"version"`
Schema SchemaInfo `json:"schema"`
}
func main() {
var provisioner terraform.ResourceProvisioner
provisioner = ansible.Provisioner()
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
return
}
Generate(provisioner.(*schema.Provisioner), "ansible-provisioner", dir)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment