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:
60
vendor/github.com/rackspace/gophercloud/pagination/http.go
generated
vendored
Normal file
60
vendor/github.com/rackspace/gophercloud/pagination/http.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
package pagination
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/rackspace/gophercloud"
|
||||
)
|
||||
|
||||
// PageResult stores the HTTP response that returned the current page of results.
|
||||
type PageResult struct {
|
||||
gophercloud.Result
|
||||
url.URL
|
||||
}
|
||||
|
||||
// PageResultFrom parses an HTTP response as JSON and returns a PageResult containing the
|
||||
// results, interpreting it as JSON if the content type indicates.
|
||||
func PageResultFrom(resp *http.Response) (PageResult, error) {
|
||||
var parsedBody interface{}
|
||||
|
||||
defer resp.Body.Close()
|
||||
rawBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return PageResult{}, err
|
||||
}
|
||||
|
||||
if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") {
|
||||
err = json.Unmarshal(rawBody, &parsedBody)
|
||||
if err != nil {
|
||||
return PageResult{}, err
|
||||
}
|
||||
} else {
|
||||
parsedBody = rawBody
|
||||
}
|
||||
|
||||
return PageResultFromParsed(resp, parsedBody), err
|
||||
}
|
||||
|
||||
// PageResultFromParsed constructs a PageResult from an HTTP response that has already had its
|
||||
// body parsed as JSON (and closed).
|
||||
func PageResultFromParsed(resp *http.Response, body interface{}) PageResult {
|
||||
return PageResult{
|
||||
Result: gophercloud.Result{
|
||||
Body: body,
|
||||
Header: resp.Header,
|
||||
},
|
||||
URL: *resp.Request.URL,
|
||||
}
|
||||
}
|
||||
|
||||
// Request performs an HTTP request and extracts the http.Response from the result.
|
||||
func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (*http.Response, error) {
|
||||
return client.Request("GET", url, gophercloud.RequestOpts{
|
||||
MoreHeaders: headers,
|
||||
OkCodes: []int{200, 204},
|
||||
})
|
||||
}
|
67
vendor/github.com/rackspace/gophercloud/pagination/linked.go
generated
vendored
Normal file
67
vendor/github.com/rackspace/gophercloud/pagination/linked.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package pagination
|
||||
|
||||
import "fmt"
|
||||
|
||||
// LinkedPageBase may be embedded to implement a page that provides navigational "Next" and "Previous" links within its result.
|
||||
type LinkedPageBase struct {
|
||||
PageResult
|
||||
|
||||
// LinkPath lists the keys that should be traversed within a response to arrive at the "next" pointer.
|
||||
// If any link along the path is missing, an empty URL will be returned.
|
||||
// If any link results in an unexpected value type, an error will be returned.
|
||||
// When left as "nil", []string{"links", "next"} will be used as a default.
|
||||
LinkPath []string
|
||||
}
|
||||
|
||||
// NextPageURL extracts the pagination structure from a JSON response and returns the "next" link, if one is present.
|
||||
// It assumes that the links are available in a "links" element of the top-level response object.
|
||||
// If this is not the case, override NextPageURL on your result type.
|
||||
func (current LinkedPageBase) NextPageURL() (string, error) {
|
||||
var path []string
|
||||
var key string
|
||||
|
||||
if current.LinkPath == nil {
|
||||
path = []string{"links", "next"}
|
||||
} else {
|
||||
path = current.LinkPath
|
||||
}
|
||||
|
||||
submap, ok := current.Body.(map[string]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("Expected an object, but was %#v", current.Body)
|
||||
}
|
||||
|
||||
for {
|
||||
key, path = path[0], path[1:len(path)]
|
||||
|
||||
value, ok := submap[key]
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if len(path) > 0 {
|
||||
submap, ok = value.(map[string]interface{})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("Expected an object, but was %#v", value)
|
||||
}
|
||||
} else {
|
||||
if value == nil {
|
||||
// Actual null element.
|
||||
return "", nil
|
||||
}
|
||||
|
||||
url, ok := value.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("Expected a string, but was %#v", value)
|
||||
}
|
||||
|
||||
return url, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetBody returns the linked page's body. This method is needed to satisfy the
|
||||
// Page interface.
|
||||
func (current LinkedPageBase) GetBody() interface{} {
|
||||
return current.Body
|
||||
}
|
40
vendor/github.com/rackspace/gophercloud/pagination/marker.go
generated
vendored
Normal file
40
vendor/github.com/rackspace/gophercloud/pagination/marker.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package pagination
|
||||
|
||||
// MarkerPage is a stricter Page interface that describes additional functionality required for use with NewMarkerPager.
|
||||
// For convenience, embed the MarkedPageBase struct.
|
||||
type MarkerPage interface {
|
||||
Page
|
||||
|
||||
// LastMarker returns the last "marker" value on this page.
|
||||
LastMarker() (string, error)
|
||||
}
|
||||
|
||||
// MarkerPageBase is a page in a collection that's paginated by "limit" and "marker" query parameters.
|
||||
type MarkerPageBase struct {
|
||||
PageResult
|
||||
|
||||
// Owner is a reference to the embedding struct.
|
||||
Owner MarkerPage
|
||||
}
|
||||
|
||||
// NextPageURL generates the URL for the page of results after this one.
|
||||
func (current MarkerPageBase) NextPageURL() (string, error) {
|
||||
currentURL := current.URL
|
||||
|
||||
mark, err := current.Owner.LastMarker()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
q := currentURL.Query()
|
||||
q.Set("marker", mark)
|
||||
currentURL.RawQuery = q.Encode()
|
||||
|
||||
return currentURL.String(), nil
|
||||
}
|
||||
|
||||
// GetBody returns the linked page's body. This method is needed to satisfy the
|
||||
// Page interface.
|
||||
func (current MarkerPageBase) GetBody() interface{} {
|
||||
return current.Body
|
||||
}
|
20
vendor/github.com/rackspace/gophercloud/pagination/null.go
generated
vendored
Normal file
20
vendor/github.com/rackspace/gophercloud/pagination/null.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
package pagination
|
||||
|
||||
// nullPage is an always-empty page that trivially satisfies all Page interfacts.
|
||||
// It's useful to be returned along with an error.
|
||||
type nullPage struct{}
|
||||
|
||||
// NextPageURL always returns "" to indicate that there are no more pages to return.
|
||||
func (p nullPage) NextPageURL() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// IsEmpty always returns true to prevent iteration over nullPages.
|
||||
func (p nullPage) IsEmpty() (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// LastMark always returns "" because the nullPage contains no items to have a mark.
|
||||
func (p nullPage) LastMark() (string, error) {
|
||||
return "", nil
|
||||
}
|
226
vendor/github.com/rackspace/gophercloud/pagination/pager.go
generated
vendored
Normal file
226
vendor/github.com/rackspace/gophercloud/pagination/pager.go
generated
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
package pagination
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/rackspace/gophercloud"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist.
|
||||
ErrPageNotAvailable = errors.New("The requested page does not exist.")
|
||||
)
|
||||
|
||||
// Page must be satisfied by the result type of any resource collection.
|
||||
// It allows clients to interact with the resource uniformly, regardless of whether or not or how it's paginated.
|
||||
// Generally, rather than implementing this interface directly, implementors should embed one of the concrete PageBase structs,
|
||||
// instead.
|
||||
// Depending on the pagination strategy of a particular resource, there may be an additional subinterface that the result type
|
||||
// will need to implement.
|
||||
type Page interface {
|
||||
|
||||
// NextPageURL generates the URL for the page of data that follows this collection.
|
||||
// Return "" if no such page exists.
|
||||
NextPageURL() (string, error)
|
||||
|
||||
// IsEmpty returns true if this Page has no items in it.
|
||||
IsEmpty() (bool, error)
|
||||
|
||||
// GetBody returns the Page Body. This is used in the `AllPages` method.
|
||||
GetBody() interface{}
|
||||
}
|
||||
|
||||
// Pager knows how to advance through a specific resource collection, one page at a time.
|
||||
type Pager struct {
|
||||
client *gophercloud.ServiceClient
|
||||
|
||||
initialURL string
|
||||
|
||||
createPage func(r PageResult) Page
|
||||
|
||||
Err error
|
||||
|
||||
// Headers supplies additional HTTP headers to populate on each paged request.
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// NewPager constructs a manually-configured pager.
|
||||
// Supply the URL for the first page, a function that requests a specific page given a URL, and a function that counts a page.
|
||||
func NewPager(client *gophercloud.ServiceClient, initialURL string, createPage func(r PageResult) Page) Pager {
|
||||
return Pager{
|
||||
client: client,
|
||||
initialURL: initialURL,
|
||||
createPage: createPage,
|
||||
}
|
||||
}
|
||||
|
||||
// WithPageCreator returns a new Pager that substitutes a different page creation function. This is
|
||||
// useful for overriding List functions in delegation.
|
||||
func (p Pager) WithPageCreator(createPage func(r PageResult) Page) Pager {
|
||||
return Pager{
|
||||
client: p.client,
|
||||
initialURL: p.initialURL,
|
||||
createPage: createPage,
|
||||
}
|
||||
}
|
||||
|
||||
func (p Pager) fetchNextPage(url string) (Page, error) {
|
||||
resp, err := Request(p.client, p.Headers, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
remembered, err := PageResultFrom(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p.createPage(remembered), nil
|
||||
}
|
||||
|
||||
// EachPage iterates over each page returned by a Pager, yielding one at a time to a handler function.
|
||||
// Return "false" from the handler to prematurely stop iterating.
|
||||
func (p Pager) EachPage(handler func(Page) (bool, error)) error {
|
||||
if p.Err != nil {
|
||||
return p.Err
|
||||
}
|
||||
currentURL := p.initialURL
|
||||
for {
|
||||
currentPage, err := p.fetchNextPage(currentURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
empty, err := currentPage.IsEmpty()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if empty {
|
||||
return nil
|
||||
}
|
||||
|
||||
ok, err := handler(currentPage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
currentURL, err = currentPage.NextPageURL()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if currentURL == "" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AllPages returns all the pages from a `List` operation in a single page,
|
||||
// allowing the user to retrieve all the pages at once.
|
||||
func (p Pager) AllPages() (Page, error) {
|
||||
// pagesSlice holds all the pages until they get converted into as Page Body.
|
||||
var pagesSlice []interface{}
|
||||
// body will contain the final concatenated Page body.
|
||||
var body reflect.Value
|
||||
|
||||
// Grab a test page to ascertain the page body type.
|
||||
testPage, err := p.fetchNextPage(p.initialURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Store the page type so we can use reflection to create a new mega-page of
|
||||
// that type.
|
||||
pageType := reflect.TypeOf(testPage)
|
||||
|
||||
// Switch on the page body type. Recognized types are `map[string]interface{}`,
|
||||
// `[]byte`, and `[]interface{}`.
|
||||
switch testPage.GetBody().(type) {
|
||||
case map[string]interface{}:
|
||||
// key is the map key for the page body if the body type is `map[string]interface{}`.
|
||||
var key string
|
||||
// Iterate over the pages to concatenate the bodies.
|
||||
err := p.EachPage(func(page Page) (bool, error) {
|
||||
b := page.GetBody().(map[string]interface{})
|
||||
for k := range b {
|
||||
// If it's a linked page, we don't want the `links`, we want the other one.
|
||||
if !strings.HasSuffix(k, "links") {
|
||||
key = k
|
||||
}
|
||||
}
|
||||
pagesSlice = append(pagesSlice, b[key].([]interface{})...)
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Set body to value of type `map[string]interface{}`
|
||||
body = reflect.MakeMap(reflect.MapOf(reflect.TypeOf(key), reflect.TypeOf(pagesSlice)))
|
||||
body.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(pagesSlice))
|
||||
case []byte:
|
||||
// Iterate over the pages to concatenate the bodies.
|
||||
err := p.EachPage(func(page Page) (bool, error) {
|
||||
b := page.GetBody().([]byte)
|
||||
pagesSlice = append(pagesSlice, b)
|
||||
// seperate pages with a comma
|
||||
pagesSlice = append(pagesSlice, []byte{10})
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(pagesSlice) > 0 {
|
||||
// Remove the trailing comma.
|
||||
pagesSlice = pagesSlice[:len(pagesSlice)-1]
|
||||
}
|
||||
var b []byte
|
||||
// Combine the slice of slices in to a single slice.
|
||||
for _, slice := range pagesSlice {
|
||||
b = append(b, slice.([]byte)...)
|
||||
}
|
||||
// Set body to value of type `bytes`.
|
||||
body = reflect.New(reflect.TypeOf(b)).Elem()
|
||||
body.SetBytes(b)
|
||||
case []interface{}:
|
||||
// Iterate over the pages to concatenate the bodies.
|
||||
err := p.EachPage(func(page Page) (bool, error) {
|
||||
b := page.GetBody().([]interface{})
|
||||
pagesSlice = append(pagesSlice, b...)
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Set body to value of type `[]interface{}`
|
||||
body = reflect.MakeSlice(reflect.TypeOf(pagesSlice), len(pagesSlice), len(pagesSlice))
|
||||
for i, s := range pagesSlice {
|
||||
body.Index(i).Set(reflect.ValueOf(s))
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("Page body has unrecognized type.")
|
||||
}
|
||||
|
||||
// Each `Extract*` function is expecting a specific type of page coming back,
|
||||
// otherwise the type assertion in those functions will fail. pageType is needed
|
||||
// to create a type in this method that has the same type that the `Extract*`
|
||||
// function is expecting and set the Body of that object to the concatenated
|
||||
// pages.
|
||||
page := reflect.New(pageType)
|
||||
// Set the page body to be the concatenated pages.
|
||||
page.Elem().FieldByName("Body").Set(body)
|
||||
// Set any additional headers that were pass along. The `objectstorage` pacakge,
|
||||
// for example, passes a Content-Type header.
|
||||
h := make(http.Header)
|
||||
for k, v := range p.Headers {
|
||||
h.Add(k, v)
|
||||
}
|
||||
page.Elem().FieldByName("Header").Set(reflect.ValueOf(h))
|
||||
// Type assert the page to a Page interface so that the type assertion in the
|
||||
// `Extract*` methods will work.
|
||||
return page.Elem().Interface().(Page), err
|
||||
}
|
4
vendor/github.com/rackspace/gophercloud/pagination/pkg.go
generated
vendored
Normal file
4
vendor/github.com/rackspace/gophercloud/pagination/pkg.go
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
Package pagination contains utilities and convenience structs that implement common pagination idioms within OpenStack APIs.
|
||||
*/
|
||||
package pagination
|
15
vendor/github.com/rackspace/gophercloud/pagination/single.go
generated
vendored
Normal file
15
vendor/github.com/rackspace/gophercloud/pagination/single.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package pagination
|
||||
|
||||
// SinglePageBase may be embedded in a Page that contains all of the results from an operation at once.
|
||||
type SinglePageBase PageResult
|
||||
|
||||
// NextPageURL always returns "" to indicate that there are no more pages to return.
|
||||
func (current SinglePageBase) NextPageURL() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// GetBody returns the single page's body. This method is needed to satisfy the
|
||||
// Page interface.
|
||||
func (current SinglePageBase) GetBody() interface{} {
|
||||
return current.Body
|
||||
}
|
Reference in New Issue
Block a user