Skip to content

Commit 7d47410

Browse files
committed
Flavor Extra Specs: List / Get
1 parent caa74f7 commit 7d47410

7 files changed

Lines changed: 174 additions & 0 deletions

File tree

acceptance/openstack/compute/v2/flavors_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,23 @@ func TestFlavorAccessesList(t *testing.T) {
114114
tools.PrintResource(t, access)
115115
}
116116
}
117+
118+
func TestFlavorExtraSpecs(t *testing.T) {
119+
client, err := clients.NewComputeV2Client()
120+
if err != nil {
121+
t.Fatalf("Unable to create a compute client: %v", err)
122+
}
123+
124+
flavor, err := CreatePrivateFlavor(t, client)
125+
if err != nil {
126+
t.Fatalf("Unable to create flavor: %v", err)
127+
}
128+
defer DeleteFlavor(t, client, flavor)
129+
130+
allExtraSpecs, err := flavors.ListExtraSpecs(client, flavor.ID).Extract()
131+
if err != nil {
132+
t.Fatalf("Unable to get flavor extra_specs: %v", err)
133+
}
134+
135+
tools.PrintResource(t, allExtraSpecs)
136+
}

openstack/compute/v2/flavors/doc.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,15 @@ Example to List Flavor Access
5959
for _, access := range allAccesses {
6060
fmt.Printf("%+v", access)
6161
}
62+
63+
Example to Get Extra Specs for a Flavor
64+
flavorID := "e91758d6-a54a-4778-ad72-0c73a1cb695b"
65+
66+
extraSpecs, err := flavors.ListExtraSpecs(computeClient, flavorID).Extract()
67+
if err != nil {
68+
panic(err)
69+
}
70+
71+
fmt.Printf("%+v", extraSpecs)
6272
*/
6373
package flavors

openstack/compute/v2/flavors/requests.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,14 @@ func IDFromName(client *gophercloud.ServiceClient, name string) (string, error)
200200
return "", err
201201
}
202202
}
203+
204+
// ExtraSpecs requests all the extra-specs for the given flavor ID.
205+
func ListExtraSpecs(client *gophercloud.ServiceClient, flavorID string) (r ListExtraSpecsResult) {
206+
_, r.Err = client.Get(extraSpecsListURL(client, flavorID), &r.Body, nil)
207+
return
208+
}
209+
210+
func GetExtraSpec(client *gophercloud.ServiceClient, flavorID string, key string) (r GetExtraSpecsResult) {
211+
_, r.Err = client.Get(extraSpecsGetURL(client, flavorID, key), &r.Body, nil)
212+
return
213+
}

