github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/openstack/config.go (about)

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