github.com/amanya/packer@v0.12.1-0.20161117214323-902ac5ab2eb6/builder/openstack/access_config.go (about) 1 package openstack 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "net/http" 7 "os" 8 9 "github.com/mitchellh/packer/template/interpolate" 10 "github.com/rackspace/gophercloud" 11 "github.com/rackspace/gophercloud/openstack" 12 ) 13 14 // AccessConfig is for common configuration related to openstack access 15 type AccessConfig struct { 16 Username string `mapstructure:"username"` 17 UserID string `mapstructure:"user_id"` 18 Password string `mapstructure:"password"` 19 APIKey string `mapstructure:"api_key"` 20 IdentityEndpoint string `mapstructure:"identity_endpoint"` 21 TenantID string `mapstructure:"tenant_id"` 22 TenantName string `mapstructure:"tenant_name"` 23 DomainID string `mapstructure:"domain_id"` 24 DomainName string `mapstructure:"domain_name"` 25 Insecure bool `mapstructure:"insecure"` 26 Region string `mapstructure:"region"` 27 EndpointType string `mapstructure:"endpoint_type"` 28 29 osClient *gophercloud.ProviderClient 30 } 31 32 func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { 33 if c.EndpointType != "internal" && c.EndpointType != "internalURL" && 34 c.EndpointType != "admin" && c.EndpointType != "adminURL" && 35 c.EndpointType != "public" && c.EndpointType != "publicURL" && 36 c.EndpointType != "" { 37 return []error{fmt.Errorf("Invalid endpoint type provided")} 38 } 39 40 if c.Region == "" { 41 c.Region = os.Getenv("OS_REGION_NAME") 42 } 43 44 // Legacy RackSpace stuff. We're keeping this around to keep things BC. 45 if c.APIKey == "" { 46 c.APIKey = os.Getenv("SDK_API_KEY") 47 } 48 if c.Password == "" { 49 c.Password = os.Getenv("SDK_PASSWORD") 50 } 51 if c.Region == "" { 52 c.Region = os.Getenv("SDK_REGION") 53 } 54 if c.TenantName == "" { 55 c.TenantName = os.Getenv("SDK_PROJECT") 56 } 57 if c.Username == "" { 58 c.Username = os.Getenv("SDK_USERNAME") 59 } 60 61 // Get as much as possible from the end 62 ao, _ := openstack.AuthOptionsFromEnv() 63 64 // Override values if we have them in our config 65 overrides := []struct { 66 From, To *string 67 }{ 68 {&c.Username, &ao.Username}, 69 {&c.UserID, &ao.UserID}, 70 {&c.Password, &ao.Password}, 71 {&c.APIKey, &ao.APIKey}, 72 {&c.IdentityEndpoint, &ao.IdentityEndpoint}, 73 {&c.TenantID, &ao.TenantID}, 74 {&c.TenantName, &ao.TenantName}, 75 {&c.DomainID, &ao.DomainID}, 76 {&c.DomainName, &ao.DomainName}, 77 } 78 for _, s := range overrides { 79 if *s.From != "" { 80 *s.To = *s.From 81 } 82 } 83 84 // Build the client itself 85 client, err := openstack.NewClient(ao.IdentityEndpoint) 86 if err != nil { 87 return []error{err} 88 } 89 90 // If we have insecure set, then create a custom HTTP client that 91 // ignores SSL errors. 92 if c.Insecure { 93 config := &tls.Config{InsecureSkipVerify: true} 94 transport := &http.Transport{TLSClientConfig: config} 95 client.HTTPClient.Transport = transport 96 } 97 98 // Auth 99 err = openstack.Authenticate(client, ao) 100 if err != nil { 101 return []error{err} 102 } 103 104 c.osClient = client 105 return nil 106 } 107 108 func (c *AccessConfig) computeV2Client() (*gophercloud.ServiceClient, error) { 109 return openstack.NewComputeV2(c.osClient, gophercloud.EndpointOpts{ 110 Region: c.Region, 111 Availability: c.getEndpointType(), 112 }) 113 } 114 115 func (c *AccessConfig) getEndpointType() gophercloud.Availability { 116 if c.EndpointType == "internal" || c.EndpointType == "internalURL" { 117 return gophercloud.AvailabilityInternal 118 } 119 if c.EndpointType == "admin" || c.EndpointType == "adminURL" { 120 return gophercloud.AvailabilityAdmin 121 } 122 return gophercloud.AvailabilityPublic 123 }