Naming convention and better parsing of Location
diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go
index caeb946..aa8c1a8 100644
--- a/openstack/compute/v2/servers/requests.go
+++ b/openstack/compute/v2/servers/requests.go
@@ -4,7 +4,6 @@
"encoding/base64"
"errors"
"fmt"
- "strings"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
@@ -702,23 +701,23 @@
return pagination.NewPager(client, listAddressesByNetworkURL(client, id, network), createPageFn)
}
-type CreateServerImageOpts struct {
+type CreateImageOpts struct {
// Name [required] of the image/snapshot
Name string
// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the created image.
Metadata map[string]string
}
-type CreateServerImageOptsBuilder interface {
- ToCreateServerImageMap() (map[string]interface{}, error)
+type CreateImageOptsBuilder interface {
+ ToServerCreateImageMap() (map[string]interface{}, error)
}
-// ToServerImageCreateMap formats an ServerImageCreateOpts structure into a request body.
-func (opts CreateServerImageOpts) ToCreateServerImageMap() (map[string]interface{}, error) {
+// ToServerCreateImageMap formats a CreateImageOpts structure into a request body.
+func (opts CreateImageOpts) ToServerCreateImageMap() (map[string]interface{}, error) {
var err error
img := make(map[string]interface{})
if opts.Name == "" {
- err = fmt.Errorf("Cannot create a server image without a name")
+ return nil, fmt.Errorf("Cannot create a server image without a name")
}
img["name"] = opts.Name
if opts.Metadata != nil {
@@ -729,30 +728,10 @@
return createImage, err
}
-// ExtractImageID gets the ID of the newly created server image from the header
-func (res CreateServerImageResult) ExtractImageID() (string, error) {
- var err error
- if res.Err != nil {
- return "", res.Err
- }
- // Get the image id from the header
- rawUrl := res.Header.Get("Location")
- fmt.Println("RawUrl:", rawUrl)
- if rawUrl != "" {
- split := strings.Split(rawUrl, "/")
- if len(split) > 0 {
- id := split[len(split)-1]
- return id, nil
- }
- }
- err = fmt.Errorf("Failed to parse the ID of newly created image")
- return "", err
-}
-
-// CreateServerImage makes a request against the nova API to schedule an image to be created of the server
-func CreateServerImage(client *gophercloud.ServiceClient, serverId string, opts CreateServerImageOptsBuilder) CreateServerImageResult {
- var res CreateServerImageResult
- reqBody, err := opts.ToCreateServerImageMap()
+// CreateImage makes a request against the nova API to schedule an image to be created of the server
+func CreateImage(client *gophercloud.ServiceClient, serverId string, opts CreateImageOptsBuilder) CreateImageResult {
+ var res CreateImageResult
+ reqBody, err := opts.ToServerCreateImageMap()
if err != nil {
res.Err = err
return res
@@ -761,8 +740,6 @@
OkCodes: []int{202},
})
res.Err = err
- if err == nil {
- res.Header = response.Header
- }
+ res.Header = response.Header
return res
}
diff --git a/openstack/compute/v2/servers/requests_test.go b/openstack/compute/v2/servers/requests_test.go
index 466bbf7..1f39fe1 100644
--- a/openstack/compute/v2/servers/requests_test.go
+++ b/openstack/compute/v2/servers/requests_test.go
@@ -331,7 +331,6 @@
defer th.TeardownHTTP()
HandleCreateServerImageSuccessfully(t)
- _, err := CreateServerImage(client.ServiceClient(), "serverimage", CreateServerImageOpts{Name: "test"}).ExtractImageID()
+ _, err := CreateImage(client.ServiceClient(), "serverimage", CreateImageOpts{Name: "test"}).ExtractImageID()
th.AssertNoErr(t, err)
-
}
diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go
index 26e099a..f278709 100644
--- a/openstack/compute/v2/servers/results.go
+++ b/openstack/compute/v2/servers/results.go
@@ -2,6 +2,9 @@
import (
"reflect"
+ "fmt"
+ "path"
+ "net/url"
"github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
@@ -74,11 +77,28 @@
ActionResult
}
-// RescueResult represents the result of a server rescue operation
-type CreateServerImageResult struct {
+// CreateImageResult represents the result of an image creation operation
+type CreateImageResult struct {
gophercloud.Result
}
+// ExtractImageID gets the ID of the newly created server image from the header
+func (res CreateImageResult) ExtractImageID() (string, error) {
+ if res.Err != nil {
+ return "", res.Err
+ }
+ // Get the image id from the header
+ u, err := url.ParseRequestURI(res.Header.Get("Location"))
+ if err != nil {
+ return "", fmt.Errorf("Failed to parse the image id: %s", err.Error())
+ }
+ imageId := path.Base(u.Path)
+ if imageId == "." || imageId == "/" {
+ return "", fmt.Errorf("Failed to parse the ID of newly created image: %s", u)
+ }
+ return imageId, nil
+}
+
// Extract interprets any RescueResult as an AdminPass, if possible.
func (r RescueResult) Extract() (string, error) {
if r.Err != nil {