Merge pull request #9943 from jtopjian/openstack-swauth
provider/openstack: Add Swauth/Swift Authentication
This commit is contained in:
commit
ab0b171b33
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/gophercloud/gophercloud"
|
"github.com/gophercloud/gophercloud"
|
||||||
"github.com/gophercloud/gophercloud/openstack"
|
"github.com/gophercloud/gophercloud/openstack"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -21,6 +22,7 @@ type Config struct {
|
||||||
IdentityEndpoint string
|
IdentityEndpoint string
|
||||||
Insecure bool
|
Insecure bool
|
||||||
Password string
|
Password string
|
||||||
|
Swauth bool
|
||||||
TenantID string
|
TenantID string
|
||||||
TenantName string
|
TenantName string
|
||||||
Token string
|
Token string
|
||||||
|
@ -95,10 +97,13 @@ func (c *Config) loadAndValidate() error {
|
||||||
transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config}
|
transport := &http.Transport{Proxy: http.ProxyFromEnvironment, TLSClientConfig: config}
|
||||||
client.HTTPClient.Transport = transport
|
client.HTTPClient.Transport = transport
|
||||||
|
|
||||||
|
// If using Swift Authentication, there's no need to validate authentication normally.
|
||||||
|
if !c.Swauth {
|
||||||
err = openstack.Authenticate(client, ao)
|
err = openstack.Authenticate(client, ao)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.osClient = client
|
c.osClient = client
|
||||||
|
|
||||||
|
@ -134,6 +139,14 @@ func (c *Config) networkingV2Client(region string) (*gophercloud.ServiceClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) objectStorageV1Client(region string) (*gophercloud.ServiceClient, error) {
|
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{
|
return openstack.NewObjectStorageV1(c.osClient, gophercloud.EndpointOpts{
|
||||||
Region: region,
|
Region: region,
|
||||||
Availability: c.getEndpointType(),
|
Availability: c.getEndpointType(),
|
||||||
|
|
|
@ -125,6 +125,13 @@ func Provider() terraform.ResourceProvider {
|
||||||
DefaultFunc: schema.EnvDefaultFunc("OS_KEY", ""),
|
DefaultFunc: schema.EnvDefaultFunc("OS_KEY", ""),
|
||||||
Description: descriptions["key"],
|
Description: descriptions["key"],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"swauth": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: schema.EnvDefaultFunc("OS_SWAUTH", ""),
|
||||||
|
Description: descriptions["swauth"],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
@ -196,6 +203,9 @@ func init() {
|
||||||
"cert": "A client certificate to authenticate with.",
|
"cert": "A client certificate to authenticate with.",
|
||||||
|
|
||||||
"key": "A client private key to authenticate with.",
|
"key": "A client private key to authenticate with.",
|
||||||
|
|
||||||
|
"swauth": "Use Swift's authentication system instead of Keystone. Only used for\n" +
|
||||||
|
"interaction with Swift.",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +220,7 @@ func configureProvider(d *schema.ResourceData) (interface{}, error) {
|
||||||
IdentityEndpoint: d.Get("auth_url").(string),
|
IdentityEndpoint: d.Get("auth_url").(string),
|
||||||
Insecure: d.Get("insecure").(bool),
|
Insecure: d.Get("insecure").(bool),
|
||||||
Password: d.Get("password").(string),
|
Password: d.Get("password").(string),
|
||||||
|
Swauth: d.Get("swauth").(bool),
|
||||||
Token: d.Get("token").(string),
|
Token: d.Get("token").(string),
|
||||||
TenantID: d.Get("tenant_id").(string),
|
TenantID: d.Get("tenant_id").(string),
|
||||||
TenantName: d.Get("tenant_name").(string),
|
TenantName: d.Get("tenant_name").(string),
|
||||||
|
|
|
@ -56,22 +56,20 @@ func testAccCheckObjectStorageV1ContainerDestroy(s *terraform.State) error {
|
||||||
|
|
||||||
var testAccObjectStorageV1Container_basic = fmt.Sprintf(`
|
var testAccObjectStorageV1Container_basic = fmt.Sprintf(`
|
||||||
resource "openstack_objectstorage_container_v1" "container_1" {
|
resource "openstack_objectstorage_container_v1" "container_1" {
|
||||||
region = "%s"
|
|
||||||
name = "tf-test-container"
|
name = "tf-test-container"
|
||||||
metadata {
|
metadata {
|
||||||
test = "true"
|
test = "true"
|
||||||
}
|
}
|
||||||
content_type = "application/json"
|
content_type = "application/json"
|
||||||
}`,
|
}
|
||||||
OS_REGION_NAME)
|
`)
|
||||||
|
|
||||||
var testAccObjectStorageV1Container_update = fmt.Sprintf(`
|
var testAccObjectStorageV1Container_update = fmt.Sprintf(`
|
||||||
resource "openstack_objectstorage_container_v1" "container_1" {
|
resource "openstack_objectstorage_container_v1" "container_1" {
|
||||||
region = "%s"
|
|
||||||
name = "tf-test-container"
|
name = "tf-test-container"
|
||||||
metadata {
|
metadata {
|
||||||
test = "true"
|
test = "true"
|
||||||
}
|
}
|
||||||
content_type = "text/plain"
|
content_type = "text/plain"
|
||||||
}`,
|
}
|
||||||
OS_REGION_NAME)
|
`)
|
||||||
|
|
70
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth/requests.go
generated
vendored
Normal file
70
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth/requests.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package swauth
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
// AuthOptsBuilder describes struct types that can be accepted by the Auth call.
|
||||||
|
// The AuthOpts struct in this package does.
|
||||||
|
type AuthOptsBuilder interface {
|
||||||
|
ToAuthOptsMap() (map[string]string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthOpts specifies an authentication request.
|
||||||
|
type AuthOpts struct {
|
||||||
|
// User is an Swauth-based username in username:tenant format.
|
||||||
|
User string `h:"X-Auth-User" required:"true"`
|
||||||
|
// Key is a secret/password to authenticate the User with.
|
||||||
|
Key string `h:"X-Auth-Key" required:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToAuthOptsMap formats an AuthOpts structure into a request body.
|
||||||
|
func (opts AuthOpts) ToAuthOptsMap() (map[string]string, error) {
|
||||||
|
return gophercloud.BuildHeaders(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auth performs an authentication request for a Swauth-based user.
|
||||||
|
func Auth(c *gophercloud.ProviderClient, opts AuthOptsBuilder) (r GetAuthResult) {
|
||||||
|
h := make(map[string]string)
|
||||||
|
|
||||||
|
if opts != nil {
|
||||||
|
headers, err := opts.ToAuthOptsMap()
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range headers {
|
||||||
|
h[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.Request("GET", getURL(c), &gophercloud.RequestOpts{
|
||||||
|
MoreHeaders: h,
|
||||||
|
OkCodes: []int{200},
|
||||||
|
})
|
||||||
|
|
||||||
|
if resp != nil {
|
||||||
|
r.Header = resp.Header
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Err = err
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewObjectStorageV1 creates a Swauth-authenticated *gophercloud.ServiceClient
|
||||||
|
// client that can issue ObjectStorage-based API calls.
|
||||||
|
func NewObjectStorageV1(pc *gophercloud.ProviderClient, authOpts AuthOpts) (*gophercloud.ServiceClient, error) {
|
||||||
|
auth, err := Auth(pc, authOpts).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
swiftClient := &gophercloud.ServiceClient{
|
||||||
|
ProviderClient: pc,
|
||||||
|
Endpoint: gophercloud.NormalizeURL(auth.StorageURL),
|
||||||
|
}
|
||||||
|
|
||||||
|
swiftClient.TokenID = auth.Token
|
||||||
|
|
||||||
|
return swiftClient, nil
|
||||||
|
}
|
27
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth/results.go
generated
vendored
Normal file
27
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth/results.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package swauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetAuthResult temporarily contains the response from a Swauth
|
||||||
|
// authentication call.
|
||||||
|
type GetAuthResult struct {
|
||||||
|
gophercloud.HeaderResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthResult contains the authentication information from a Swauth
|
||||||
|
// authentication request.
|
||||||
|
type AuthResult struct {
|
||||||
|
Token string `json:"X-Auth-Token"`
|
||||||
|
StorageURL string `json:"X-Storage-Url"`
|
||||||
|
CDNURL string `json:"X-CDN-Management-Url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract is a method that attempts to interpret any Swauth authentication
|
||||||
|
// response as a AuthResult struct.
|
||||||
|
func (r GetAuthResult) Extract() (*AuthResult, error) {
|
||||||
|
var s *AuthResult
|
||||||
|
err := r.ExtractInto(&s)
|
||||||
|
return s, err
|
||||||
|
}
|
7
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth/urls.go
generated
vendored
Normal file
7
vendor/github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth/urls.go
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package swauth
|
||||||
|
|
||||||
|
import "github.com/gophercloud/gophercloud"
|
||||||
|
|
||||||
|
func getURL(c *gophercloud.ProviderClient) string {
|
||||||
|
return c.IdentityBase + "auth/v1.0"
|
||||||
|
}
|
|
@ -1377,6 +1377,12 @@
|
||||||
"revision": "45720eeefeeeba03b2d7da500297ec68eeee51af",
|
"revision": "45720eeefeeeba03b2d7da500297ec68eeee51af",
|
||||||
"revisionTime": "2016-10-31T15:28:56Z"
|
"revisionTime": "2016-10-31T15:28:56Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "roxPPVwS2CjJhf0CApHNQxAX7EA=",
|
||||||
|
"path": "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth",
|
||||||
|
"revision": "d5eda9707e146108e4d424062b602fd97a71c2e6",
|
||||||
|
"revisionTime": "2016-11-14T18:28:31Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "TDOZnaS0TO0NirpxV1QwPerAQTY=",
|
"checksumSHA1": "TDOZnaS0TO0NirpxV1QwPerAQTY=",
|
||||||
"path": "github.com/gophercloud/gophercloud/openstack/utils",
|
"path": "github.com/gophercloud/gophercloud/openstack/utils",
|
||||||
|
|
|
@ -86,6 +86,13 @@ The following arguments are supported:
|
||||||
service catalog. It can be set using the OS_ENDPOINT_TYPE environment
|
service catalog. It can be set using the OS_ENDPOINT_TYPE environment
|
||||||
variable. If not set, public endpoints is used.
|
variable. If not set, public endpoints is used.
|
||||||
|
|
||||||
|
* `swauth` - (Optional) Set to `true` to authenticate against Swauth, a
|
||||||
|
Swift-native authentication system. If omitted, the `OS_SWAUTH` environment
|
||||||
|
variable is used. You must also set `username` to the Swauth/Swift username
|
||||||
|
such as `username:project`. Set the `password` to the Swauth/Swift key.
|
||||||
|
Finally, set `auth_url` as the location of the Swift service. Note that this
|
||||||
|
will only work when used with the OpenStack Object Storage resources.
|
||||||
|
|
||||||
## Rackspace Compatibility
|
## Rackspace Compatibility
|
||||||
|
|
||||||
Using this OpenStack provider with Rackspace is not supported and not
|
Using this OpenStack provider with Rackspace is not supported and not
|
||||||
|
|
Loading…
Reference in New Issue