ImageService v2: Fixing Create Properties (#264)
* Fix Creating Image Properties
The combination of JSON tags were not rendering the JSON body
correctly and causing a 400 error by the API.
* ImageService v2 Acceptance Tests
* unit tests
diff --git a/acceptance/clients/clients.go b/acceptance/clients/clients.go
index f07754f..8bf4aa3 100644
--- a/acceptance/clients/clients.go
+++ b/acceptance/clients/clients.go
@@ -266,6 +266,25 @@
return openstack.NewIdentityV3(client, gophercloud.EndpointOpts{})
}
+// NewImageServiceV2Client returns a *ServiceClient for making calls to the
+// OpenStack Image v2 API. An error will be returned if authentication or
+// client creation was not possible.
+func NewImageServiceV2Client() (*gophercloud.ServiceClient, error) {
+ ao, err := openstack.AuthOptionsFromEnv()
+ if err != nil {
+ return nil, err
+ }
+
+ client, err := openstack.AuthenticatedClient(ao)
+ if err != nil {
+ return nil, err
+ }
+
+ return openstack.NewImageServiceV2(client, gophercloud.EndpointOpts{
+ Region: os.Getenv("OS_REGION_NAME"),
+ })
+}
+
// NewNetworkV2Client returns a *ServiceClient for making calls to the
// OpenStack Networking v2 API. An error will be returned if authentication
// or client creation was not possible.
diff --git a/acceptance/openstack/imageservice/v2/images_test.go b/acceptance/openstack/imageservice/v2/images_test.go
new file mode 100644
index 0000000..aa0390b
--- /dev/null
+++ b/acceptance/openstack/imageservice/v2/images_test.go
@@ -0,0 +1,26 @@
+// +build acceptance imageservice images
+
+package v2
+
+import (
+ "testing"
+
+ "github.com/gophercloud/gophercloud/acceptance/clients"
+ "github.com/gophercloud/gophercloud/acceptance/tools"
+)
+
+func TestImagesCreateDestroyEmptyImage(t *testing.T) {
+ client, err := clients.NewImageServiceV2Client()
+ if err != nil {
+ t.Fatalf("Unable to create an image service client: %v", err)
+ }
+
+ image, err := CreateEmptyImage(t, client)
+ if err != nil {
+ t.Fatalf("Unable to create empty image: %v", err)
+ }
+
+ defer DeleteImage(t, client, image)
+
+ tools.PrintResource(t, image)
+}
diff --git a/acceptance/openstack/imageservice/v2/imageservice.go b/acceptance/openstack/imageservice/v2/imageservice.go
new file mode 100644
index 0000000..8aaeeb7
--- /dev/null
+++ b/acceptance/openstack/imageservice/v2/imageservice.go
@@ -0,0 +1,55 @@
+// Package v2 contains common functions for creating imageservice resources
+// for use in acceptance tests. See the `*_test.go` files for example usages.
+package v2
+
+import (
+ "testing"
+
+ "github.com/gophercloud/gophercloud"
+ "github.com/gophercloud/gophercloud/acceptance/tools"
+ "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
+)
+
+// CreateEmptyImage will create an image, but with no actual image data.
+// An error will be returned if an image was unable to be created.
+func CreateEmptyImage(t *testing.T, client *gophercloud.ServiceClient) (*images.Image, error) {
+ var image *images.Image
+
+ name := tools.RandomString("ACPTTEST", 16)
+ t.Logf("Attempting to create image: %s", name)
+
+ protected := false
+ visibility := images.ImageVisibilityPrivate
+ createOpts := &images.CreateOpts{
+ Name: name,
+ ContainerFormat: "bare",
+ DiskFormat: "qcow2",
+ MinDisk: 0,
+ MinRAM: 0,
+ Protected: &protected,
+ Visibility: &visibility,
+ Properties: map[string]string{
+ "architecture": "x86_64",
+ },
+ }
+
+ image, err := images.Create(client, createOpts).Extract()
+ if err != nil {
+ return image, err
+ }
+
+ t.Logf("Created image %s: %#v", name, image)
+ return image, nil
+}
+
+// DeleteImage deletes an image.
+// A fatal error will occur if the image failed to delete. This works best when
+// used as a deferred function.
+func DeleteImage(t *testing.T, client *gophercloud.ServiceClient, image *images.Image) {
+ err := images.Delete(client, image.ID).ExtractErr()
+ if err != nil {
+ t.Fatalf("Unable to delete image %s: %v", image.ID, err)
+ }
+
+ t.Logf("Deleted image: %s", image.ID)
+}
diff --git a/openstack/imageservice/v2/images/requests.go b/openstack/imageservice/v2/images/requests.go
index 32f09ee..044b5cb 100644
--- a/openstack/imageservice/v2/images/requests.go
+++ b/openstack/imageservice/v2/images/requests.go
@@ -99,7 +99,7 @@
// properties is a set of properties, if any, that
// are associated with the image.
- Properties map[string]string `json:"-,omitempty"`
+ Properties map[string]string `json:"-"`
}
// ToImageCreateMap assembles a request body based on the contents of
diff --git a/openstack/imageservice/v2/images/testing/fixtures.go b/openstack/imageservice/v2/images/testing/fixtures.go
index 1754407..10a87b4 100644
--- a/openstack/imageservice/v2/images/testing/fixtures.go
+++ b/openstack/imageservice/v2/images/testing/fixtures.go
@@ -158,6 +158,7 @@
th.TestJSONRequest(t, r, `{
"id": "e7db3b45-8db7-47ad-8109-3fb55c2c24fd",
"name": "Ubuntu 12.10",
+ "architecture": "x86_64",
"tags": [
"ubuntu",
"quantal"
diff --git a/openstack/imageservice/v2/images/testing/requests_test.go b/openstack/imageservice/v2/images/testing/requests_test.go
index fdd8402..0371e4c 100644
--- a/openstack/imageservice/v2/images/testing/requests_test.go
+++ b/openstack/imageservice/v2/images/testing/requests_test.go
@@ -69,6 +69,9 @@
actualImage, err := images.Create(fakeclient.ServiceClient(), images.CreateOpts{
ID: id,
Name: name,
+ Properties: map[string]string{
+ "architecture": "x86_64",
+ },
Tags: []string{"ubuntu", "quantal"},
}).Extract()