You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
terraform/builtin/providers/openstack/config.go

193 lines
4.8 KiB

package openstack
import (
"crypto/tls"
"crypto/x509"
"fmt"
"net/http"
"os"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth"
"github.com/hashicorp/terraform/helper/pathorcontents"
)
type Config struct {
CACertFile string
ClientCertFile string
ClientKeyFile string
DomainID string
DomainName string
EndpointType string
IdentityEndpoint string
Insecure bool
Password string
Swauth bool
TenantID string
TenantName string
Token string
Username string
UserID string
osClient *gophercloud.ProviderClient
}
func (c *Config) loadAndValidate() error {
validEndpoint := false
validEndpoints := []string{
"internal", "internalURL",
"admin", "adminURL",
"public", "publicURL",
"",
}
for _, endpoint := range validEndpoints {
if c.EndpointType == endpoint {
validEndpoint = true
}
}
if !validEndpoint {
return fmt.Errorf("Invalid endpoint type provided")
}
ao := gophercloud.AuthOptions{
DomainID: c.DomainID,
DomainName: c.DomainName,
IdentityEndpoint: c.IdentityEndpoint,
Password: c.Password,
TenantID: c.TenantID,
TenantName: c.TenantName,
TokenID: c.Token,
Username: c.Username,
UserID: c.UserID,
}
client, err := openstack.NewClient(ao.IdentityEndpoint)
if err != nil {
return err
}
config := &tls.Config{}
if c.CACertFile != "" {
caCert, _, err := pathorcontents.Read(c.CACertFile)
if err != nil {
return fmt.Errorf("Error reading CA Cert: %s", err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM([]byte(caCert))
config.RootCAs = caCertPool
}
if c.Insecure {
config.InsecureSkipVerify = true
}
if c.ClientCertFile != "" && c.ClientKeyFile != "" {
clientCert, _, err := pathorcontents.Read(c.ClientCertFile)
if err != nil {
return fmt.Errorf("Error reading Client Cert: %s", err)
}
clientKey, _, err := pathorcontents.Read(c.ClientKeyFile)
if err != nil {
return fmt.Errorf("Error reading Client Key: %s", err)
}
cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
if err != nil {
return err
}
config.Certificates = []tls.Certificate{cert}
config.BuildNameToCertificate()
}
// if OS_DEBUG is set, log the requests and responses
var osDebug bool
if os.Getenv("OS_DEBUG") != "" {
osDebug = true
}
transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config}
client.HTTPClient = http.Client{
Transport: &LogRoundTripper{
Rt: transport,
OsDebug: osDebug,
},
}
// If using Swift Authentication, there's no need to validate authentication normally.
if !c.Swauth {
err = openstack.Authenticate(client, ao)
if err != nil {
return err
}
}
c.osClient = client
return nil
}
func (c *Config) blockStorageV1Client(region string) (*gophercloud.ServiceClient, error) {
return openstack.NewBlockStorageV1(c.osClient, gophercloud.EndpointOpts{
Region: region,
Availability: c.getEndpointType(),
})
}
func (c *Config) blockStorageV2Client(region string) (*gophercloud.ServiceClient, error) {
return openstack.NewBlockStorageV2(c.osClient, gophercloud.EndpointOpts{
Region: region,
Availability: c.getEndpointType(),
})
}
func (c *Config) computeV2Client(region string) (*gophercloud.ServiceClient, error) {
return openstack.NewComputeV2(c.osClient, gophercloud.EndpointOpts{
Region: region,
Availability: c.getEndpointType(),
})
}
func (c *Config) imageV2Client(region string) (*gophercloud.ServiceClient, error) {
return openstack.NewImageServiceV2(c.osClient, gophercloud.EndpointOpts{
Region: region,
Availability: c.getEndpointType(),
})
}
func (c *Config) networkingV2Client(region string) (*gophercloud.ServiceClient, error) {
return openstack.NewNetworkV2(c.osClient, gophercloud.EndpointOpts{
Region: region,
Availability: c.getEndpointType(),
})
}
func (c *Config) objectStorageV1Client(region string) (*gophercloud.ServiceClient, error) {
// If Swift Authentication is being used, return a swauth client.
if c.Swauth {
return swauth.NewObjectStorageV1(c.osClient, swauth.AuthOpts{
User: c.Username,
Key: c.Password,
})
}
return openstack.NewObjectStorageV1(c.osClient, gophercloud.EndpointOpts{
Region: region,
Availability: c.getEndpointType(),
})
}
func (c *Config) getEndpointType() gophercloud.Availability {
if c.EndpointType == "internal" || c.EndpointType == "internalURL" {
return gophercloud.AvailabilityInternal
}
if c.EndpointType == "admin" || c.EndpointType == "adminURL" {
return gophercloud.AvailabilityAdmin
}
return gophercloud.AvailabilityPublic
}