Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit 5e7410b

Browse files
James FisherSamuel Ortiz
authored andcommitted
failing implementation of Create
1 parent e8e4ee4 commit 5e7410b

File tree

3 files changed

+253
-1
lines changed

3 files changed

+253
-1
lines changed

openstack/imageservice/v2/requests.go

Lines changed: 160 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,162 @@
11
package v2
22

3-
// TODO
3+
import (
4+
"github.com/rackspace/gophercloud"
5+
//"github.com/rackspace/gophercloud/pagination"
6+
)
7+
8+
// List : (*gophercloud.ServiceClient) -> pagination.Pager<ImagePage>
9+
// func List(c *gophercloud.ServiceClient) pagination.Pager {
10+
// return pagination.NewPager(c, listURL(c), func (r pagination.PageResult) pagination.Page {
11+
// p := ImagePage{pagination.MarkerPageBase{PageResult: r}}
12+
// p.MarkerPageBase.Owner = p
13+
// return p
14+
// })
15+
// }
16+
17+
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
18+
var res CreateResult
19+
body, err := opts.ToImageCreateMap()
20+
if err != nil {
21+
res.Err = err
22+
return res
23+
}
24+
response, err := client.Post(createURL(client), body, &res.Body, nil)
25+
// TODO check response..?
26+
return res
27+
}
28+
29+
// CreateOptsBuilder describes struct types that can be accepted by the Create call.
30+
// The CreateOpts struct in this package does.
31+
type CreateOptsBuilder interface {
32+
// Returns value that implements json.Marshaler
33+
ToImageCreateMap() (map[string]interface{}, error)
34+
}
35+
36+
// implements CreateOptsBuilder
37+
type CreateOpts struct {
38+
// Name [required] is the name of the new image.
39+
Name string
40+
41+
// Id [optional] is the the image ID.
42+
Id string
43+
44+
// Visibility [optional] defines who can see/use the image.
45+
Visibility ImageVisibility
46+
47+
// Tags [optional] is a set of image tags.
48+
Tags []string
49+
50+
// ContainerFormat [optional] is the format of the
51+
// container. Valid values are ami, ari, aki, bare, and ovf.
52+
ContainerFormat string
53+
54+
// DiskFormat [optional] is the format of the disk. If set,
55+
// valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi,
56+
// and iso.
57+
DiskFormat string
58+
59+
// MinDiskGigabytes [optional] is the amount of disk space in
60+
// GB that is required to boot the image.
61+
MinDiskGigabytes int
62+
63+
// MinRamMegabytes [optional] is the amount of RAM in MB that
64+
// is required to boot the image.
65+
MinRamMegabytes int
66+
67+
// protected [optional] is whether the image is not deletable.
68+
Protected bool
69+
70+
// properties [optional] is a set of properties, if any, that
71+
// are associated with the image.
72+
Properties map[string]string
73+
}
74+
75+
func setIfNotNil(m map[string]interface{}, k string, v interface{}) {
76+
if v != nil {
77+
m[k] = v
78+
}
79+
}
80+
81+
// ToImageCreateMap assembles a request body based on the contents of
82+
// a CreateOpts.
83+
func (opts CreateOpts) ToImageCreateMap() (map[string]interface{}, error) {
84+
body := map[string]interface{}{}
85+
body["name"] = opts.Name
86+
setIfNotNil(body, "id", opts.Id)
87+
setIfNotNil(body, "visibility", opts.Visibility)
88+
setIfNotNil(body, "tags", opts.Tags)
89+
setIfNotNil(body, "container_format", opts.ContainerFormat)
90+
setIfNotNil(body, "disk_format", opts.DiskFormat)
91+
setIfNotNil(body, "min_disk", opts.MinDiskGigabytes)
92+
setIfNotNil(body, "min_ram", opts.MinRamMegabytes)
93+
setIfNotNil(body, "protected", opts.Protected)
94+
setIfNotNil(body, "properties", opts.Properties)
95+
return body, nil
96+
}
97+
98+
func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
99+
var res DeleteResult
100+
_, res.Err = client.Delete(deleteURL(client, id), nil)
101+
return res
102+
}
103+
104+
func Get(client *gophercloud.ServiceClient, id string) GetResult {
105+
var res GetResult
106+
client.Get(getURL(client, id), &res.Body, nil)
107+
return res
108+
}
109+
110+
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
111+
var res UpdateResult
112+
reqBody := opts.ToImageUpdateMap()
113+
114+
_, res.Err = client.Patch(updateURL(client, id), reqBody, &res.Body, &gophercloud.RequestOpts{
115+
OkCodes: []int{200},
116+
})
117+
return res
118+
}
119+
120+
type UpdateOptsBuilder interface {
121+
// returns value implementing json.Marshaler which when marshaled matches the patch schema:
122+
// http://specs.openstack.org/openstack/glance-specs/specs/api/v2/http-patch-image-api-v2.html
123+
ToImageUpdateMap() []interface{}
124+
}
125+
126+
// implements UpdateOptsBuilder
127+
type UpdateOpts []Patch
128+
129+
func (opts UpdateOpts) ToImageUpdateMap() []interface{} {
130+
m := make([]interface{}, len(opts))
131+
for i, patch := range opts {
132+
patchJson := patch.ToImagePatchMap()
133+
m[i] = patchJson
134+
}
135+
return m
136+
}
137+
138+
// Patch represents a single update to an existing image. Multiple updates to an image can be
139+
// submitted at the same time.
140+
type Patch interface {
141+
ToImagePatchMap() map[string]interface{}
142+
}
143+
144+
//implements Patch
145+
type ReplaceImageName struct {
146+
NewName string
147+
}
148+
149+
func (r *ReplaceImageName) ToImagePatchMap() map[string]interface{} {
150+
m := map[string]interface{}{}
151+
m["op"] = "replace"
152+
m["path"] = "/name"
153+
m["value"] = r.NewName
154+
return m
155+
}
156+
157+
// Things implementing Patch can also implement UpdateOptsBuilder.
158+
// Unfortunately we have to specify each of these manually.
159+
160+
func (r *ReplaceImageName) ToImageUpdateMap() map[string]interface{} {
161+
return r.ToImagePatchMap()
162+
}

