Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.
Closed
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
3 changes: 3 additions & 0 deletions openstack/blockstorage/v2/apiversions/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package apiversions provides information and interaction with the different
// API versions for the OpenStack Block Storage service, code-named Cinder.
package apiversions
21 changes: 21 additions & 0 deletions openstack/blockstorage/v2/apiversions/requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package apiversions

import (
"github.com/rackspace/gophercloud"
"github.com/rackspace/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)}
})
}

// Get will retrieve the volume type with the provided ID. To extract the volume
// type from the result, call the Extract method on the GetResult.
func Get(client *gophercloud.ServiceClient, v string) GetResult {
var res GetResult
_, res.Err = client.Get(getURL(client, v), &res.Body, nil)
return res
}
145 changes: 145 additions & 0 deletions openstack/blockstorage/v2/apiversions/requests_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package apiversions

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

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

func TestListVersions(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

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, `{
"versions": [
{
"status": "CURRENT",
"updated": "2012-01-04T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "http://23.253.228.211:8776/v2/",
"rel": "self"
}
]
},
{
"status": "CURRENT",
"updated": "2012-11-21T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "http://23.253.228.211:8776/v2/",
"rel": "self"
}
]
}
]
}`)
})

count := 0

List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
count++
actual, err := ExtractAPIVersions(page)
if err != nil {
t.Errorf("Failed to extract API versions: %v", err)
return false, err
}

expected := []APIVersion{
{
ID: "v2.0",
Status: "CURRENT",
Updated: "2012-01-04T11:33:21Z",
},
{
ID: "v2.0",
Status: "CURRENT",
Updated: "2012-11-21T11:33:21Z",
},
}

th.AssertDeepEquals(t, expected, actual)

return true, nil
})

if count != 1 {
t.Errorf("Expected 1 page, got %d", count)
}
}

func TestAPIInfo(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

th.Mux.HandleFunc("/v2/", 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, `{
"version": {
"status": "CURRENT",
"updated": "2012-01-04T11:33:21Z",
"media-types": [
{
"base": "application/xml",
"type": "application/vnd.openstack.volume+xml;version=1"
},
{
"base": "application/json",
"type": "application/vnd.openstack.volume+json;version=1"
}
],
"id": "v2.0",
"links": [
{
"href": "http://23.253.228.211:8776/v2/",
"rel": "self"
},
{
"href": "http://jorgew.github.com/block-storage-api/content/os-block-storage-2.0.pdf",
"type": "application/pdf",
"rel": "describedby"
},
{
"href": "http://docs.rackspacecloud.com/servers/api/v2.1/application.wadl",
"type": "application/vnd.sun.wadl+xml",
"rel": "describedby"
}
]
}
}`)
})

actual, err := Get(client.ServiceClient(), "v2").Extract()
if err != nil {
t.Errorf("Failed to extract version: %v", err)
}

expected := APIVersion{
ID: "v2.0",
Status: "CURRENT",
Updated: "2012-01-04T11:33:21Z",
}

th.AssertEquals(t, actual.ID, expected.ID)
th.AssertEquals(t, actual.Status, expected.Status)
th.AssertEquals(t, actual.Updated, expected.Updated)
}
58 changes: 58 additions & 0 deletions openstack/blockstorage/v2/apiversions/results.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package apiversions

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

"github.com/mitchellh/mapstructure"
)

// APIVersion represents an API version for Cinder.
type APIVersion struct {
ID string `json:"id" mapstructure:"id"` // unique identifier
Status string `json:"status" mapstructure:"status"` // current status
Updated string `json:"updated" mapstructure:"updated"` // date last updated
}

// 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)
if err != nil {
return true, err
}
return len(is) == 0, nil
}

// 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(page pagination.Page) ([]APIVersion, error) {
var resp struct {
Versions []APIVersion `mapstructure:"versions"`
}

err := mapstructure.Decode(page.(APIVersionPage).Body, &resp)

return resp.Versions, err
}

// GetResult represents the result of a get operation.
type GetResult struct {
gophercloud.Result
}

// Extract is a function that accepts a result and extracts an API version resource.
func (r GetResult) Extract() (*APIVersion, error) {
var resp struct {
Version *APIVersion `mapstructure:"version"`
}

err := mapstructure.Decode(r.Body, &resp)

return resp.Version, err
}
15 changes: 15 additions & 0 deletions openstack/blockstorage/v2/apiversions/urls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package apiversions

import (
"strings"

"github.com/rackspace/gophercloud"
)

func getURL(c *gophercloud.ServiceClient, version string) string {
return c.ServiceURL(strings.TrimRight(version, "/") + "/")
}

func listURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL("")
}
26 changes: 26 additions & 0 deletions openstack/blockstorage/v2/apiversions/urls_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package apiversions

import (
"testing"

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

const endpoint = "http://localhost:57909/"

func endpointClient() *gophercloud.ServiceClient {
return &gophercloud.ServiceClient{Endpoint: endpoint}
}

func TestGetURL(t *testing.T) {
actual := getURL(endpointClient(), "v2")
expected := endpoint + "v2/"
th.AssertEquals(t, expected, actual)
}

func TestListURL(t *testing.T) {
actual := listURL(endpointClient())
expected := endpoint
th.AssertEquals(t, expected, actual)
}
5 changes: 5 additions & 0 deletions openstack/blockstorage/v2/snapshots/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Package snapshots provides information and interaction with snapshots in the
// OpenStack Block Storage service. A snapshot is a point in time copy of the
// data contained in an external storage volume, and can be controlled
// programmatically.
package snapshots
114 changes: 114 additions & 0 deletions openstack/blockstorage/v2/snapshots/fixtures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package snapshots

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

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

func MockListResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots", 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, `
{
"snapshots": [
{
"id": "289da7f8-6440-407c-9fb4-7db01ec49164",
"display_name": "snapshot-001"
},
{
"id": "96c3bda7-c82a-4f50-be73-ca7621794835",
"display_name": "snapshot-002"
}
]
}
`)
})
}

func MockGetResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", 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, `
{
"snapshot": {
"display_name": "snapshot-001",
"id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
}
}
`)
})
}

func MockCreateResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "POST")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "Content-Type", "application/json")
th.TestHeader(t, r, "Accept", "application/json")
th.TestJSONRequest(t, r, `
{
"snapshot": {
"volume_id": "1234",
"display_name": "snapshot-001"
}
}
`)

w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)

fmt.Fprintf(w, `
{
"snapshot": {
"volume_id": "1234",
"display_name": "snapshot-001",
"id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
}
}
`)
})
}

func MockUpdateMetadataResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "PUT")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "Content-Type", "application/json")
th.TestJSONRequest(t, r, `
{
"metadata": {
"key": "v2"
}
}
`)

fmt.Fprintf(w, `
{
"metadata": {
"key": "v2"
}
}
`)
})
}

func MockDeleteResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", 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)
})
}
Loading