github.com/nevins-b/terraform@v0.3.8-0.20170215184714-bbae22007d5a/builtin/providers/openstack/config.go (about)

     1  package openstack
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"fmt"
     7  	"net/http"
     8  
     9  	"github.com/gophercloud/gophercloud"
    10  	"github.com/gophercloud/gophercloud/openstack"
    11  	"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth"
    12  	"github.com/hashicorp/terraform/helper/pathorcontents"
    13  )
    14  
    15  type Config struct {
    16  	CACertFile       string
    17  	ClientCertFile   string
    18  	ClientKeyFile    string
    19  	DomainID         string
    20  	DomainName       string
    21  	EndpointType     string
    22  	IdentityEndpoint string
    23  	Insecure         bool
    24  	Password         string
    25  	Swauth           bool
    26  	TenantID         string
    27  	TenantName       string
    28  	Token            string
    29  	Username         string
    30  	UserID           string
    31  
    32  	osClient *gophercloud.ProviderClient
    33  }
    34  
    35  func (c *Config) loadAndValidate() error {
    36  	validEndpoint := false
    37  	validEndpoints := []string{
    38  		"internal", "internalURL",
    39  		"admin", "adminURL",
    40  		"public", "publicURL",
    41  		"",
    42  	}
    43  
    44  	for _, endpoint := range validEndpoints {
    45  		if c.EndpointType == endpoint {
    46  			validEndpoint = true
    47  		}
    48  	}
    49  
    50  	if !validEndpoint {
    51  		return fmt.Errorf("Invalid endpoint type provided")
    52  	}
    53  
    54  	ao := gophercloud.AuthOptions{
    55  		DomainID:         c.DomainID,
    56  		DomainName:       c.DomainName,
    57  		IdentityEndpoint: c.IdentityEndpoint,
    58  		Password:         c.Password,
    59  		TenantID:         c.TenantID,
    60  		TenantName:       c.TenantName,
    61  		TokenID:          c.Token,
    62  		Username:         c.Username,
    63  		UserID:           c.UserID,
    64  	}
    65  
    66  	client, err := openstack.NewClient(ao.IdentityEndpoint)
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	config := &tls.Config{}
    72  	if c.CACertFile != "" {
    73  		caCert, _, err := pathorcontents.Read(c.CACertFile)
    74  		if err != nil {
    75  			return fmt.Errorf("Error reading CA Cert: %s", err)
    76  		}
    77  
    78  		caCertPool := x509.NewCertPool()
    79  		caCertPool.AppendCertsFromPEM([]byte(caCert))
    80  		config.RootCAs = caCertPool
    81  	}
    82  
    83  	if c.Insecure {
    84  		config.InsecureSkipVerify = true
    85  	}
    86  
    87  	if c.ClientCertFile != "" && c.ClientKeyFile != "" {
    88  		clientCert, _, err := pathorcontents.Read(c.ClientCertFile)
    89  		if err != nil {
    90  			return fmt.Errorf("Error reading Client Cert: %s", err)
    91  		}
    92  		clientKey, _, err := pathorcontents.Read(c.ClientKeyFile)
    93  		if err != nil {
    94  			return fmt.Errorf("Error reading Client Key: %s", err)
    95  		}
    96  
    97  		cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
    98  		if err != nil {
    99  			return err
   100  		}
   101  
   102  		config.Certificates = []tls.Certificate{cert}
   103  		config.BuildNameToCertificate()
   104  	}
   105  
   106  	transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config}
   107  	client.HTTPClient.Transport = transport
   108  
   109  	// If using Swift Authentication, there's no need to validate authentication normally.
   110  	if !c.Swauth {
   111  		err = openstack.Authenticate(client, ao)
   112  		if err != nil {
   113  			return err
   114  		}
   115  	}
   116  
   117  	c.osClient = client
   118  
   119  	return nil
   120  }
   121  
   122  func (c *Config) blockStorageV1Client(region string) (*gophercloud.ServiceClient, error) {
   123  	return openstack.NewBlockStorageV1(c.osClient, gophercloud.EndpointOpts{
   124  		Region:       region,
   125  		Availability: c.getEndpointType(),
   126  	})
   127  }
   128  
   129  func (c *Config) blockStorageV2Client(region string) (*gophercloud.ServiceClient, error) {
   130  	return openstack.NewBlockStorageV2(c.osClient, gophercloud.EndpointOpts{
   131  		Region:       region,
   132  		Availability: c.getEndpointType(),
   133  	})
   134  }
   135  
   136  func (c *Config) computeV2Client(region string) (*gophercloud.ServiceClient, error) {
   137  	return openstack.NewComputeV2(c.osClient, gophercloud.EndpointOpts{
   138  		Region:       region,
   139  		Availability: c.getEndpointType(),
   140  	})
   141  }
   142  
   143  func (c *Config) networkingV2Client(region string) (*gophercloud.ServiceClient, error) {
   144  	return openstack.NewNetworkV2(c.osClient, gophercloud.EndpointOpts{
   145  		Region:       region,
   146  		Availability: c.getEndpointType(),
   147  	})
   148  }
   149  
   150  func (c *Config) objectStorageV1Client(region string) (*gophercloud.ServiceClient, error) {
   151  	// If Swift Authentication is being used, return a swauth client.
   152  	if c.Swauth {
   153  		return swauth.NewObjectStorageV1(c.osClient, swauth.AuthOpts{
   154  			User: c.Username,
   155  			Key:  c.Password,
   156  		})
   157  	}
   158  
   159  	return openstack.NewObjectStorageV1(c.osClient, gophercloud.EndpointOpts{
   160  		Region:       region,
   161  		Availability: c.getEndpointType(),
   162  	})
   163  }
   164  
   165  func (c *Config) getEndpointType() gophercloud.Availability {
   166  	if c.EndpointType == "internal" || c.EndpointType == "internalURL" {
   167  		return gophercloud.AvailabilityInternal
   168  	}
   169  	if c.EndpointType == "admin" || c.EndpointType == "adminURL" {
   170  		return gophercloud.AvailabilityAdmin
   171  	}
   172  	return gophercloud.AvailabilityPublic
   173  }