Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BlockStorage: apiversions #458

Merged
merged 5 commits into from
Jan 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions acceptance/openstack/blockstorage/apiversions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// +build acceptance blockstorage

package blockstorage

import (
"testing"

"github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/acceptance/tools"
"github.com/gophercloud/gophercloud/openstack/blockstorage/apiversions"
)

func TestAPIVersionsList(t *testing.T) {
client, err := clients.NewBlockStorageV2Client()
if err != nil {
t.Fatalf("Unable to create a blockstorage client: %v", err)
}

allPages, err := apiversions.List(client).AllPages()
if err != nil {
t.Fatalf("Unable to retrieve API versions: %v", err)
}

allVersions, err := apiversions.ExtractAPIVersions(allPages)
if err != nil {
t.Fatalf("Unable to extract API versions: %v", err)
}

for _, v := range allVersions {
tools.PrintResource(t, v)
}
}

func TestAPIVersionsGet(t *testing.T) {
client, err := clients.NewBlockStorageV2Client()
if err != nil {
t.Fatalf("Unable to create a blockstorage client: %v", err)
}

allPages, err := apiversions.List(client).AllPages()
if err != nil {
t.Fatalf("Unable to retrieve API versions: %v", err)
}

v, err := apiversions.ExtractAPIVersion(allPages, "v3.0")
if err != nil {
t.Fatalf("Unable to extract API version: %v", err)
}

tools.PrintResource(t, v)
}
31 changes: 31 additions & 0 deletions openstack/blockstorage/apiversions/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Package apiversions provides information and interaction with the different
API versions for the OpenStack Block Storage service, code-named Cinder.

Example of Retrieving all API Versions

allPages, err := apiversions.List(client).AllPages()
if err != nil {
panic("Unable to get API versions: %s", err)
}

allVersions, err := apiversions.ExtractAPIVersions(allPages)
if err != nil {
panic("Unable to extract API versions: %s", err)
}

for _, version := range versions {
fmt.Printf("%+v\n", version)
}


Example of Retrieving an API Version

version, err := apiversions.Get(client, "v3").Extract()
if err != nil {
panic("Unable to get API version: %s", err)
}

fmt.Printf("%+v\n", version)
*/
package apiversions
23 changes: 23 additions & 0 deletions openstack/blockstorage/apiversions/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package apiversions

import (
"fmt"
)

// ErrVersionNotFound is the error when the requested API version
// could not be found.
type ErrVersionNotFound struct{}

func (e ErrVersionNotFound) Error() string {
return fmt.Sprintf("Unable to find requested API version")
}

// ErrMultipleVersionsFound is the error when a request for an API
// version returns multiple results.
type ErrMultipleVersionsFound struct {
Count int
}

func (e ErrMultipleVersionsFound) Error() string {
return fmt.Sprintf("Found %d API versions", e.Count)
}
13 changes: 13 additions & 0 deletions openstack/blockstorage/apiversions/requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package apiversions

import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)

// List lists all the Cinder API versions available to end-users.
func List(c *gophercloud.ServiceClient) pagination.Pager {
return pagination.NewPager(c, listURL(c), func(r pagination.PageResult) pagination.Page {
return APIVersionPage{pagination.SinglePageBase(r)}
})
}
64 changes: 64 additions & 0 deletions openstack/blockstorage/apiversions/results.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package apiversions

import (
"time"

"github.com/gophercloud/gophercloud/pagination"
)

// APIVersion represents an API version for Cinder.
type APIVersion struct {
// ID is the unique identifier of the API version.
ID string `json:"id"`

// MinVersion is the minimum microversion supported.
MinVersion string `json:"min_version"`

// Status represents the status of the API version.
Status string `json:"status"`

// Updated is the date the API version was updated.
Updated time.Time `json:"updated"`

// Version is the current version and microversion.
Version string `json:"version"`
}

// APIVersionPage is the page returned by a pager when traversing over a
// collection of API versions.
type APIVersionPage struct {
pagination.SinglePageBase
}

// IsEmpty checks whether an APIVersionPage struct is empty.
func (r APIVersionPage) IsEmpty() (bool, error) {
is, err := ExtractAPIVersions(r)
return len(is) == 0, err
}

// ExtractAPIVersions takes a collection page, extracts all of the elements,
// and returns them a slice of APIVersion structs. It is effectively a cast.
func ExtractAPIVersions(r pagination.Page) ([]APIVersion, error) {
var s struct {
Versions []APIVersion `json:"versions"`
}
err := (r.(APIVersionPage)).ExtractInto(&s)
return s.Versions, err
}

// ExtractAPIVersion takes a List result and extracts a single requested
// version, which is returned as an APIVersion
func ExtractAPIVersion(r pagination.Page, v string) (*APIVersion, error) {
allVersions, err := ExtractAPIVersions(r)
if err != nil {
return nil, err
}

for _, version := range allVersions {
if version.ID == v {
return &version, nil
}
}

return nil, ErrVersionNotFound{}
}
2 changes: 2 additions & 0 deletions openstack/blockstorage/apiversions/testing/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// apiversions_v1
package testing
141 changes: 141 additions & 0 deletions openstack/blockstorage/apiversions/testing/fixtures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package testing

import (
"fmt"
"net/http"
"testing"

th "github.com/gophercloud/gophercloud/testhelper"
"github.com/gophercloud/gophercloud/testhelper/client"
)

const APIListResponse = `
{
"versions": [
{
"id": "v1.0",
"links": [
{
"href": "http://docs.openstack.org/",
"rel": "describedby",
"type": "text/html"
},
{
"href": "http://localhost:8776/v1/",
"rel": "self"
}
],
"media-types": [
{
"base": "application/json",
"type": "application/vnd.openstack.volume+json;version=1"
}
],
"min_version": "",
"status": "DEPRECATED",
"updated": "2016-05-02T20:25:19Z",
"version": ""
},
{
"id": "v2.0",
"links": [
{
"href": "http://docs.openstack.org/",
"rel": "describedby",
"type": "text/html"
},
{
"href": "http://localhost:8776/v2/",
"rel": "self"
}
],
"media-types": [
{
"base": "application/json",
"type": "application/vnd.openstack.volume+json;version=1"
}
],
"min_version": "",
"status": "SUPPORTED",
"updated": "2014-06-28T12:20:21Z",
"version": ""
},
{
"id": "v3.0",
"links": [
{
"href": "http://docs.openstack.org/",
"rel": "describedby",
"type": "text/html"
},
{
"href": "http://localhost:8776/v3/",
"rel": "self"
}
],
"media-types": [
{
"base": "application/json",
"type": "application/vnd.openstack.volume+json;version=1"
}
],
"min_version": "3.0",
"status": "CURRENT",
"updated": "2016-02-08T12:20:21Z",
"version": "3.27"
}
]
}
`

const APIListOldResponse = `
{
"versions": [
{
"status": "CURRENT",
"updated": "2012-01-04T11:33:21Z",
"id": "v1.0",
"links": [
{
"href": "http://23.253.228.211:8776/v1/",
"rel": "self"
}
]
},
{
"status": "CURRENT",
"updated": "2012-11-21T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "http://23.253.228.211:8776/v2/",
"rel": "self"
}
]
}
]
}`

func MockListResponse(t *testing.T) {
th.Mux.HandleFunc("/", 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")
w.WriteHeader(http.StatusOK)

fmt.Fprintf(w, APIListResponse)
})
}

func MockListOldResponse(t *testing.T) {
th.Mux.HandleFunc("/", 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")
w.WriteHeader(http.StatusOK)

fmt.Fprintf(w, APIListOldResponse)
})
}
Loading