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