package openstack import ( "crypto/tls" "crypto/x509" "fmt" "io/ioutil" "net/http" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack" ) type Config struct { CACertFile string ClientCertFile string ClientKeyFile string DomainID string DomainName string EndpointType string IdentityEndpoint string Insecure bool Password string 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 := ioutil.ReadFile(c.CACertFile) if err != nil { return err } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) config.RootCAs = caCertPool } if c.Insecure { config.InsecureSkipVerify = true } if c.ClientCertFile != "" && c.ClientKeyFile != "" { cert, err := tls.LoadX509KeyPair(c.ClientCertFile, c.ClientKeyFile) if err != nil { return err } config.Certificates = []tls.Certificate{cert} config.BuildNameToCertificate() } transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config} client.HTTPClient.Transport = transport 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) 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) { 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 }