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 }