github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/builder/openstack/access_config.go (about) 1 package openstack 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "github.com/mitchellh/packer/common" 7 "github.com/mitchellh/packer/packer" 8 "github.com/rackspace/gophercloud" 9 "net/http" 10 "net/url" 11 "os" 12 "strings" 13 ) 14 15 // AccessConfig is for common configuration related to openstack access 16 type AccessConfig struct { 17 Username string `mapstructure:"username"` 18 Password string `mapstructure:"password"` 19 ApiKey string `mapstructure:"api_key"` 20 Project string `mapstructure:"project"` 21 Provider string `mapstructure:"provider"` 22 RawRegion string `mapstructure:"region"` 23 ProxyUrl string `mapstructure:"proxy_url"` 24 TenantId string `mapstructure:"tenant_id"` 25 Insecure bool `mapstructure:"insecure"` 26 } 27 28 // Auth returns a valid Auth object for access to openstack services, or 29 // an error if the authentication couldn't be resolved. 30 func (c *AccessConfig) Auth() (gophercloud.AccessProvider, error) { 31 c.Username = common.ChooseString(c.Username, os.Getenv("SDK_USERNAME"), os.Getenv("OS_USERNAME")) 32 c.Password = common.ChooseString(c.Password, os.Getenv("SDK_PASSWORD"), os.Getenv("OS_PASSWORD")) 33 c.ApiKey = common.ChooseString(c.ApiKey, os.Getenv("SDK_API_KEY")) 34 c.Project = common.ChooseString(c.Project, os.Getenv("SDK_PROJECT"), os.Getenv("OS_TENANT_NAME")) 35 c.Provider = common.ChooseString(c.Provider, os.Getenv("SDK_PROVIDER"), os.Getenv("OS_AUTH_URL")) 36 c.RawRegion = common.ChooseString(c.RawRegion, os.Getenv("SDK_REGION"), os.Getenv("OS_REGION_NAME")) 37 c.TenantId = common.ChooseString(c.TenantId, os.Getenv("OS_TENANT_ID")) 38 39 // OpenStack's auto-generated openrc.sh files do not append the suffix 40 // /tokens to the authentication URL. This ensures it is present when 41 // specifying the URL. 42 if strings.Contains(c.Provider, "://") && !strings.HasSuffix(c.Provider, "/tokens") { 43 c.Provider += "/tokens" 44 } 45 46 authoptions := gophercloud.AuthOptions{ 47 AllowReauth: true, 48 49 ApiKey: c.ApiKey, 50 TenantId: c.TenantId, 51 TenantName: c.Project, 52 Username: c.Username, 53 Password: c.Password, 54 } 55 56 default_transport := &http.Transport{} 57 58 if c.Insecure { 59 cfg := new(tls.Config) 60 cfg.InsecureSkipVerify = true 61 default_transport.TLSClientConfig = cfg 62 } 63 64 // For corporate networks it may be the case where we want our API calls 65 // to be sent through a separate HTTP proxy than external traffic. 66 if c.ProxyUrl != "" { 67 url, err := url.Parse(c.ProxyUrl) 68 if err != nil { 69 return nil, err 70 } 71 72 // The gophercloud.Context has a UseCustomClient method which 73 // would allow us to override with a new instance of http.Client. 74 default_transport.Proxy = http.ProxyURL(url) 75 } 76 77 if c.Insecure || c.ProxyUrl != "" { 78 http.DefaultTransport = default_transport 79 } 80 81 return gophercloud.Authenticate(c.Provider, authoptions) 82 } 83 84 func (c *AccessConfig) Region() string { 85 return common.ChooseString(c.RawRegion, os.Getenv("SDK_REGION"), os.Getenv("OS_REGION_NAME")) 86 } 87 88 func (c *AccessConfig) Prepare(t *packer.ConfigTemplate) []error { 89 if t == nil { 90 var err error 91 t, err = packer.NewConfigTemplate() 92 if err != nil { 93 return []error{err} 94 } 95 } 96 97 templates := map[string]*string{ 98 "username": &c.Username, 99 "password": &c.Password, 100 "api_key": &c.ApiKey, 101 "provider": &c.Provider, 102 "project": &c.Project, 103 "tenant_id": &c.TenantId, 104 "region": &c.RawRegion, 105 "proxy_url": &c.ProxyUrl, 106 } 107 108 errs := make([]error, 0) 109 for n, ptr := range templates { 110 var err error 111 *ptr, err = t.Process(*ptr, nil) 112 if err != nil { 113 errs = append( 114 errs, fmt.Errorf("Error processing %s: %s", n, err)) 115 } 116 } 117 118 if strings.HasPrefix(c.Provider, "rackspace") { 119 if c.Region() == "" { 120 errs = append(errs, fmt.Errorf("region must be specified when using rackspace")) 121 } 122 } 123 124 if len(errs) > 0 { 125 return errs 126 } 127 128 return nil 129 }