github.com/jd3nn1s/terraform@v0.9.6-0.20170906225847-13878347b7a1/backend/remote-state/consul/backend.go (about) 1 package consul 2 3 import ( 4 "context" 5 "strings" 6 7 consulapi "github.com/hashicorp/consul/api" 8 "github.com/hashicorp/terraform/backend" 9 "github.com/hashicorp/terraform/helper/schema" 10 ) 11 12 // New creates a new backend for Consul remote state. 13 func New() backend.Backend { 14 s := &schema.Backend{ 15 Schema: map[string]*schema.Schema{ 16 "path": &schema.Schema{ 17 Type: schema.TypeString, 18 Required: true, 19 Description: "Path to store state in Consul", 20 }, 21 22 "access_token": &schema.Schema{ 23 Type: schema.TypeString, 24 Optional: true, 25 Description: "Access token for a Consul ACL", 26 Default: "", // To prevent input 27 }, 28 29 "address": &schema.Schema{ 30 Type: schema.TypeString, 31 Optional: true, 32 Description: "Address to the Consul Cluster", 33 Default: "", // To prevent input 34 }, 35 36 "scheme": &schema.Schema{ 37 Type: schema.TypeString, 38 Optional: true, 39 Description: "Scheme to communicate to Consul with", 40 Default: "", // To prevent input 41 }, 42 43 "datacenter": &schema.Schema{ 44 Type: schema.TypeString, 45 Optional: true, 46 Description: "Datacenter to communicate with", 47 Default: "", // To prevent input 48 }, 49 50 "http_auth": &schema.Schema{ 51 Type: schema.TypeString, 52 Optional: true, 53 Description: "HTTP Auth in the format of 'username:password'", 54 Default: "", // To prevent input 55 }, 56 57 "gzip": &schema.Schema{ 58 Type: schema.TypeBool, 59 Optional: true, 60 Description: "Compress the state data using gzip", 61 Default: false, 62 }, 63 64 "lock": &schema.Schema{ 65 Type: schema.TypeBool, 66 Optional: true, 67 Description: "Lock state access", 68 Default: true, 69 }, 70 71 "ca_file": &schema.Schema{ 72 Type: schema.TypeString, 73 Optional: true, 74 Description: "A path to a PEM-encoded certificate authority used to verify the remote agent's certificate.", 75 DefaultFunc: schema.EnvDefaultFunc("CONSUL_CACERT", ""), 76 }, 77 78 "cert_file": &schema.Schema{ 79 Type: schema.TypeString, 80 Optional: true, 81 Description: "A path to a PEM-encoded certificate provided to the remote agent; requires use of key_file.", 82 DefaultFunc: schema.EnvDefaultFunc("CONSUL_CLIENT_CERT", ""), 83 }, 84 85 "key_file": &schema.Schema{ 86 Type: schema.TypeString, 87 Optional: true, 88 Description: "A path to a PEM-encoded private key, required if cert_file is specified.", 89 DefaultFunc: schema.EnvDefaultFunc("CONSUL_CLIENT_KEY", ""), 90 }, 91 }, 92 } 93 94 result := &Backend{Backend: s} 95 result.Backend.ConfigureFunc = result.configure 96 return result 97 } 98 99 type Backend struct { 100 *schema.Backend 101 102 // The fields below are set from configure 103 configData *schema.ResourceData 104 lock bool 105 } 106 107 func (b *Backend) configure(ctx context.Context) error { 108 // Grab the resource data 109 b.configData = schema.FromContextBackendConfig(ctx) 110 111 // Store the lock information 112 b.lock = b.configData.Get("lock").(bool) 113 114 // Initialize a client to test config 115 _, err := b.clientRaw() 116 return err 117 } 118 119 func (b *Backend) clientRaw() (*consulapi.Client, error) { 120 data := b.configData 121 122 // Configure the client 123 config := consulapi.DefaultConfig() 124 if v, ok := data.GetOk("access_token"); ok && v.(string) != "" { 125 config.Token = v.(string) 126 } 127 if v, ok := data.GetOk("address"); ok && v.(string) != "" { 128 config.Address = v.(string) 129 } 130 if v, ok := data.GetOk("scheme"); ok && v.(string) != "" { 131 config.Scheme = v.(string) 132 } 133 if v, ok := data.GetOk("datacenter"); ok && v.(string) != "" { 134 config.Datacenter = v.(string) 135 } 136 137 if v, ok := data.GetOk("ca_file"); ok && v.(string) != "" { 138 config.TLSConfig.CAFile = v.(string) 139 } 140 if v, ok := data.GetOk("cert_file"); ok && v.(string) != "" { 141 config.TLSConfig.CertFile = v.(string) 142 } 143 if v, ok := data.GetOk("key_file"); ok && v.(string) != "" { 144 config.TLSConfig.KeyFile = v.(string) 145 } 146 147 if v, ok := data.GetOk("http_auth"); ok && v.(string) != "" { 148 auth := v.(string) 149 150 var username, password string 151 if strings.Contains(auth, ":") { 152 split := strings.SplitN(auth, ":", 2) 153 username = split[0] 154 password = split[1] 155 } else { 156 username = auth 157 } 158 159 config.HttpAuth = &consulapi.HttpBasicAuth{ 160 Username: username, 161 Password: password, 162 } 163 } 164 165 return consulapi.NewClient(config) 166 }