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