github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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  	}
    58  
    59  	result := &Backend{Backend: s}
    60  	result.Backend.ConfigureFunc = result.configure
    61  	return result
    62  }
    63  
    64  type Backend struct {
    65  	*schema.Backend
    66  
    67  	configData *schema.ResourceData
    68  }
    69  
    70  func (b *Backend) configure(ctx context.Context) error {
    71  	// Grab the resource data
    72  	b.configData = schema.FromContextBackendConfig(ctx)
    73  
    74  	// Initialize a client to test config
    75  	_, err := b.clientRaw()
    76  	return err
    77  }
    78  
    79  func (b *Backend) clientRaw() (*consulapi.Client, error) {
    80  	data := b.configData
    81  
    82  	// Configure the client
    83  	config := consulapi.DefaultConfig()
    84  	if v, ok := data.GetOk("access_token"); ok && v.(string) != "" {
    85  		config.Token = v.(string)
    86  	}
    87  	if v, ok := data.GetOk("address"); ok && v.(string) != "" {
    88  		config.Address = v.(string)
    89  	}
    90  	if v, ok := data.GetOk("scheme"); ok && v.(string) != "" {
    91  		config.Scheme = v.(string)
    92  	}
    93  	if v, ok := data.GetOk("datacenter"); ok && v.(string) != "" {
    94  		config.Datacenter = v.(string)
    95  	}
    96  	if v, ok := data.GetOk("http_auth"); ok && v.(string) != "" {
    97  		auth := v.(string)
    98  
    99  		var username, password string
   100  		if strings.Contains(auth, ":") {
   101  			split := strings.SplitN(auth, ":", 2)
   102  			username = split[0]
   103  			password = split[1]
   104  		} else {
   105  			username = auth
   106  		}
   107  
   108  		config.HttpAuth = &consulapi.HttpBasicAuth{
   109  			Username: username,
   110  			Password: password,
   111  		}
   112  	}
   113  
   114  	return consulapi.NewClient(config)
   115  }