package openstack import ( "crypto/tls" "crypto/x509" "fmt" "io/ioutil" "net/http" "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack" "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth" ) 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 := 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 // 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) 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 }