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:
6
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/doc.go
generated
vendored
Normal file
6
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/doc.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// Package endpoints provides information and interaction with the service
|
||||
// endpoints API resource in the OpenStack Identity service.
|
||||
//
|
||||
// For more information, see:
|
||||
// http://developer.openstack.org/api-ref-identity-v3.html#endpoints-v3
|
||||
package endpoints
|
21
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/errors.go
generated
vendored
Normal file
21
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/errors.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package endpoints
|
||||
|
||||
import "fmt"
|
||||
|
||||
func requiredAttribute(attribute string) error {
|
||||
return fmt.Errorf("You must specify %s for this endpoint.", attribute)
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrAvailabilityRequired is reported if an Endpoint is created without an Availability.
|
||||
ErrAvailabilityRequired = requiredAttribute("an availability")
|
||||
|
||||
// ErrNameRequired is reported if an Endpoint is created without a Name.
|
||||
ErrNameRequired = requiredAttribute("a name")
|
||||
|
||||
// ErrURLRequired is reported if an Endpoint is created without a URL.
|
||||
ErrURLRequired = requiredAttribute("a URL")
|
||||
|
||||
// ErrServiceIDRequired is reported if an Endpoint is created without a ServiceID.
|
||||
ErrServiceIDRequired = requiredAttribute("a serviceID")
|
||||
)
|
123
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/requests.go
generated
vendored
Normal file
123
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/requests.go
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// EndpointOpts contains the subset of Endpoint attributes that should be used to create or update an Endpoint.
|
||||
type EndpointOpts struct {
|
||||
Availability gophercloud.Availability
|
||||
Name string
|
||||
Region string
|
||||
URL string
|
||||
ServiceID string
|
||||
}
|
||||
|
||||
// Create inserts a new Endpoint into the service catalog.
|
||||
// Within EndpointOpts, Region may be omitted by being left as "", but all other fields are required.
|
||||
func Create(client *gophercloud.ServiceClient, opts EndpointOpts) CreateResult {
|
||||
// Redefined so that Region can be re-typed as a *string, which can be omitted from the JSON output.
|
||||
type endpoint struct {
|
||||
Interface string `json:"interface"`
|
||||
Name string `json:"name"`
|
||||
Region *string `json:"region,omitempty"`
|
||||
URL string `json:"url"`
|
||||
ServiceID string `json:"service_id"`
|
||||
}
|
||||
|
||||
type request struct {
|
||||
Endpoint endpoint `json:"endpoint"`
|
||||
}
|
||||
|
||||
// Ensure that EndpointOpts is fully populated.
|
||||
if opts.Availability == "" {
|
||||
return createErr(ErrAvailabilityRequired)
|
||||
}
|
||||
if opts.Name == "" {
|
||||
return createErr(ErrNameRequired)
|
||||
}
|
||||
if opts.URL == "" {
|
||||
return createErr(ErrURLRequired)
|
||||
}
|
||||
if opts.ServiceID == "" {
|
||||
return createErr(ErrServiceIDRequired)
|
||||
}
|
||||
|
||||
// Populate the request body.
|
||||
reqBody := request{
|
||||
Endpoint: endpoint{
|
||||
Interface: string(opts.Availability),
|
||||
Name: opts.Name,
|
||||
URL: opts.URL,
|
||||
ServiceID: opts.ServiceID,
|
||||
},
|
||||
}
|
||||
reqBody.Endpoint.Region = gophercloud.MaybeString(opts.Region)
|
||||
|
||||
var result CreateResult
|
||||
_, result.Err = client.Post(listURL(client), reqBody, &result.Body, nil)
|
||||
return result
|
||||
}
|
||||
|
||||
// ListOpts allows finer control over the endpoints returned by a List call.
|
||||
// All fields are optional.
|
||||
type ListOpts struct {
|
||||
Availability gophercloud.Availability `q:"interface"`
|
||||
ServiceID string `q:"service_id"`
|
||||
Page int `q:"page"`
|
||||
PerPage int `q:"per_page"`
|
||||
}
|
||||
|
||||
// List enumerates endpoints in a paginated collection, optionally filtered by ListOpts criteria.
|
||||
func List(client *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
|
||||
u := listURL(client)
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
u += q.String()
|
||||
createPage := func(r pagination.PageResult) pagination.Page {
|
||||
return EndpointPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
}
|
||||
|
||||
return pagination.NewPager(client, u, createPage)
|
||||
}
|
||||
|
||||
// Update changes an existing endpoint with new data.
|
||||
// All fields are optional in the provided EndpointOpts.
|
||||
func Update(client *gophercloud.ServiceClient, endpointID string, opts EndpointOpts) UpdateResult {
|
||||
type endpoint struct {
|
||||
Interface *string `json:"interface,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Region *string `json:"region,omitempty"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
ServiceID *string `json:"service_id,omitempty"`
|
||||
}
|
||||
|
||||
type request struct {
|
||||
Endpoint endpoint `json:"endpoint"`
|
||||
}
|
||||
|
||||
reqBody := request{Endpoint: endpoint{}}
|
||||
reqBody.Endpoint.Interface = gophercloud.MaybeString(string(opts.Availability))
|
||||
reqBody.Endpoint.Name = gophercloud.MaybeString(opts.Name)
|
||||
reqBody.Endpoint.Region = gophercloud.MaybeString(opts.Region)
|
||||
reqBody.Endpoint.URL = gophercloud.MaybeString(opts.URL)
|
||||
reqBody.Endpoint.ServiceID = gophercloud.MaybeString(opts.ServiceID)
|
||||
|
||||
var result UpdateResult
|
||||
_, result.Err = client.Request("PATCH", endpointURL(client, endpointID), gophercloud.RequestOpts{
|
||||
JSONBody: &reqBody,
|
||||
JSONResponse: &result.Body,
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
// Delete removes an endpoint from the service catalog.
|
||||
func Delete(client *gophercloud.ServiceClient, endpointID string) DeleteResult {
|
||||
var res DeleteResult
|
||||
_, res.Err = client.Delete(endpointURL(client, endpointID), nil)
|
||||
return res
|
||||
}
|
82
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/results.go
generated
vendored
Normal file
82
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/results.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Endpoint.
|
||||
// An error is returned if the original call or the extraction failed.
|
||||
func (r commonResult) Extract() (*Endpoint, error) {
|
||||
if r.Err != nil {
|
||||
return nil, r.Err
|
||||
}
|
||||
|
||||
var res struct {
|
||||
Endpoint `json:"endpoint"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(r.Body, &res)
|
||||
|
||||
return &res.Endpoint, err
|
||||
}
|
||||
|
||||
// CreateResult is the deferred result of a Create call.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// createErr quickly wraps an error in a CreateResult.
|
||||
func createErr(err error) CreateResult {
|
||||
return CreateResult{commonResult{gophercloud.Result{Err: err}}}
|
||||
}
|
||||
|
||||
// UpdateResult is the deferred result of an Update call.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult is the deferred result of an Delete call.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// Endpoint describes the entry point for another service's API.
|
||||
type Endpoint struct {
|
||||
ID string `mapstructure:"id" json:"id"`
|
||||
Availability gophercloud.Availability `mapstructure:"interface" json:"interface"`
|
||||
Name string `mapstructure:"name" json:"name"`
|
||||
Region string `mapstructure:"region" json:"region"`
|
||||
ServiceID string `mapstructure:"service_id" json:"service_id"`
|
||||
URL string `mapstructure:"url" json:"url"`
|
||||
}
|
||||
|
||||
// EndpointPage is a single page of Endpoint results.
|
||||
type EndpointPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if no Endpoints were returned.
|
||||
func (p EndpointPage) IsEmpty() (bool, error) {
|
||||
es, err := ExtractEndpoints(p)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
return len(es) == 0, nil
|
||||
}
|
||||
|
||||
// ExtractEndpoints extracts an Endpoint slice from a Page.
|
||||
func ExtractEndpoints(page pagination.Page) ([]Endpoint, error) {
|
||||
var response struct {
|
||||
Endpoints []Endpoint `mapstructure:"endpoints"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(page.(EndpointPage).Body, &response)
|
||||
|
||||
return response.Endpoints, err
|
||||
}
|
11
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/urls.go
generated
vendored
Normal file
11
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/endpoints/urls.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package endpoints
|
||||
|
||||
import "github.com/rackspace/gophercloud"
|
||||
|
||||
func listURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("endpoints")
|
||||
}
|
||||
|
||||
func endpointURL(client *gophercloud.ServiceClient, endpointID string) string {
|
||||
return client.ServiceURL("endpoints", endpointID)
|
||||
}
|
3
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/roles/doc.go
generated
vendored
Normal file
3
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/roles/doc.go
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// Package roles provides information and interaction with the roles API
|
||||
// resource for the OpenStack Identity service.
|
||||
package roles
|
50
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests.go
generated
vendored
Normal file
50
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/roles/requests.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// ListAssignmentsOptsBuilder allows extensions to add additional parameters to
|
||||
// the ListAssignments request.
|
||||
type ListAssignmentsOptsBuilder interface {
|
||||
ToRolesListAssignmentsQuery() (string, error)
|
||||
}
|
||||
|
||||
// ListAssignmentsOpts allows you to query the ListAssignments method.
|
||||
// Specify one of or a combination of GroupId, RoleId, ScopeDomainId, ScopeProjectId,
|
||||
// and/or UserId to search for roles assigned to corresponding entities.
|
||||
// Effective lists effective assignments at the user, project, and domain level,
|
||||
// allowing for the effects of group membership.
|
||||
type ListAssignmentsOpts struct {
|
||||
GroupId string `q:"group.id"`
|
||||
RoleId string `q:"role.id"`
|
||||
ScopeDomainId string `q:"scope.domain.id"`
|
||||
ScopeProjectId string `q:"scope.project.id"`
|
||||
UserId string `q:"user.id"`
|
||||
Effective bool `q:"effective"`
|
||||
}
|
||||
|
||||
// ToRolesListAssignmentsQuery formats a ListAssignmentsOpts into a query string.
|
||||
func (opts ListAssignmentsOpts) ToRolesListAssignmentsQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return q.String(), nil
|
||||
}
|
||||
|
||||
// ListAssignments enumerates the roles assigned to a specified resource.
|
||||
func ListAssignments(client *gophercloud.ServiceClient, opts ListAssignmentsOptsBuilder) pagination.Pager {
|
||||
url := listAssignmentsURL(client)
|
||||
query, err := opts.ToRolesListAssignmentsQuery()
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
url += query
|
||||
createPage := func(r pagination.PageResult) pagination.Page {
|
||||
return RoleAssignmentsPage{pagination.LinkedPageBase{PageResult: r}}
|
||||
}
|
||||
|
||||
return pagination.NewPager(client, url, createPage)
|
||||
}
|
81
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/roles/results.go
generated
vendored
Normal file
81
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/roles/results.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
package roles
|
||||
|
||||
import (
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
// RoleAssignment is the result of a role assignments query.
|
||||
type RoleAssignment struct {
|
||||
Role Role `json:"role,omitempty"`
|
||||
Scope Scope `json:"scope,omitempty"`
|
||||
User User `json:"user,omitempty"`
|
||||
Group Group `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
type Role struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type Scope struct {
|
||||
Domain Domain `json:"domain,omitempty"`
|
||||
Project Project `json:"domain,omitempty"`
|
||||
}
|
||||
|
||||
type Domain struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
// RoleAssignmentsPage is a single page of RoleAssignments results.
|
||||
type RoleAssignmentsPage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the page contains no results.
|
||||
func (p RoleAssignmentsPage) IsEmpty() (bool, error) {
|
||||
roleAssignments, err := ExtractRoleAssignments(p)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
return len(roleAssignments) == 0, nil
|
||||
}
|
||||
|
||||
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
|
||||
func (page RoleAssignmentsPage) NextPageURL() (string, error) {
|
||||
type resp struct {
|
||||
Links struct {
|
||||
Next string `mapstructure:"next"`
|
||||
} `mapstructure:"links"`
|
||||
}
|
||||
|
||||
var r resp
|
||||
err := mapstructure.Decode(page.Body, &r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return r.Links.Next, nil
|
||||
}
|
||||
|
||||
// ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection acquired from List.
|
||||
func ExtractRoleAssignments(page pagination.Page) ([]RoleAssignment, error) {
|
||||
var response struct {
|
||||
RoleAssignments []RoleAssignment `mapstructure:"role_assignments"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(page.(RoleAssignmentsPage).Body, &response)
|
||||
return response.RoleAssignments, err
|
||||
}
|
7
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls.go
generated
vendored
Normal file
7
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/roles/urls.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package roles
|
||||
|
||||
import "github.com/rackspace/gophercloud"
|
||||
|
||||
func listAssignmentsURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("role_assignments")
|
||||
}
|
3
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/services/doc.go
generated
vendored
Normal file
3
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/services/doc.go
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// Package services provides information and interaction with the services API
|
||||
// resource for the OpenStack Identity service.
|
||||
package services
|
77
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/services/requests.go
generated
vendored
Normal file
77
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/services/requests.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
)
|
||||
|
||||
type response struct {
|
||||
Service Service `json:"service"`
|
||||
}
|
||||
|
||||
// Create adds a new service of the requested type to the catalog.
|
||||
func Create(client *gophercloud.ServiceClient, serviceType string) CreateResult {
|
||||
type request struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
req := request{Type: serviceType}
|
||||
|
||||
var result CreateResult
|
||||
_, result.Err = client.Post(listURL(client), req, &result.Body, nil)
|
||||
return result
|
||||
}
|
||||
|
||||
// ListOpts allows you to query the List method.
|
||||
type ListOpts struct {
|
||||
ServiceType string `q:"type"`
|
||||
PerPage int `q:"perPage"`
|
||||
Page int `q:"page"`
|
||||
}
|
||||
|
||||
// List enumerates the services available to a specific user.
|
||||
func List(client *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
|
||||
u := listURL(client)
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
if err != nil {
|
||||
return pagination.Pager{Err: err}
|
||||
}
|
||||
u += q.String()
|
||||
createPage := func(r pagination.PageResult) pagination.Page {
|
||||
return ServicePage{pagination.LinkedPageBase{PageResult: r}}
|
||||
}
|
||||
|
||||
return pagination.NewPager(client, u, createPage)
|
||||
}
|
||||
|
||||
// Get returns additional information about a service, given its ID.
|
||||
func Get(client *gophercloud.ServiceClient, serviceID string) GetResult {
|
||||
var result GetResult
|
||||
_, result.Err = client.Get(serviceURL(client, serviceID), &result.Body, nil)
|
||||
return result
|
||||
}
|
||||
|
||||
// Update changes the service type of an existing service.
|
||||
func Update(client *gophercloud.ServiceClient, serviceID string, serviceType string) UpdateResult {
|
||||
type request struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
req := request{Type: serviceType}
|
||||
|
||||
var result UpdateResult
|
||||
_, result.Err = client.Request("PATCH", serviceURL(client, serviceID), gophercloud.RequestOpts{
|
||||
JSONBody: &req,
|
||||
JSONResponse: &result.Body,
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
// Delete removes an existing service.
|
||||
// It either deletes all associated endpoints, or fails until all endpoints are deleted.
|
||||
func Delete(client *gophercloud.ServiceClient, serviceID string) DeleteResult {
|
||||
var res DeleteResult
|
||||
_, res.Err = client.Delete(serviceURL(client, serviceID), nil)
|
||||
return res
|
||||
}
|
80
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/services/results.go
generated
vendored
Normal file
80
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/services/results.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/rackspace/gophercloud"
|
||||
"github.com/rackspace/gophercloud/pagination"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Service.
|
||||
// An error is returned if the original call or the extraction failed.
|
||||
func (r commonResult) Extract() (*Service, error) {
|
||||
if r.Err != nil {
|
||||
return nil, r.Err
|
||||
}
|
||||
|
||||
var res struct {
|
||||
Service `json:"service"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(r.Body, &res)
|
||||
|
||||
return &res.Service, err
|
||||
}
|
||||
|
||||
// CreateResult is the deferred result of a Create call.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult is the deferred result of a Get call.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult is the deferred result of an Update call.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult is the deferred result of an Delete call.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
||||
|
||||
// Service is the result of a list or information query.
|
||||
type Service struct {
|
||||
Description *string `json:"description,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// ServicePage is a single page of Service results.
|
||||
type ServicePage struct {
|
||||
pagination.LinkedPageBase
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the page contains no results.
|
||||
func (p ServicePage) IsEmpty() (bool, error) {
|
||||
services, err := ExtractServices(p)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
return len(services) == 0, nil
|
||||
}
|
||||
|
||||
// ExtractServices extracts a slice of Services from a Collection acquired from List.
|
||||
func ExtractServices(page pagination.Page) ([]Service, error) {
|
||||
var response struct {
|
||||
Services []Service `mapstructure:"services"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(page.(ServicePage).Body, &response)
|
||||
return response.Services, err
|
||||
}
|
11
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/services/urls.go
generated
vendored
Normal file
11
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/services/urls.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package services
|
||||
|
||||
import "github.com/rackspace/gophercloud"
|
||||
|
||||
func listURL(client *gophercloud.ServiceClient) string {
|
||||
return client.ServiceURL("services")
|
||||
}
|
||||
|
||||
func serviceURL(client *gophercloud.ServiceClient, serviceID string) string {
|
||||
return client.ServiceURL("services", serviceID)
|
||||
}
|
6
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/doc.go
generated
vendored
Normal file
6
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/doc.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// 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-v3.html#tokens-v3
|
||||
package tokens
|
72
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/errors.go
generated
vendored
Normal file
72
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/errors.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func unacceptedAttributeErr(attribute string) error {
|
||||
return fmt.Errorf("The base Identity V3 API does not accept authentication by %s", attribute)
|
||||
}
|
||||
|
||||
func redundantWithTokenErr(attribute string) error {
|
||||
return fmt.Errorf("%s may not be provided when authenticating with a TokenID", attribute)
|
||||
}
|
||||
|
||||
func redundantWithUserID(attribute string) error {
|
||||
return fmt.Errorf("%s may not be provided when authenticating with a UserID", attribute)
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrAPIKeyProvided indicates that an APIKey was provided but can't be used.
|
||||
ErrAPIKeyProvided = unacceptedAttributeErr("APIKey")
|
||||
|
||||
// ErrTenantIDProvided indicates that a TenantID was provided but can't be used.
|
||||
ErrTenantIDProvided = unacceptedAttributeErr("TenantID")
|
||||
|
||||
// ErrTenantNameProvided indicates that a TenantName was provided but can't be used.
|
||||
ErrTenantNameProvided = unacceptedAttributeErr("TenantName")
|
||||
|
||||
// ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead.
|
||||
ErrUsernameWithToken = redundantWithTokenErr("Username")
|
||||
|
||||
// ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead.
|
||||
ErrUserIDWithToken = redundantWithTokenErr("UserID")
|
||||
|
||||
// ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead.
|
||||
ErrDomainIDWithToken = redundantWithTokenErr("DomainID")
|
||||
|
||||
// ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s
|
||||
ErrDomainNameWithToken = redundantWithTokenErr("DomainName")
|
||||
|
||||
// ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once.
|
||||
ErrUsernameOrUserID = errors.New("Exactly one of Username and UserID must be provided for password authentication")
|
||||
|
||||
// ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used.
|
||||
ErrDomainIDWithUserID = redundantWithUserID("DomainID")
|
||||
|
||||
// ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used.
|
||||
ErrDomainNameWithUserID = redundantWithUserID("DomainName")
|
||||
|
||||
// ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it.
|
||||
// It may also indicate that both a DomainID and a DomainName were provided at once.
|
||||
ErrDomainIDOrDomainName = errors.New("You must provide exactly one of DomainID or DomainName to authenticate by Username")
|
||||
|
||||
// ErrMissingPassword indicates that no password was provided and no token is available.
|
||||
ErrMissingPassword = errors.New("You must provide a password to authenticate")
|
||||
|
||||
// ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present.
|
||||
ErrScopeDomainIDOrDomainName = errors.New("You must provide exactly one of DomainID or DomainName in a Scope with ProjectName")
|
||||
|
||||
// ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope.
|
||||
ErrScopeProjectIDOrProjectName = errors.New("You must provide at most one of ProjectID or ProjectName in a Scope")
|
||||
|
||||
// ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope.
|
||||
ErrScopeProjectIDAlone = errors.New("ProjectID must be supplied alone in a Scope")
|
||||
|
||||
// ErrScopeDomainName indicates that a DomainName was provided alone in a Scope.
|
||||
ErrScopeDomainName = errors.New("DomainName must be supplied with a ProjectName or ProjectID in a Scope.")
|
||||
|
||||
// ErrScopeEmpty indicates that no credentials were provided in a Scope.
|
||||
ErrScopeEmpty = errors.New("You must provide either a Project or Domain in a Scope")
|
||||
)
|
281
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests.go
generated
vendored
Normal file
281
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/requests.go
generated
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/rackspace/gophercloud"
|
||||
)
|
||||
|
||||
// Scope allows a created token to be limited to a specific domain or project.
|
||||
type Scope struct {
|
||||
ProjectID string
|
||||
ProjectName string
|
||||
DomainID string
|
||||
DomainName string
|
||||
}
|
||||
|
||||
func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
|
||||
return map[string]string{
|
||||
"X-Subject-Token": subjectToken,
|
||||
}
|
||||
}
|
||||
|
||||
// Create authenticates and either generates a new token, or changes the Scope of an existing token.
|
||||
func Create(c *gophercloud.ServiceClient, options gophercloud.AuthOptions, scope *Scope) CreateResult {
|
||||
type domainReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
type projectReq struct {
|
||||
Domain *domainReq `json:"domain,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type userReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Password string `json:"password"`
|
||||
Domain *domainReq `json:"domain,omitempty"`
|
||||
}
|
||||
|
||||
type passwordReq struct {
|
||||
User userReq `json:"user"`
|
||||
}
|
||||
|
||||
type tokenReq struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type identityReq struct {
|
||||
Methods []string `json:"methods"`
|
||||
Password *passwordReq `json:"password,omitempty"`
|
||||
Token *tokenReq `json:"token,omitempty"`
|
||||
}
|
||||
|
||||
type scopeReq struct {
|
||||
Domain *domainReq `json:"domain,omitempty"`
|
||||
Project *projectReq `json:"project,omitempty"`
|
||||
}
|
||||
|
||||
type authReq struct {
|
||||
Identity identityReq `json:"identity"`
|
||||
Scope *scopeReq `json:"scope,omitempty"`
|
||||
}
|
||||
|
||||
type request struct {
|
||||
Auth authReq `json:"auth"`
|
||||
}
|
||||
|
||||
// Populate the request structure based on the provided arguments. Create and return an error
|
||||
// if insufficient or incompatible information is present.
|
||||
var req request
|
||||
|
||||
// Test first for unrecognized arguments.
|
||||
if options.APIKey != "" {
|
||||
return createErr(ErrAPIKeyProvided)
|
||||
}
|
||||
if options.TenantID != "" {
|
||||
return createErr(ErrTenantIDProvided)
|
||||
}
|
||||
if options.TenantName != "" {
|
||||
return createErr(ErrTenantNameProvided)
|
||||
}
|
||||
|
||||
if options.Password == "" {
|
||||
if c.TokenID != "" {
|
||||
// Because we aren't using password authentication, it's an error to also provide any of the user-based authentication
|
||||
// parameters.
|
||||
if options.Username != "" {
|
||||
return createErr(ErrUsernameWithToken)
|
||||
}
|
||||
if options.UserID != "" {
|
||||
return createErr(ErrUserIDWithToken)
|
||||
}
|
||||
if options.DomainID != "" {
|
||||
return createErr(ErrDomainIDWithToken)
|
||||
}
|
||||
if options.DomainName != "" {
|
||||
return createErr(ErrDomainNameWithToken)
|
||||
}
|
||||
|
||||
// Configure the request for Token authentication.
|
||||
req.Auth.Identity.Methods = []string{"token"}
|
||||
req.Auth.Identity.Token = &tokenReq{
|
||||
ID: c.TokenID,
|
||||
}
|
||||
} else {
|
||||
// If no password or token ID are available, authentication can't continue.
|
||||
return createErr(ErrMissingPassword)
|
||||
}
|
||||
} else {
|
||||
// Password authentication.
|
||||
req.Auth.Identity.Methods = []string{"password"}
|
||||
|
||||
// At least one of Username and UserID must be specified.
|
||||
if options.Username == "" && options.UserID == "" {
|
||||
return createErr(ErrUsernameOrUserID)
|
||||
}
|
||||
|
||||
if options.Username != "" {
|
||||
// If Username is provided, UserID may not be provided.
|
||||
if options.UserID != "" {
|
||||
return createErr(ErrUsernameOrUserID)
|
||||
}
|
||||
|
||||
// Either DomainID or DomainName must also be specified.
|
||||
if options.DomainID == "" && options.DomainName == "" {
|
||||
return createErr(ErrDomainIDOrDomainName)
|
||||
}
|
||||
|
||||
if options.DomainID != "" {
|
||||
if options.DomainName != "" {
|
||||
return createErr(ErrDomainIDOrDomainName)
|
||||
}
|
||||
|
||||
// Configure the request for Username and Password authentication with a DomainID.
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{
|
||||
Name: &options.Username,
|
||||
Password: options.Password,
|
||||
Domain: &domainReq{ID: &options.DomainID},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if options.DomainName != "" {
|
||||
// Configure the request for Username and Password authentication with a DomainName.
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{
|
||||
Name: &options.Username,
|
||||
Password: options.Password,
|
||||
Domain: &domainReq{Name: &options.DomainName},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if options.UserID != "" {
|
||||
// If UserID is specified, neither DomainID nor DomainName may be.
|
||||
if options.DomainID != "" {
|
||||
return createErr(ErrDomainIDWithUserID)
|
||||
}
|
||||
if options.DomainName != "" {
|
||||
return createErr(ErrDomainNameWithUserID)
|
||||
}
|
||||
|
||||
// Configure the request for UserID and Password authentication.
|
||||
req.Auth.Identity.Password = &passwordReq{
|
||||
User: userReq{ID: &options.UserID, Password: options.Password},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a "scope" element if a Scope has been provided.
|
||||
if scope != nil {
|
||||
if scope.ProjectName != "" {
|
||||
// ProjectName provided: either DomainID or DomainName must also be supplied.
|
||||
// ProjectID may not be supplied.
|
||||
if scope.DomainID == "" && scope.DomainName == "" {
|
||||
return createErr(ErrScopeDomainIDOrDomainName)
|
||||
}
|
||||
if scope.ProjectID != "" {
|
||||
return createErr(ErrScopeProjectIDOrProjectName)
|
||||
}
|
||||
|
||||
if scope.DomainID != "" {
|
||||
// ProjectName + DomainID
|
||||
req.Auth.Scope = &scopeReq{
|
||||
Project: &projectReq{
|
||||
Name: &scope.ProjectName,
|
||||
Domain: &domainReq{ID: &scope.DomainID},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if scope.DomainName != "" {
|
||||
// ProjectName + DomainName
|
||||
req.Auth.Scope = &scopeReq{
|
||||
Project: &projectReq{
|
||||
Name: &scope.ProjectName,
|
||||
Domain: &domainReq{Name: &scope.DomainName},
|
||||
},
|
||||
}
|
||||
}
|
||||
} else if scope.ProjectID != "" {
|
||||
// ProjectID provided. ProjectName, DomainID, and DomainName may not be provided.
|
||||
if scope.DomainID != "" {
|
||||
return createErr(ErrScopeProjectIDAlone)
|
||||
}
|
||||
if scope.DomainName != "" {
|
||||
return createErr(ErrScopeProjectIDAlone)
|
||||
}
|
||||
|
||||
// ProjectID
|
||||
req.Auth.Scope = &scopeReq{
|
||||
Project: &projectReq{ID: &scope.ProjectID},
|
||||
}
|
||||
} else if scope.DomainID != "" {
|
||||
// DomainID provided. ProjectID, ProjectName, and DomainName may not be provided.
|
||||
if scope.DomainName != "" {
|
||||
return createErr(ErrScopeDomainIDOrDomainName)
|
||||
}
|
||||
|
||||
// DomainID
|
||||
req.Auth.Scope = &scopeReq{
|
||||
Domain: &domainReq{ID: &scope.DomainID},
|
||||
}
|
||||
} else if scope.DomainName != "" {
|
||||
return createErr(ErrScopeDomainName)
|
||||
} else {
|
||||
return createErr(ErrScopeEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
var result CreateResult
|
||||
var response *http.Response
|
||||
response, result.Err = c.Post(tokenURL(c), req, &result.Body, nil)
|
||||
if result.Err != nil {
|
||||
return result
|
||||
}
|
||||
result.Header = response.Header
|
||||
return result
|
||||
}
|
||||
|
||||
// Get validates and retrieves information about another token.
|
||||
func Get(c *gophercloud.ServiceClient, token string) GetResult {
|
||||
var result GetResult
|
||||
var response *http.Response
|
||||
response, result.Err = c.Get(tokenURL(c), &result.Body, &gophercloud.RequestOpts{
|
||||
MoreHeaders: subjectTokenHeaders(c, token),
|
||||
OkCodes: []int{200, 203},
|
||||
})
|
||||
if result.Err != nil {
|
||||
return result
|
||||
}
|
||||
result.Header = response.Header
|
||||
return result
|
||||
}
|
||||
|
||||
// Validate determines if a specified token is valid or not.
|
||||
func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
|
||||
response, err := c.Request("HEAD", tokenURL(c), gophercloud.RequestOpts{
|
||||
MoreHeaders: subjectTokenHeaders(c, token),
|
||||
OkCodes: []int{204, 404},
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return response.StatusCode == 204, nil
|
||||
}
|
||||
|
||||
// Revoke immediately makes specified token invalid.
|
||||
func Revoke(c *gophercloud.ServiceClient, token string) RevokeResult {
|
||||
var res RevokeResult
|
||||
_, res.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{
|
||||
MoreHeaders: subjectTokenHeaders(c, token),
|
||||
})
|
||||
return res
|
||||
}
|
139
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/results.go
generated
vendored
Normal file
139
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/results.go
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/rackspace/gophercloud"
|
||||
)
|
||||
|
||||
// Endpoint represents a single API endpoint offered by a service.
|
||||
// It matches either a public, internal or admin URL.
|
||||
// If supported, it contains a region specifier, again if provided.
|
||||
// The significance of the Region field will depend upon your provider.
|
||||
type Endpoint struct {
|
||||
ID string `mapstructure:"id"`
|
||||
Region string `mapstructure:"region"`
|
||||
Interface string `mapstructure:"interface"`
|
||||
URL string `mapstructure:"url"`
|
||||
}
|
||||
|
||||
// CatalogEntry provides a type-safe interface to an Identity API V3 service catalog listing.
|
||||
// Each class of service, such as cloud DNS or block storage services, could have multiple
|
||||
// CatalogEntry representing it (one by interface type, e.g public, admin or internal).
|
||||
//
|
||||
// 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 {
|
||||
|
||||
// Service ID
|
||||
ID string `mapstructure:"id"`
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// commonResult is the deferred result of a Create or a Get call.
|
||||
type commonResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a shortcut for ExtractToken.
|
||||
// This function is deprecated and still present for backward compatibility.
|
||||
func (r commonResult) Extract() (*Token, error) {
|
||||
return r.ExtractToken()
|
||||
}
|
||||
|
||||
// ExtractToken interprets a commonResult as a Token.
|
||||
func (r commonResult) ExtractToken() (*Token, error) {
|
||||
if r.Err != nil {
|
||||
return nil, r.Err
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Token struct {
|
||||
ExpiresAt string `mapstructure:"expires_at"`
|
||||
} `mapstructure:"token"`
|
||||
}
|
||||
|
||||
var token Token
|
||||
|
||||
// Parse the token itself from the stored headers.
|
||||
token.ID = r.Header.Get("X-Subject-Token")
|
||||
|
||||
err := mapstructure.Decode(r.Body, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Attempt to parse the timestamp.
|
||||
token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, response.Token.ExpiresAt)
|
||||
|
||||
return &token, err
|
||||
}
|
||||
|
||||
// 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 {
|
||||
Token struct {
|
||||
Entries []CatalogEntry `mapstructure:"catalog"`
|
||||
} `mapstructure:"token"`
|
||||
}
|
||||
|
||||
err := mapstructure.Decode(result.Body, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ServiceCatalog{Entries: response.Token.Entries}, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// createErr quickly creates a CreateResult that reports an error.
|
||||
func createErr(err error) CreateResult {
|
||||
return CreateResult{
|
||||
commonResult: commonResult{Result: gophercloud.Result{Err: err}},
|
||||
}
|
||||
}
|
||||
|
||||
// GetResult is the deferred response from a Get call.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// RevokeResult is the deferred response from a Revoke call.
|
||||
type RevokeResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// Token is a string that grants a user access to a controlled set of services in an OpenStack provider.
|
||||
// Each Token is valid for a set length of time.
|
||||
type Token struct {
|
||||
// ID is the issued token.
|
||||
ID string
|
||||
|
||||
// ExpiresAt is the timestamp at which this token will no longer be accepted.
|
||||
ExpiresAt time.Time
|
||||
}
|
7
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls.go
generated
vendored
Normal file
7
vendor/github.com/rackspace/gophercloud/openstack/identity/v3/tokens/urls.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package tokens
|
||||
|
||||
import "github.com/rackspace/gophercloud"
|
||||
|
||||
func tokenURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("auth", "tokens")
|
||||
}
|
Reference in New Issue
Block a user