openstack/compute/v2/flavors/results.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,44 @@ type FlavorAccess struct {
162162
// TenantID is the unique ID of the tenant.
163163
TenantID string `json:"tenant_id"`
164164
}
165+
166+
// Extract interprets any extraSpecsResult as ExtraSpecs, if possible.
167+
func (r extraSpecsResult) Extract() (map[string]string, error) {
168+
var s struct {
169+
ExtraSpecs map[string]string `json:"extra_specs"`
170+
}
171+
err := r.ExtractInto(&s)
172+
return s.ExtraSpecs, err
173+
}
174+
175+
// extraSpecsResult contains the result of a call for (potentially) multiple
176+
// key-value pairs. Call its Extract method to interpret it as a
177+
// map[string]interface.
178+
type extraSpecsResult struct {
179+
gophercloud.Result
180+
}
181+
182+
// ListExtraSpecsResult contains the result of a Get operation. Call its Extract
183+
// method to interpret it as a map[string]interface.
184+
type ListExtraSpecsResult struct {
185+
extraSpecsResult
186+
}
187+
188+
// extraSpecResult contains the result of a call for individual a single
189+
// key-value pair.
190+
type extraSpecResult struct {
191+
gophercloud.Result
192+
}
193+
194+
// GetExtraSpecsResult contains the result of a Get operation. Call its Extract
195+
// method to interpret it as a map[string]interface.
196+
type GetExtraSpecsResult struct {
197+
extraSpecResult
198+
}
199+
200+
// Extract interprets any extraSpecResult as an ExtraSpec, if possible.
201+
func (r extraSpecResult) Extract() (map[string]string, error) {
202+
var s map[string]string
203+
err := r.ExtractInto(&s)
204+
return s, err
205+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package testing
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"testing"
7+
8+
th "github.com/gophercloud/gophercloud/testhelper"
9+
fake "github.com/gophercloud/gophercloud/testhelper/client"
10+
)
11+
12+
// ExtraSpecsGetBody provides a GET result of the extra_specs for a flavor
13+
const ExtraSpecsGetBody = `
14+
{
15+
"extra_specs" : {
16+
"hw:cpu_policy": "CPU-POLICY",
17+
"hw:cpu_thread_policy": "CPU-THREAD-POLICY"
18+
}
19+
}
20+
`
21+
22+
// ExtraSpecGetBody provides a GET result of a particular extra_spec for a flavor
23+
const GetExtraSpecBody = `
24+
{
25+
"hw:cpu_policy": "CPU-POLICY"
26+
}
27+
`
28+
29+
// ExtraSpecs is the expected extra_specs returned from GET on a flavor's extra_specs
30+
var ExtraSpecs = map[string]string{
31+
"hw:cpu_policy": "CPU-POLICY",
32+
"hw:cpu_thread_policy": "CPU-THREAD-POLICY",
33+
}
34+
35+
// ExtraSpec is the expected extra_spec returned from GET on a flavor's extra_specs
36+
var ExtraSpec = map[string]string{
37+
"hw:cpu_policy": "CPU-POLICY",
38+
}
39+
40+
func HandleExtraSpecsListSuccessfully(t *testing.T) {
41+
th.Mux.HandleFunc("/flavors/1/os-extra_specs", func(w http.ResponseWriter, r *http.Request) {
42+
th.TestMethod(t, r, "GET")
43+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
44+
th.TestHeader(t, r, "Accept", "application/json")
45+
46+
w.Header().Set("Content-Type", "application/json")
47+
w.WriteHeader(http.StatusOK)
48+
fmt.Fprintf(w, ExtraSpecsGetBody)
49+
})
50+
}
51+
52+
func HandleExtraSpecGetSuccessfully(t *testing.T) {
53+
th.Mux.HandleFunc("/flavors/1/os-extra_specs/hw:cpu_policy", func(w http.ResponseWriter, r *http.Request) {
54+
th.TestMethod(t, r, "GET")
55+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
56+
th.TestHeader(t, r, "Accept", "application/json")
57+
58+
w.Header().Set("Content-Type", "application/json")
59+
w.WriteHeader(http.StatusOK)
60+
fmt.Fprintf(w, GetExtraSpecBody)
61+
})
62+
}

openstack/compute/v2/flavors/testing/requests_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,25 @@ func TestFlavorAccessesList(t *testing.T) {
250250
t.Errorf("Expected %#v, but was %#v", expected, actual)
251251
}
252252
}
253+
254+
func TestFlavorExtraSpecsList(t *testing.T) {
255+
th.SetupHTTP()
256+
defer th.TeardownHTTP()
257+
HandleExtraSpecsListSuccessfully(t)
258+
259+
expected := ExtraSpecs
260+
actual, err := flavors.ListExtraSpecs(fake.ServiceClient(), "1").Extract()
261+
th.AssertNoErr(t, err)
262+
th.CheckDeepEquals(t, expected, actual)
263+
}
264+
265+
func TestFlavorExtraSpecGet(t *testing.T) {
266+
th.SetupHTTP()
267+
defer th.TeardownHTTP()
268+
HandleExtraSpecGetSuccessfully(t)
269+
270+
expected := ExtraSpec
271+
actual, err := flavors.GetExtraSpec(fake.ServiceClient(), "1", "hw:cpu_policy").Extract()
272+
th.AssertNoErr(t, err)
273+
th.CheckDeepEquals(t, expected, actual)
274+
}

openstack/compute/v2/flavors/urls.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,11 @@ func deleteURL(client *gophercloud.ServiceClient, id string) string {
2323
func accessURL(client *gophercloud.ServiceClient, id string) string {
2424
return client.ServiceURL("flavors", id, "os-flavor-access")
2525
}
26+
27+
func extraSpecsListURL(client *gophercloud.ServiceClient, id string) string {
28+
return client.ServiceURL("flavors", id, "os-extra_specs")
29+
}
30+
31+
func extraSpecsGetURL(client *gophercloud.ServiceClient, id, key string) string {
32+
return client.ServiceURL("flavors", id, "os-extra_specs", key)
33+
}

0 commit comments

Comments
 (0)