Move deps from _workspace/ to vendor/
godep restore pushd $GOPATH/src/github.com/appc/spec git co master popd go get go4.org/errorutil rm -rf Godeps godep save ./... git add vendor git add -f $(git ls-files --other vendor/) git co -- Godeps/LICENSES Godeps/.license_file_state Godeps/OWNERS
This commit is contained in:
16
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/docs.go
generated
vendored
Normal file
16
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/docs.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Package roles provides functionality to interact with and control roles on
|
||||
// the API.
|
||||
//
|
||||
// A role represents a personality that a user can assume when performing a
|
||||
// specific set of operations. If a role includes a set of rights and
|
||||
// privileges, a user assuming that role inherits those rights and privileges.
|
||||
//
|
||||
// When a token is generated, the list of roles that user can assume is returned
|
||||
// back to them. Services that are being called by that user determine how they
|
||||
// interpret the set of roles a user has and to which operations or resources
|
||||
// each role grants access.
|
||||
//
|
||||
// It is up to individual services such as Compute or Image to assign meaning
|
||||
// to these roles. As far as the Identity service is concerned, a role is an
|
||||
// arbitrary name assigned by the user.
|
||||
package roles
|
48
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/fixtures.go
generated
vendored
Normal file
48
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/fixtures.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
th "github.com/rackspace/gophercloud/testhelper"
|
||||
fake "github.com/rackspace/gophercloud/testhelper/client"
|
||||
)
|
||||
|
||||
func MockListRoleResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/OS-KSADM/roles", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "GET")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
fmt.Fprintf(w, `
|
||||
{
|
||||
"roles": [
|
||||
{
|
||||
"id": "123",
|
||||
"name": "compute:admin",
|
||||
"description": "Nova Administrator"
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
func MockAddUserRoleResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "PUT")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
})
|
||||
}
|
||||
|
||||
func MockDeleteUserRoleResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "DELETE")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
})
|
||||
}
|
33
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/requests.go
generated
vendored
Normal file
33
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/requests.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// List is the operation responsible for listing all available global roles
|
||||
// that a user can adopt.
|
||||
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||
createPage := func(r pagination.PageResult) pagination.Page {
|
||||
return RolePage{pagination.SinglePageBase(r)}
|
||||
}
|
||||
return pagination.NewPager(client, rootURL(client), createPage)
|
||||
}
|
||||
|
||||
// AddUserRole is the operation responsible for assigning a particular role to
|
||||
// a user. This is confined to the scope of the user's tenant - so the tenant
|
||||
// ID is a required argument.
|
||||
func AddUserRole(client *gophercloud.ServiceClient, tenantID, userID, roleID string) UserRoleResult {
|
||||
var result UserRoleResult
|
||||
_, result.Err = client.Put(userRoleURL(client, tenantID, userID, roleID), nil, nil, nil)
|
||||
return result
|
||||
}
|
||||
|
||||
// DeleteUserRole is the operation responsible for deleting a particular role
|
||||
// from a user. This is confined to the scope of the user's tenant - so the
|
||||
// tenant ID is a required argument.
|
||||
func DeleteUserRole(client *gophercloud.ServiceClient, tenantID, userID, roleID string) UserRoleResult {
|
||||
var result UserRoleResult
|
||||
_, result.Err = client.Delete(userRoleURL(client, tenantID, userID, roleID), nil)
|
||||
return result
|
||||
}
|
53
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/results.go
generated
vendored
Normal file
53
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/results.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Role represents an API role resource.
|
||||
type Role struct {
|
||||
// The unique ID for the role.
|
||||
ID string
|
||||
|
||||
// The human-readable name of the role.
|
||||
Name string
|
||||
|
||||
// The description of the role.
|
||||
Description string
|
||||
|
||||
// The associated service for this role.
|
||||
ServiceID string
|
||||
}
|
||||
|
||||
// RolePage is a single page of a user Role collection.
|
||||
type RolePage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a page of Tenants contains any results.
|
||||
func (page RolePage) IsEmpty() (bool, error) {
|
||||
users, err := ExtractRoles(page)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return len(users) == 0, nil
|
||||
}
|
||||
|
||||
// ExtractRoles returns a slice of roles contained in a single page of results.
|
||||
func ExtractRoles(page pagination.Page) ([]Role, error) {
|
||||
casted := page.(RolePage).Body
|
||||
var response struct {
|
||||
Roles []Role `mapstructure:"roles"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(casted, &response)
|
||||
return response.Roles, err
|
||||
}
|
||||
|
||||
// UserRoleResult represents the result of either an AddUserRole or
|
||||
// a DeleteUserRole operation.
|
||||
type UserRoleResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
21
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/urls.go
generated
vendored
Normal file
21
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/admin/roles/urls.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package roles
|
||||
|
||||
import "github.com/rackspace/gophercloud"
|
||||
|
||||
const (
|
||||
ExtPath = "OS-KSADM"
|
||||
RolePath = "roles"
|
||||
UserPath = "users"
|
||||
)
|
||||
|
||||
func resourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL(ExtPath, RolePath, id)
|
||||
}
|
||||
|
||||
func rootURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL(ExtPath, RolePath)
|
||||
}
|
||||
|
||||
func userRoleURL(c *gophercloud.ServiceClient, tenantID, userID, roleID string) string {
|
||||
return c.ServiceURL("tenants", tenantID, UserPath, userID, RolePath, ExtPath, roleID)
|
||||
}
|
52
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/delegate.go
generated
vendored
Normal file
52
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/delegate.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/rackspace/gophercloud"
|
||||
common "github.com/rackspace/gophercloud/openstack/common/extensions"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ExtensionPage is a single page of Extension results.
|
||||
type ExtensionPage struct {
|
||||
common.ExtensionPage
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the current page contains at least one Extension.
|
||||
func (page ExtensionPage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractExtensions(page)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
return len(is) == 0, nil
|
||||
}
|
||||
|
||||
// ExtractExtensions accepts a Page struct, specifically an ExtensionPage struct, and extracts the
|
||||
// elements into a slice of Extension structs.
|
||||
func ExtractExtensions(page pagination.Page) ([]common.Extension, error) {
|
||||
// Identity v2 adds an intermediate "values" object.
|
||||
|
||||
var resp struct {
|
||||
Extensions struct {
|
||||
Values []common.Extension `mapstructure:"values"`
|
||||
} `mapstructure:"extensions"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(page.(ExtensionPage).Body, &resp)
|
||||
return resp.Extensions.Values, err
|
||||
}
|
||||
|
||||
// Get retrieves information for a specific extension using its alias.
|
||||
func Get(c *gophercloud.ServiceClient, alias string) common.GetResult {
|
||||
return common.Get(c, alias)
|
||||
}
|
||||
|
||||
// List returns a Pager which allows you to iterate over the full collection of extensions.
|
||||
// It does not accept query parameters.
|
||||
func List(c *gophercloud.ServiceClient) pagination.Pager {
|
||||
return common.List(c).WithPageCreator(func(r pagination.PageResult) pagination.Page {
|
||||
return ExtensionPage{
|
||||
ExtensionPage: common.ExtensionPage{SinglePageBase: pagination.SinglePageBase(r)},
|
||||
}
|
||||
})
|
||||
}
|
3
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/doc.go
generated
vendored
Normal file
3
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/doc.go
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// Package extensions provides information and interaction with the
|
||||
// different extensions available for the OpenStack Identity service.
|
||||
package extensions
|
60
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/fixtures.go
generated
vendored
Normal file
60
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/extensions/fixtures.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// +build fixtures
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
th "github.com/rackspace/gophercloud/testhelper"
|
||||
"github.com/rackspace/gophercloud/testhelper/client"
|
||||
)
|
||||
|
||||
// ListOutput provides a single Extension result. It differs from the delegated implementation
|
||||
// by the introduction of an intermediate "values" member.
|
||||
const ListOutput = `
|
||||
{
|
||||
"extensions": {
|
||||
"values": [
|
||||
{
|
||||
"updated": "2013-01-20T00:00:00-00:00",
|
||||
"name": "Neutron Service Type Management",
|
||||
"links": [],
|
||||
"namespace": "http://docs.openstack.org/ext/neutron/service-type/api/v1.0",
|
||||
"alias": "service-type",
|
||||
"description": "API for retrieving service providers for Neutron advanced services"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
// HandleListExtensionsSuccessfully creates an HTTP handler that returns ListOutput for a List
|
||||
// call.
|
||||
func HandleListExtensionsSuccessfully(t *testing.T) {
|
||||
th.Mux.HandleFunc("/extensions", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "GET")
|
||||
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
|
||||
fmt.Fprintf(w, `
|
||||
{
|
||||
"extensions": {
|
||||
"values": [
|
||||
{
|
||||
"updated": "2013-01-20T00:00:00-00:00",
|
||||
"name": "Neutron Service Type Management",
|
||||
"links": [],
|
||||
"namespace": "http://docs.openstack.org/ext/neutron/service-type/api/v1.0",
|
||||
"alias": "service-type",
|
||||
"description": "API for retrieving service providers for Neutron advanced services"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
}
|
7
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/doc.go
generated
vendored
Normal file
7
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/doc.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Package tenants provides information and interaction with the
|
||||
// tenants API resource for the OpenStack Identity service.
|
||||
//
|
||||
// See http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2
|
||||
// and http://developer.openstack.org/api-ref-identity-v2.html#admin-tenants
|
||||
// for more information.
|
||||
package tenants
|
65
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/fixtures.go
generated
vendored
Normal file
65
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/fixtures.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// +build fixtures
|
||||
|
||||
package tenants
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
th "github.com/rackspace/gophercloud/testhelper"
|
||||
"github.com/rackspace/gophercloud/testhelper/client"
|
||||
)
|
||||
|
||||
// ListOutput provides a single page of Tenant results.
|
||||
const ListOutput = `
|
||||
{
|
||||
"tenants": [
|
||||
{
|
||||
"id": "1234",
|
||||
"name": "Red Team",
|
||||
"description": "The team that is red",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": "9876",
|
||||
"name": "Blue Team",
|
||||
"description": "The team that is blue",
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
||||
|
||||
// RedTeam is a Tenant fixture.
|
||||
var RedTeam = Tenant{
|
||||
ID: "1234",
|
||||
Name: "Red Team",
|
||||
Description: "The team that is red",
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
// BlueTeam is a Tenant fixture.
|
||||
var BlueTeam = Tenant{
|
||||
ID: "9876",
|
||||
Name: "Blue Team",
|
||||
Description: "The team that is blue",
|
||||
Enabled: false,
|
||||
}
|
||||
|
||||
// ExpectedTenantSlice is the slice of tenants expected to be returned from ListOutput.
|
||||
var ExpectedTenantSlice = []Tenant{RedTeam, BlueTeam}
|
||||
|
||||
// HandleListTenantsSuccessfully creates an HTTP handler at `/tenants` on the test handler mux that
|
||||
// responds with a list of two tenants.
|
||||
func HandleListTenantsSuccessfully(t *testing.T) {
|
||||
th.Mux.HandleFunc("/tenants", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "GET")
|
||||
th.TestHeader(t, r, "Accept", "application/json")
|
||||
th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, ListOutput)
|
||||
})
|
||||
}
|
33
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests.go
generated
vendored
Normal file
33
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/requests.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package tenants
|
||||
|
||||
import (
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ListOpts filters the Tenants that are returned by the List call.
|
||||
type ListOpts struct {
|
||||
// Marker is the ID of the last Tenant on the previous page.
|
||||
Marker string `q:"marker"`
|
||||
|
||||
// Limit specifies the page size.
|
||||
Limit int `q:"limit"`
|
||||
}
|
||||
|
||||
// List enumerates the Tenants to which the current token has access.
|
||||
func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager {
|
||||
createPage := func(r pagination.PageResult) pagination.Page {
|
||||
return TenantPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
}
|
||||
|
||||
url := listURL(client)
|
||||
if opts != nil {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += q.String()
|
||||
}
|
||||
|
||||
return pagination.NewPager(client, url, createPage)
|
||||
}
|
62
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/results.go
generated
vendored
Normal file
62
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/results.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
package tenants
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// Tenant is a grouping of users in the identity service.
|
||||
type Tenant struct {
|
||||
// ID is a unique identifier for this tenant.
|
||||
ID string `mapstructure:"id"`
|
||||
|
||||
// Name is a friendlier user-facing name for this tenant.
|
||||
Name string `mapstructure:"name"`
|
||||
|
||||
// Description is a human-readable explanation of this Tenant's purpose.
|
||||
Description string `mapstructure:"description"`
|
||||
|
||||
// Enabled indicates whether or not a tenant is active.
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
}
|
||||
|
||||
// TenantPage is a single page of Tenant results.
|
||||
type TenantPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a page of Tenants contains any results.
|
||||
func (page TenantPage) IsEmpty() (bool, error) {
|
||||
tenants, err := ExtractTenants(page)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return len(tenants) == 0, nil
|
||||
}
|
||||
|
||||
// NextPageURL extracts the "next" link from the tenants_links section of the result.
|
||||
func (page TenantPage) NextPageURL() (string, error) {
|
||||
type resp struct {
|
||||
Links []gophercloud.Link `mapstructure:"tenants_links"`
|
||||
}
|
||||
|
||||
var r resp
|
||||
err := mapstructure.Decode(page.Body, &r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return gophercloud.ExtractNextURL(r.Links)
|
||||
}
|
||||
|
||||
// ExtractTenants returns a slice of Tenants contained in a single page of results.
|
||||
func ExtractTenants(page pagination.Page) ([]Tenant, error) {
|
||||
casted := page.(TenantPage).Body
|
||||
var response struct {
|
||||
Tenants []Tenant `mapstructure:"tenants"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(casted, &response)
|
||||
return response.Tenants, err
|
||||
}
|
7
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/urls.go
generated
vendored
Normal file
7
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tenants/urls.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package tenants
|
||||
|
||||
import "github.com/rackspace/gophercloud"
|
||||
|
||||
func listURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("tenants")
|
||||
}
|
5
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/doc.go
generated
vendored
Normal file
5
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/doc.go
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// Package tokens provides information and interaction with the token API
|
||||
// resource for the OpenStack Identity service.
|
||||
// For more information, see:
|
||||
// http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2
|
||||
package tokens
|
30
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go
generated
vendored
Normal file
30
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/errors.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUserIDProvided is returned if you attempt to authenticate with a UserID.
|
||||
ErrUserIDProvided = unacceptedAttributeErr("UserID")
|
||||
|
||||
// ErrAPIKeyProvided is returned if you attempt to authenticate with an APIKey.
|
||||
ErrAPIKeyProvided = unacceptedAttributeErr("APIKey")
|
||||
|
||||
// ErrDomainIDProvided is returned if you attempt to authenticate with a DomainID.
|
||||
ErrDomainIDProvided = unacceptedAttributeErr("DomainID")
|
||||
|
||||
// ErrDomainNameProvided is returned if you attempt to authenticate with a DomainName.
|
||||
ErrDomainNameProvided = unacceptedAttributeErr("DomainName")
|
||||
|
||||
// ErrUsernameRequired is returned if you attempt to authenticate without a Username.
|
||||
ErrUsernameRequired = errors.New("You must supply a Username in your AuthOptions.")
|
||||
|
||||
// ErrPasswordRequired is returned if you don't provide a password.
|
||||
ErrPasswordRequired = errors.New("Please supply a Password in your AuthOptions.")
|
||||
)
|
||||
|
||||
func unacceptedAttributeErr(attribute string) error {
|
||||
return fmt.Errorf("The base Identity V2 API does not accept authentication by %s", attribute)
|
||||
}
|
195
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/fixtures.go
generated
vendored
Normal file
195
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/fixtures.go
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
// +build fixtures
|
||||
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/rackspace/gophercloud/openstack/identity/v2/tenants"
|
||||
th "github.com/rackspace/gophercloud/testhelper"
|
||||
thclient "github.com/rackspace/gophercloud/testhelper/client"
|
||||
)
|
||||
|
||||
// ExpectedToken is the token that should be parsed from TokenCreationResponse.
|
||||
var ExpectedToken = &Token{
|
||||
ID: "aaaabbbbccccdddd",
|
||||
ExpiresAt: time.Date(2014, time.January, 31, 15, 30, 58, 0, time.UTC),
|
||||
Tenant: tenants.Tenant{
|
||||
ID: "fc394f2ab2df4114bde39905f800dc57",
|
||||
Name: "test",
|
||||
Description: "There are many tenants. This one is yours.",
|
||||
Enabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
// ExpectedServiceCatalog is the service catalog that should be parsed from TokenCreationResponse.
|
||||
var ExpectedServiceCatalog = &ServiceCatalog{
|
||||
Entries: []CatalogEntry{
|
||||
CatalogEntry{
|
||||
Name: "inscrutablewalrus",
|
||||
Type: "something",
|
||||
Endpoints: []Endpoint{
|
||||
Endpoint{
|
||||
PublicURL: "http://something0:1234/v2/",
|
||||
Region: "region0",
|
||||
},
|
||||
Endpoint{
|
||||
PublicURL: "http://something1:1234/v2/",
|
||||
Region: "region1",
|
||||
},
|
||||
},
|
||||
},
|
||||
CatalogEntry{
|
||||
Name: "arbitrarypenguin",
|
||||
Type: "else",
|
||||
Endpoints: []Endpoint{
|
||||
Endpoint{
|
||||
PublicURL: "http://else0:4321/v3/",
|
||||
Region: "region0",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// ExpectedUser is the token that should be parsed from TokenGetResponse.
|
||||
var ExpectedUser = &User{
|
||||
ID: "a530fefc3d594c4ba2693a4ecd6be74e",
|
||||
Name: "apiserver",
|
||||
Roles: []Role{{"member"}, {"service"}},
|
||||
UserName: "apiserver",
|
||||
}
|
||||
|
||||
// TokenCreationResponse is a JSON response that contains ExpectedToken and ExpectedServiceCatalog.
|
||||
const TokenCreationResponse = `
|
||||
{
|
||||
"access": {
|
||||
"token": {
|
||||
"issued_at": "2014-01-30T15:30:58.000000Z",
|
||||
"expires": "2014-01-31T15:30:58Z",
|
||||
"id": "aaaabbbbccccdddd",
|
||||
"tenant": {
|
||||
"description": "There are many tenants. This one is yours.",
|
||||
"enabled": true,
|
||||
"id": "fc394f2ab2df4114bde39905f800dc57",
|
||||
"name": "test"
|
||||
}
|
||||
},
|
||||
"serviceCatalog": [
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"publicURL": "http://something0:1234/v2/",
|
||||
"region": "region0"
|
||||
},
|
||||
{
|
||||
"publicURL": "http://something1:1234/v2/",
|
||||
"region": "region1"
|
||||
}
|
||||
],
|
||||
"type": "something",
|
||||
"name": "inscrutablewalrus"
|
||||
},
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"publicURL": "http://else0:4321/v3/",
|
||||
"region": "region0"
|
||||
}
|
||||
],
|
||||
"type": "else",
|
||||
"name": "arbitrarypenguin"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
// TokenGetResponse is a JSON response that contains ExpectedToken and ExpectedUser.
|
||||
const TokenGetResponse = `
|
||||
{
|
||||
"access": {
|
||||
"token": {
|
||||
"issued_at": "2014-01-30T15:30:58.000000Z",
|
||||
"expires": "2014-01-31T15:30:58Z",
|
||||
"id": "aaaabbbbccccdddd",
|
||||
"tenant": {
|
||||
"description": "There are many tenants. This one is yours.",
|
||||
"enabled": true,
|
||||
"id": "fc394f2ab2df4114bde39905f800dc57",
|
||||
"name": "test"
|
||||
}
|
||||
},
|
||||
"serviceCatalog": [],
|
||||
"user": {
|
||||
"id": "a530fefc3d594c4ba2693a4ecd6be74e",
|
||||
"name": "apiserver",
|
||||
"roles": [
|
||||
{
|
||||
"name": "member"
|
||||
},
|
||||
{
|
||||
"name": "service"
|
||||
}
|
||||
],
|
||||
"roles_links": [],
|
||||
"username": "apiserver"
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
// HandleTokenPost expects a POST against a /tokens handler, ensures that the request body has been
|
||||
// constructed properly given certain auth options, and returns the result.
|
||||
func HandleTokenPost(t *testing.T, requestJSON string) {
|
||||
th.Mux.HandleFunc("/tokens", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "POST")
|
||||
th.TestHeader(t, r, "Content-Type", "application/json")
|
||||
th.TestHeader(t, r, "Accept", "application/json")
|
||||
if requestJSON != "" {
|
||||
th.TestJSONRequest(t, r, requestJSON)
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, TokenCreationResponse)
|
||||
})
|
||||
}
|
||||
|
||||
// HandleTokenGet expects a Get against a /tokens handler, ensures that the request body has been
|
||||
// constructed properly given certain auth options, and returns the result.
|
||||
func HandleTokenGet(t *testing.T, token string) {
|
||||
th.Mux.HandleFunc("/tokens/"+token, func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "GET")
|
||||
th.TestHeader(t, r, "Accept", "application/json")
|
||||
th.TestHeader(t, r, "X-Auth-Token", thclient.TokenID)
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, TokenGetResponse)
|
||||
})
|
||||
}
|
||||
|
||||
// IsSuccessful ensures that a CreateResult was successful and contains the correct token and
|
||||
// service catalog.
|
||||
func IsSuccessful(t *testing.T, result CreateResult) {
|
||||
token, err := result.ExtractToken()
|
||||
th.AssertNoErr(t, err)
|
||||
th.CheckDeepEquals(t, ExpectedToken, token)
|
||||
|
||||
serviceCatalog, err := result.ExtractServiceCatalog()
|
||||
th.AssertNoErr(t, err)
|
||||
th.CheckDeepEquals(t, ExpectedServiceCatalog, serviceCatalog)
|
||||
}
|
||||
|
||||
// GetIsSuccessful ensures that a GetResult was successful and contains the correct token and
|
||||
// User Info.
|
||||
func GetIsSuccessful(t *testing.T, result GetResult) {
|
||||
token, err := result.ExtractToken()
|
||||
th.AssertNoErr(t, err)
|
||||
th.CheckDeepEquals(t, ExpectedToken, token)
|
||||
|
||||
user, err := result.ExtractUser()
|
||||
th.AssertNoErr(t, err)
|
||||
th.CheckDeepEquals(t, ExpectedUser, user)
|
||||
}
|
99
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go
generated
vendored
Normal file
99
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/requests.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rackspace/gophercloud"
|
||||
)
|
||||
|
||||
// AuthOptionsBuilder describes any argument that may be passed to the Create call.
|
||||
type AuthOptionsBuilder interface {
|
||||
|
||||
// ToTokenCreateMap assembles the Create request body, returning an error if parameters are
|
||||
// missing or inconsistent.
|
||||
ToTokenCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// AuthOptions wraps a gophercloud AuthOptions in order to adhere to the AuthOptionsBuilder
|
||||
// interface.
|
||||
type AuthOptions struct {
|
||||
gophercloud.AuthOptions
|
||||
}
|
||||
|
||||
// WrapOptions embeds a root AuthOptions struct in a package-specific one.
|
||||
func WrapOptions(original gophercloud.AuthOptions) AuthOptions {
|
||||
return AuthOptions{AuthOptions: original}
|
||||
}
|
||||
|
||||
// ToTokenCreateMap converts AuthOptions into nested maps that can be serialized into a JSON
|
||||
// request.
|
||||
func (auth AuthOptions) ToTokenCreateMap() (map[string]interface{}, error) {
|
||||
// Error out if an unsupported auth option is present.
|
||||
if auth.UserID != "" {
|
||||
return nil, ErrUserIDProvided
|
||||
}
|
||||
if auth.APIKey != "" {
|
||||
return nil, ErrAPIKeyProvided
|
||||
}
|
||||
if auth.DomainID != "" {
|
||||
return nil, ErrDomainIDProvided
|
||||
}
|
||||
if auth.DomainName != "" {
|
||||
return nil, ErrDomainNameProvided
|
||||
}
|
||||
|
||||
// Populate the request map.
|
||||
authMap := make(map[string]interface{})
|
||||
|
||||
if auth.Username != "" {
|
||||
if auth.Password != "" {
|
||||
authMap["passwordCredentials"] = map[string]interface{}{
|
||||
"username": auth.Username,
|
||||
"password": auth.Password,
|
||||
}
|
||||
} else {
|
||||
return nil, ErrPasswordRequired
|
||||
}
|
||||
} else if auth.TokenID != "" {
|
||||
authMap["token"] = map[string]interface{}{
|
||||
"id": auth.TokenID,
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("You must provide either username/password or tenantID/token values.")
|
||||
}
|
||||
|
||||
if auth.TenantID != "" {
|
||||
authMap["tenantId"] = auth.TenantID
|
||||
}
|
||||
if auth.TenantName != "" {
|
||||
authMap["tenantName"] = auth.TenantName
|
||||
}
|
||||
|
||||
return map[string]interface{}{"auth": authMap}, nil
|
||||
}
|
||||
|
||||
// Create authenticates to the identity service and attempts to acquire a Token.
|
||||
// If successful, the CreateResult
|
||||
// Generally, rather than interact with this call directly, end users should call openstack.AuthenticatedClient(),
|
||||
// which abstracts all of the gory details about navigating service catalogs and such.
|
||||
func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) CreateResult {
|
||||
request, err := auth.ToTokenCreateMap()
|
||||
if err != nil {
|
||||
return CreateResult{gophercloud.Result{Err: err}}
|
||||
}
|
||||
|
||||
var result CreateResult
|
||||
_, result.Err = client.Post(CreateURL(client), request, &result.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
// Validates and retrieves information for user's token.
|
||||
func Get(client *gophercloud.ServiceClient, token string) GetResult {
|
||||
var result GetResult
|
||||
_, result.Err = client.Get(GetURL(client, token), &result.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
return result
|
||||
}
|
170
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/results.go
generated
vendored
Normal file
170
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/results.go
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/openstack/identity/v2/tenants"
|
||||
)
|
||||
|
||||
// Token provides only the most basic information related to an authentication token.
|
||||
type Token struct {
|
||||
// ID provides the primary means of identifying a user to the OpenStack API.
|
||||
// OpenStack defines this field as an opaque value, so do not depend on its content.
|
||||
// It is safe, however, to compare for equality.
|
||||
ID string
|
||||
|
||||
// ExpiresAt provides a timestamp in ISO 8601 format, indicating when the authentication token becomes invalid.
|
||||
// After this point in time, future API requests made using this authentication token will respond with errors.
|
||||
// Either the caller will need to reauthenticate manually, or more preferably, the caller should exploit automatic re-authentication.
|
||||
// See the AuthOptions structure for more details.
|
||||
ExpiresAt time.Time
|
||||
|
||||
// Tenant provides information about the tenant to which this token grants access.
|
||||
Tenant tenants.Tenant
|
||||
}
|
||||
|
||||
// Authorization need user info which can get from token authentication's response
|
||||
type Role struct {
|
||||
Name string `mapstructure:"name"`
|
||||
}
|
||||
type User struct {
|
||||
ID string `mapstructure:"id"`
|
||||
Name string `mapstructure:"name"`
|
||||
UserName string `mapstructure:"username"`
|
||||
Roles []Role `mapstructure:"roles"`
|
||||
}
|
||||
|
||||
// Endpoint represents a single API endpoint offered by a service.
|
||||
// It provides the public and internal URLs, if supported, along with a region specifier, again if provided.
|
||||
// The significance of the Region field will depend upon your provider.
|
||||
//
|
||||
// In addition, the interface offered by the service will have version information associated with it
|
||||
// through the VersionId, VersionInfo, and VersionList fields, if provided or supported.
|
||||
//
|
||||
// In all cases, fields which aren't supported by the provider and service combined will assume a zero-value ("").
|
||||
type Endpoint struct {
|
||||
TenantID string `mapstructure:"tenantId"`
|
||||
PublicURL string `mapstructure:"publicURL"`
|
||||
InternalURL string `mapstructure:"internalURL"`
|
||||
AdminURL string `mapstructure:"adminURL"`
|
||||
Region string `mapstructure:"region"`
|
||||
VersionID string `mapstructure:"versionId"`
|
||||
VersionInfo string `mapstructure:"versionInfo"`
|
||||
VersionList string `mapstructure:"versionList"`
|
||||
}
|
||||
|
||||
// CatalogEntry provides a type-safe interface to an Identity API V2 service catalog listing.
|
||||
// Each class of service, such as cloud DNS or block storage services, will have a single
|
||||
// CatalogEntry representing it.
|
||||
//
|
||||
// Note: when looking for the desired service, try, whenever possible, to key off the type field.
|
||||
// Otherwise, you'll tie the representation of the service to a specific provider.
|
||||
type CatalogEntry struct {
|
||||
// Name will contain the provider-specified name for the service.
|
||||
Name string `mapstructure:"name"`
|
||||
|
||||
// Type will contain a type string if OpenStack defines a type for the service.
|
||||
// Otherwise, for provider-specific services, the provider may assign their own type strings.
|
||||
Type string `mapstructure:"type"`
|
||||
|
||||
// Endpoints will let the caller iterate over all the different endpoints that may exist for
|
||||
// the service.
|
||||
Endpoints []Endpoint `mapstructure:"endpoints"`
|
||||
}
|
||||
|
||||
// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
|
||||
type ServiceCatalog struct {
|
||||
Entries []CatalogEntry
|
||||
}
|
||||
|
||||
// CreateResult defers the interpretation of a created token.
|
||||
// Use ExtractToken() to interpret it as a Token, or ExtractServiceCatalog() to interpret it as a service catalog.
|
||||
type CreateResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// GetResult is the deferred response from a Get call, which is the same with a Created token.
|
||||
// Use ExtractUser() to interpret it as a User.
|
||||
type GetResult struct {
|
||||
CreateResult
|
||||
}
|
||||
|
||||
// ExtractToken returns the just-created Token from a CreateResult.
|
||||
func (result CreateResult) ExtractToken() (*Token, error) {
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Access struct {
|
||||
Token struct {
|
||||
Expires string `mapstructure:"expires"`
|
||||
ID string `mapstructure:"id"`
|
||||
Tenant tenants.Tenant `mapstructure:"tenant"`
|
||||
} `mapstructure:"token"`
|
||||
} `mapstructure:"access"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(result.Body, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expiresTs, err := time.Parse(gophercloud.RFC3339Milli, response.Access.Token.Expires)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Token{
|
||||
ID: response.Access.Token.ID,
|
||||
ExpiresAt: expiresTs,
|
||||
Tenant: response.Access.Token.Tenant,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
|
||||
func (result CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Access struct {
|
||||
Entries []CatalogEntry `mapstructure:"serviceCatalog"`
|
||||
} `mapstructure:"access"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(result.Body, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ServiceCatalog{Entries: response.Access.Entries}, nil
|
||||
}
|
||||
|
||||
// createErr quickly packs an error in a CreateResult.
|
||||
func createErr(err error) CreateResult {
|
||||
return CreateResult{gophercloud.Result{Err: err}}
|
||||
}
|
||||
|
||||
// ExtractUser returns the User from a GetResult.
|
||||
func (result GetResult) ExtractUser() (*User, error) {
|
||||
if result.Err != nil {
|
||||
return nil, result.Err
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Access struct {
|
||||
User User `mapstructure:"user"`
|
||||
} `mapstructure:"access"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(result.Body, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &response.Access.User, nil
|
||||
}
|
13
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/urls.go
generated
vendored
Normal file
13
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/tokens/urls.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
package tokens
|
||||
|
||||
import "github.com/rackspace/gophercloud"
|
||||
|
||||
// CreateURL generates the URL used to create new Tokens.
|
||||
func CreateURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("tokens")
|
||||
}
|
||||
|
||||
// GetURL generates the URL used to Validate Tokens.
|
||||
func GetURL(client *gophercloud.ServiceClient, token string) string {
|
||||
return client.ServiceURL("tokens", token)
|
||||
}
|
1
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/doc.go
generated
vendored
Normal file
1
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/doc.go
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
package users
|
163
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/fixtures.go
generated
vendored
Normal file
163
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/fixtures.go
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
package users
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
th "github.com/rackspace/gophercloud/testhelper"
|
||||
fake "github.com/rackspace/gophercloud/testhelper/client"
|
||||
)
|
||||
|
||||
func MockListUserResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "GET")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
fmt.Fprintf(w, `
|
||||
{
|
||||
"users":[
|
||||
{
|
||||
"id": "u1000",
|
||||
"name": "John Smith",
|
||||
"username": "jqsmith",
|
||||
"email": "john.smith@example.org",
|
||||
"enabled": true,
|
||||
"tenant_id": "12345"
|
||||
},
|
||||
{
|
||||
"id": "u1001",
|
||||
"name": "Jane Smith",
|
||||
"username": "jqsmith",
|
||||
"email": "jane.smith@example.org",
|
||||
"enabled": true,
|
||||
"tenant_id": "12345"
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
func mockCreateUserResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "POST")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
|
||||
th.TestJSONRequest(t, r, `
|
||||
{
|
||||
"user": {
|
||||
"name": "new_user",
|
||||
"tenant_id": "12345",
|
||||
"enabled": false,
|
||||
"email": "new_user@foo.com"
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
fmt.Fprintf(w, `
|
||||
{
|
||||
"user": {
|
||||
"name": "new_user",
|
||||
"tenant_id": "12345",
|
||||
"enabled": false,
|
||||
"email": "new_user@foo.com",
|
||||
"id": "c39e3de9be2d4c779f1dfd6abacc176d"
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
func mockGetUserResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/users/new_user", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "GET")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
fmt.Fprintf(w, `
|
||||
{
|
||||
"user": {
|
||||
"name": "new_user",
|
||||
"tenant_id": "12345",
|
||||
"enabled": false,
|
||||
"email": "new_user@foo.com",
|
||||
"id": "c39e3de9be2d4c779f1dfd6abacc176d"
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
func mockUpdateUserResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "PUT")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
|
||||
th.TestJSONRequest(t, r, `
|
||||
{
|
||||
"user": {
|
||||
"name": "new_name",
|
||||
"enabled": true,
|
||||
"email": "new_email@foo.com"
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
fmt.Fprintf(w, `
|
||||
{
|
||||
"user": {
|
||||
"name": "new_name",
|
||||
"tenant_id": "12345",
|
||||
"enabled": true,
|
||||
"email": "new_email@foo.com",
|
||||
"id": "c39e3de9be2d4c779f1dfd6abacc176d"
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
func mockDeleteUserResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/users/c39e3de9be2d4c779f1dfd6abacc176d", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "DELETE")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
})
|
||||
}
|
||||
|
||||
func mockListRolesResponse(t *testing.T) {
|
||||
th.Mux.HandleFunc("/tenants/1d8b6120dcc640fda4fc9194ffc80273/users/c39e3de9be2d4c779f1dfd6abacc176d/roles", func(w http.ResponseWriter, r *http.Request) {
|
||||
th.TestMethod(t, r, "GET")
|
||||
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
fmt.Fprintf(w, `
|
||||
{
|
||||
"roles": [
|
||||
{
|
||||
"id": "9fe2ff9ee4384b1894a90878d3e92bab",
|
||||
"name": "foo_role"
|
||||
},
|
||||
{
|
||||
"id": "1ea3d56793574b668e85960fbf651e13",
|
||||
"name": "admin"
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
})
|
||||
}
|
161
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/requests.go
generated
vendored
Normal file
161
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/requests.go
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
package users
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||
createPage := func(r pagination.PageResult) pagination.Page {
|
||||
return UserPage{pagination.SinglePageBase(r)}
|
||||
}
|
||||
|
||||
return pagination.NewPager(client, rootURL(client), createPage)
|
||||
}
|
||||
|
||||
// EnabledState represents whether the user is enabled or not.
|
||||
type EnabledState *bool
|
||||
|
||||
// Useful variables to use when creating or updating users.
|
||||
var (
|
||||
iTrue = true
|
||||
iFalse = false
|
||||
|
||||
Enabled EnabledState = &iTrue
|
||||
Disabled EnabledState = &iFalse
|
||||
)
|
||||
|
||||
// CommonOpts are the parameters that are shared between CreateOpts and
|
||||
// UpdateOpts
|
||||
type CommonOpts struct {
|
||||
// Either a name or username is required. When provided, the value must be
|
||||
// unique or a 409 conflict error will be returned. If you provide a name but
|
||||
// omit a username, the latter will be set to the former; and vice versa.
|
||||
Name, Username string
|
||||
|
||||
// The ID of the tenant to which you want to assign this user.
|
||||
TenantID string
|
||||
|
||||
// Indicates whether this user is enabled or not.
|
||||
Enabled EnabledState
|
||||
|
||||
// The email address of this user.
|
||||
Email string
|
||||
}
|
||||
|
||||
// CreateOpts represents the options needed when creating new users.
|
||||
type CreateOpts CommonOpts
|
||||
|
||||
// CreateOptsBuilder describes struct types that can be accepted by the Create call.
|
||||
type CreateOptsBuilder interface {
|
||||
ToUserCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// ToUserCreateMap assembles a request body based on the contents of a CreateOpts.
|
||||
func (opts CreateOpts) ToUserCreateMap() (map[string]interface{}, error) {
|
||||
m := make(map[string]interface{})
|
||||
|
||||
if opts.Name == "" && opts.Username == "" {
|
||||
return m, errors.New("Either a Name or Username must be provided")
|
||||
}
|
||||
|
||||
if opts.Name != "" {
|
||||
m["name"] = opts.Name
|
||||
}
|
||||
if opts.Username != "" {
|
||||
m["username"] = opts.Username
|
||||
}
|
||||
if opts.Enabled != nil {
|
||||
m["enabled"] = &opts.Enabled
|
||||
}
|
||||
if opts.Email != "" {
|
||||
m["email"] = opts.Email
|
||||
}
|
||||
if opts.TenantID != "" {
|
||||
m["tenant_id"] = opts.TenantID
|
||||
}
|
||||
|
||||
return map[string]interface{}{"user": m}, nil
|
||||
}
|
||||
|
||||
// Create is the operation responsible for creating new users.
|
||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
|
||||
var res CreateResult
|
||||
|
||||
reqBody, err := opts.ToUserCreateMap()
|
||||
if err != nil {
|
||||
res.Err = err
|
||||
return res
|
||||
}
|
||||
|
||||
_, res.Err = client.Post(rootURL(client), reqBody, &res.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// Get requests details on a single user, either by ID.
|
||||
func Get(client *gophercloud.ServiceClient, id string) GetResult {
|
||||
var result GetResult
|
||||
_, result.Err = client.Get(ResourceURL(client, id), &result.Body, nil)
|
||||
return result
|
||||
}
|
||||
|
||||
// UpdateOptsBuilder allows extensions to add additional attributes to the Update request.
|
||||
type UpdateOptsBuilder interface {
|
||||
ToUserUpdateMap() map[string]interface{}
|
||||
}
|
||||
|
||||
// UpdateOpts specifies the base attributes that may be updated on an existing server.
|
||||
type UpdateOpts CommonOpts
|
||||
|
||||
// ToUserUpdateMap formats an UpdateOpts structure into a request body.
|
||||
func (opts UpdateOpts) ToUserUpdateMap() map[string]interface{} {
|
||||
m := make(map[string]interface{})
|
||||
|
||||
if opts.Name != "" {
|
||||
m["name"] = opts.Name
|
||||
}
|
||||
if opts.Username != "" {
|
||||
m["username"] = opts.Username
|
||||
}
|
||||
if opts.Enabled != nil {
|
||||
m["enabled"] = &opts.Enabled
|
||||
}
|
||||
if opts.Email != "" {
|
||||
m["email"] = opts.Email
|
||||
}
|
||||
if opts.TenantID != "" {
|
||||
m["tenant_id"] = opts.TenantID
|
||||
}
|
||||
|
||||
return map[string]interface{}{"user": m}
|
||||
}
|
||||
|
||||
// Update is the operation responsible for updating exist users by their UUID.
|
||||
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
|
||||
var result UpdateResult
|
||||
reqBody := opts.ToUserUpdateMap()
|
||||
_, result.Err = client.Put(ResourceURL(client, id), reqBody, &result.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
// Delete is the operation responsible for permanently deleting an API user.
|
||||
func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
|
||||
var result DeleteResult
|
||||
_, result.Err = client.Delete(ResourceURL(client, id), nil)
|
||||
return result
|
||||
}
|
||||
|
||||
func ListRoles(client *gophercloud.ServiceClient, tenantID, userID string) pagination.Pager {
|
||||
createPage := func(r pagination.PageResult) pagination.Page {
|
||||
return RolePage{pagination.SinglePageBase(r)}
|
||||
}
|
||||
|
||||
return pagination.NewPager(client, listRolesURL(client, tenantID, userID), createPage)
|
||||
}
|
128
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/results.go
generated
vendored
Normal file
128
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/results.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
package users
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// User represents a user resource that exists on the API.
|
||||
type User struct {
|
||||
// The UUID for this user.
|
||||
ID string
|
||||
|
||||
// The human name for this user.
|
||||
Name string
|
||||
|
||||
// The username for this user.
|
||||
Username string
|
||||
|
||||
// Indicates whether the user is enabled (true) or disabled (false).
|
||||
Enabled bool
|
||||
|
||||
// The email address for this user.
|
||||
Email string
|
||||
|
||||
// The ID of the tenant to which this user belongs.
|
||||
TenantID string `mapstructure:"tenant_id"`
|
||||
}
|
||||
|
||||
// Role assigns specific responsibilities to users, allowing them to accomplish
|
||||
// certain API operations whilst scoped to a service.
|
||||
type Role struct {
|
||||
// UUID of the role
|
||||
ID string
|
||||
|
||||
// Name of the role
|
||||
Name string
|
||||
}
|
||||
|
||||
// UserPage is a single page of a User collection.
|
||||
type UserPage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// RolePage is a single page of a user Role collection.
|
||||
type RolePage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a page of Tenants contains any results.
|
||||
func (page UserPage) IsEmpty() (bool, error) {
|
||||
users, err := ExtractUsers(page)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return len(users) == 0, nil
|
||||
}
|
||||
|
||||
// ExtractUsers returns a slice of Tenants contained in a single page of results.
|
||||
func ExtractUsers(page pagination.Page) ([]User, error) {
|
||||
casted := page.(UserPage).Body
|
||||
var response struct {
|
||||
Users []User `mapstructure:"users"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(casted, &response)
|
||||
return response.Users, err
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a page of Tenants contains any results.
|
||||
func (page RolePage) IsEmpty() (bool, error) {
|
||||
users, err := ExtractRoles(page)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return len(users) == 0, nil
|
||||
}
|
||||
|
||||
// ExtractRoles returns a slice of Roles contained in a single page of results.
|
||||
func ExtractRoles(page pagination.Page) ([]Role, error) {
|
||||
casted := page.(RolePage).Body
|
||||
var response struct {
|
||||
Roles []Role `mapstructure:"roles"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(casted, &response)
|
||||
return response.Roles, err
|
||||
}
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets any commonResult as a User, if possible.
|
||||
func (r commonResult) Extract() (*User, error) {
|
||||
if r.Err != nil {
|
||||
return nil, r.Err
|
||||
}
|
||||
|
||||
var response struct {
|
||||
User User `mapstructure:"user"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(r.Body, &response)
|
||||
|
||||
return &response.User, err
|
||||
}
|
||||
|
||||
// CreateResult represents the result of a Create operation
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult represents the result of a Get operation
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult represents the result of an Update operation
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult represents the result of a Delete operation
|
||||
type DeleteResult struct {
|
||||
commonResult
|
||||
}
|
21
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/urls.go
generated
vendored
Normal file
21
vendor/github.com/rackspace/gophercloud/openstack/identity/v2/users/urls.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package users
|
||||
|
||||
import "github.com/rackspace/gophercloud"
|
||||
|
||||
const (
|
||||
tenantPath = "tenants"
|
||||
userPath = "users"
|
||||
rolePath = "roles"
|
||||
)
|
||||
|
||||
func ResourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL(userPath, id)
|
||||
}
|
||||
|
||||
func rootURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL(userPath)
|
||||
}
|
||||
|
||||
func listRolesURL(c *gophercloud.ServiceClient, tenantID, userID string) string {
|
||||
return c.ServiceURL(tenantPath, tenantID, userPath, userID, rolePath)
|
||||
}
|
Reference in New Issue
Block a user