openstack/imageservice/v2/results.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package v2
2+
3+
import (
4+
"github.com/rackspace/gophercloud"
5+
//"github.com/rackspace/gophercloud/pagination"
6+
7+
"github.com/mitchellh/mapstructure"
8+
)
9+
10+
// does not include the literal image data; just metadata.
11+
// returned by listing images, and by fetching a specific image.
12+
type Image struct {
13+
Id string `mapstructure:"id"`
14+
15+
Name string `mapstructure:"name"`
16+
17+
Status ImageStatus `mapstructure:"status"`
18+
19+
Tags []string `mapstructure:"tags"`
20+
21+
ContainerFormat string `mapstructure:"container_format"`
22+
DiskFormat string `mapstructure:"disk_format"`
23+
24+
MinDiskGigabytes int `mapstructure:"min_disk"`
25+
MinRamMegabytes int `mapstructure:"min_ram"`
26+
27+
Owner string `mapstructure:"owner"`
28+
29+
Protected bool `mapstructure:"protected"`
30+
Visibility ImageVisibility `mapstructure:"visibility"`
31+
32+
Checksum string `mapstructure:"checksum"`
33+
SizeBytes int `mapstructure:"size"`
34+
35+
Metadata map[string]string `mapstructure:"metadata"`
36+
Properties map[string]string `mapstructure:"properties"`
37+
}
38+
39+
// implements pagination.Page<Image>, pagination.MarkerPage
40+
// DOESN'T implement Page. Why? How does openstack/compute/v2
41+
// type ImagePage struct {
42+
// pagination.MarkerPageBase // pagination.MarkerPageBase<Image>
43+
// }
44+
45+
type CreateResult struct {
46+
gophercloud.ErrResult
47+
}
48+
49+
// The response to `POST /images` follows the same schema as `GET /images/:id`.
50+
func extractImage(res gophercloud.ErrResult) (*Image, error) {
51+
if res.Err != nil {
52+
return nil, res.Err
53+
}
54+
55+
var image Image
56+
57+
err := mapstructure.Decode(res.Body, &image)
58+
59+
return &image, err
60+
}
61+
62+
func (c CreateResult) Extract() (*Image, error) {
63+
return extractImage(c.ErrResult)
64+
}
65+
66+
type DeleteResult struct {
67+
gophercloud.ErrResult
68+
}
69+
70+
type GetResult struct {
71+
gophercloud.ErrResult
72+
}
73+
74+
func (c GetResult) Extract() (*Image, error) {
75+
return extractImage(c.ErrResult)
76+
}
77+
78+
type UpdateResult struct {
79+
gophercloud.ErrResult
80+
}

openstack/imageservice/v2/types.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package v2
2+
3+
type ImageStatus string
4+
const (
5+
ImageStatusActive ImageStatus = "active"
6+
// TODO
7+
)
8+
9+
type ImageVisibility string
10+
const (
11+
ImageVisibilityPublic ImageVisibility = "public"
12+
ImageVisibilityPrivate ImageVisibility = "private"
13+
)

0 commit comments

Comments
 (0)