blob: dbd367ef3ad79b80897b1fc8e1411f091690ed1c [file] [log] [blame]
package identity
import (
"github.com/racker/perigee"
)
// AuthResults encapsulates the raw results from an authentication request.
// As OpenStack allows extensions to influence the structure returned in
// ways that Gophercloud cannot predict at compile-time, you should use
// type-safe accessors to work with the data represented by this type,
// such as ServiceCatalog() and Token().
type AuthResults map[string]interface{}
// AuthOptions lets anyone calling Authenticate() supply the required access
// credentials. At present, only Identity V2 API support exists; therefore,
// only Username, Password, and optionally, TenantId are provided. If future
// Identity API versions become available, alternative fields unique to those
// versions may appear here.
//
// Endpoint specifies the HTTP endpoint offering the Identity V2 API.
// Required.
//
// Username is required if using Identity V2 API. Consult with your provider's
// control panel to discover your account's username.
//
// At most one of Password or ApiKey is required if using Identity V2 API.
// Consult with your provider's control panel to discover your account's
// preferred method of authentication.
//
// The TenantId and TenantName fields are optional for the Identity V2 API.
// Some providers allow you to specify a TenantName instead of the TenantId.
// Some require both. Your provider's authentication policies will determine
// how these fields influence authentication.
//
// AllowReauth should be set to true if you grant permission for Gophercloud to
// cache your credentials in memory, and to allow Gophercloud to attempt to
// re-authenticate automatically if/when your token expires. If you set it to
// false, it will not cache these settings, but re-authentication will not be
// possible. This setting defaults to false.
type AuthOptions struct {
Endpoint string
Username string
Password, ApiKey string
TenantId string
TenantName string
AllowReauth bool
}
// Authenticate passes the supplied credentials to the OpenStack provider for authentication.
// If successful, the caller may use Token() to retrieve the authentication token,
// and ServiceCatalog() to retrieve the set of services available to the API user.
func Authenticate(options AuthOptions) (AuthResults, error) {
type AuthContainer struct {
Auth auth `json:"auth"`
}
var ar AuthResults
if options.Endpoint == "" {
return nil, ErrEndpoint
}
if (options.Username == "") || (options.Password == "" && options.ApiKey == "") {
return nil, ErrCredentials
}
url := options.Endpoint + "/tokens"
err := perigee.Post(url, perigee.Options{
ReqBody: &AuthContainer{
Auth: getAuthCredentials(options),
},
Results: &ar,
})
return ar, err
}
func getAuthCredentials(options AuthOptions) auth {
if options.ApiKey == "" {
return auth{
PasswordCredentials: &struct {
Username string `json:"username"`
Password string `json:"password"`
}{
Username: options.Username,
Password: options.Password,
},
TenantId: options.TenantId,
TenantName: options.TenantName,
}
} else {
return auth{
ApiKeyCredentials: &struct {
Username string `json:"username"`
ApiKey string `json:"apiKey"`
}{
Username: options.Username,
ApiKey: options.ApiKey,
},
TenantId: options.TenantId,
TenantName: options.TenantName,
}
}
}
type auth struct {
PasswordCredentials interface{} `json:"passwordCredentials,omitempty"`
ApiKeyCredentials interface{} `json:"RAX-KSKEY:apiKeyCredentials,omitempty"`
TenantId string `json:"tenantId,omitempty"`
TenantName string `json:"tenantName,omitempty"`
}
func GetExtensions(options AuthOptions) (ExtensionsResult, error) {
var exts ExtensionsResult
url := options.Endpoint + "/extensions"
err := perigee.Get(url, perigee.Options{
Results: &exts,
})
return exts, err
}