blob: e670076a6e49f7ff3f47f8c0114f20c84bc1a4df [file] [log] [blame]
jrperrittc5c590a2016-11-04 14:41:15 -05001package images
2
3import (
4 "encoding/json"
5 "fmt"
6 "reflect"
7 "time"
8
Krzysztof Szukiełojć3f41d082017-05-07 14:43:06 +02009 "gerrit.mcp.mirantis.net/debian/gophercloud.git"
Joe Topjianfc6c80c2017-06-13 13:06:50 -060010 "gerrit.mcp.mirantis.net/debian/gophercloud.git/internal"
Krzysztof Szukiełojć24a29ce2017-05-07 14:24:02 +020011 "gerrit.mcp.mirantis.net/debian/gophercloud.git/pagination"
jrperrittc5c590a2016-11-04 14:41:15 -050012)
13
14// Image model
15// Does not include the literal image data; just metadata.
16// returned by listing images, and by fetching a specific image.
17type Image struct {
18 // ID is the image UUID
19 ID string `json:"id"`
20
21 // Name is the human-readable display name for the image.
22 Name string `json:"name"`
23
24 // Status is the image status. It can be "queued" or "active"
25 // See imageservice/v2/images/type.go
26 Status ImageStatus `json:"status"`
27
28 // Tags is a list of image tags. Tags are arbitrarily defined strings
29 // attached to an image.
30 Tags []string `json:"tags"`
31
32 // ContainerFormat is the format of the container.
33 // Valid values are ami, ari, aki, bare, and ovf.
34 ContainerFormat string `json:"container_format"`
35
36 // DiskFormat is the format of the disk.
37 // If set, valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, and iso.
38 DiskFormat string `json:"disk_format"`
39
40 // MinDiskGigabytes is the amount of disk space in GB that is required to boot the image.
41 MinDiskGigabytes int `json:"min_disk"`
42
43 // MinRAMMegabytes [optional] is the amount of RAM in MB that is required to boot the image.
44 MinRAMMegabytes int `json:"min_ram"`
45
46 // Owner is the tenant the image belongs to.
47 Owner string `json:"owner"`
48
49 // Protected is whether the image is deletable or not.
50 Protected bool `json:"protected"`
51
52 // Visibility defines who can see/use the image.
53 Visibility ImageVisibility `json:"visibility"`
54
55 // Checksum is the checksum of the data that's associated with the image
56 Checksum string `json:"checksum"`
57
58 // SizeBytes is the size of the data that's associated with the image.
59 SizeBytes int64 `json:"size"`
60
61 // Metadata is a set of metadata associated with the image.
62 // Image metadata allow for meaningfully define the image properties
63 // and tags. See http://docs.openstack.org/developer/glance/metadefs-concepts.html.
64 Metadata map[string]string `json:"metadata"`
65
66 // Properties is a set of key-value pairs, if any, that are associated with the image.
Joe Topjianfc6c80c2017-06-13 13:06:50 -060067 Properties map[string]interface{} `json:"-"`
jrperrittc5c590a2016-11-04 14:41:15 -050068
69 // CreatedAt is the date when the image has been created.
jrperritt98d01622017-01-12 14:24:42 -060070 CreatedAt time.Time `json:"created_at"`
jrperrittc5c590a2016-11-04 14:41:15 -050071
72 // UpdatedAt is the date when the last change has been made to the image or it's properties.
jrperritt98d01622017-01-12 14:24:42 -060073 UpdatedAt time.Time `json:"updated_at"`
jrperrittc5c590a2016-11-04 14:41:15 -050074
75 // File is the trailing path after the glance endpoint that represent the location
76 // of the image or the path to retrieve it.
77 File string `json:"file"`
78
79 // Schema is the path to the JSON-schema that represent the image or image entity.
80 Schema string `json:"schema"`
Joe Topjianfc6c80c2017-06-13 13:06:50 -060081
82 // VirtualSize is the virtual size of the image
83 VirtualSize int64 `json:"virtual_size"`
jrperrittc5c590a2016-11-04 14:41:15 -050084}
85
jrperritt98d01622017-01-12 14:24:42 -060086func (r *Image) UnmarshalJSON(b []byte) error {
jrperrittc5c590a2016-11-04 14:41:15 -050087 type tmp Image
jrperritt98d01622017-01-12 14:24:42 -060088 var s struct {
jrperrittc5c590a2016-11-04 14:41:15 -050089 tmp
90 SizeBytes interface{} `json:"size"`
jrperrittc5c590a2016-11-04 14:41:15 -050091 }
jrperritt98d01622017-01-12 14:24:42 -060092 err := json.Unmarshal(b, &s)
jrperrittc5c590a2016-11-04 14:41:15 -050093 if err != nil {
94 return err
95 }
jrperritt98d01622017-01-12 14:24:42 -060096 *r = Image(s.tmp)
jrperrittc5c590a2016-11-04 14:41:15 -050097
jrperritt98d01622017-01-12 14:24:42 -060098 switch t := s.SizeBytes.(type) {
jrperrittc5c590a2016-11-04 14:41:15 -050099 case nil:
100 return nil
101 case float32:
jrperritt98d01622017-01-12 14:24:42 -0600102 r.SizeBytes = int64(t)
jrperrittc5c590a2016-11-04 14:41:15 -0500103 case float64:
jrperritt98d01622017-01-12 14:24:42 -0600104 r.SizeBytes = int64(t)
jrperrittc5c590a2016-11-04 14:41:15 -0500105 default:
106 return fmt.Errorf("Unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t)
107 }
108
Joe Topjianfc6c80c2017-06-13 13:06:50 -0600109 // Bundle all other fields into Properties
110 var result interface{}
111 err = json.Unmarshal(b, &result)
112 if err != nil {
113 return err
114 }
115 if resultMap, ok := result.(map[string]interface{}); ok {
116 delete(resultMap, "self")
117 r.Properties = internal.RemainingKeys(Image{}, resultMap)
118 }
119
jrperrittc5c590a2016-11-04 14:41:15 -0500120 return err
121}
122
123type commonResult struct {
124 gophercloud.Result
125}
126
127// Extract interprets any commonResult as an Image.
128func (r commonResult) Extract() (*Image, error) {
129 var s *Image
130 err := r.ExtractInto(&s)
131 return s, err
132}
133
134// CreateResult represents the result of a Create operation
135type CreateResult struct {
136 commonResult
137}
138
139// UpdateResult represents the result of an Update operation
140type UpdateResult struct {
141 commonResult
142}
143
144// GetResult represents the result of a Get operation
145type GetResult struct {
146 commonResult
147}
148
149//DeleteResult model
150type DeleteResult struct {
151 gophercloud.ErrResult
152}
153
154// ImagePage represents page
155type ImagePage struct {
156 pagination.LinkedPageBase
157}
158
159// IsEmpty returns true if a page contains no Images results.
160func (r ImagePage) IsEmpty() (bool, error) {
161 images, err := ExtractImages(r)
162 return len(images) == 0, err
163}
164
165// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
166func (r ImagePage) NextPageURL() (string, error) {
167 var s struct {
168 Next string `json:"next"`
169 }
170 err := r.ExtractInto(&s)
171 if err != nil {
172 return "", err
173 }
Joe Topjianff779172017-02-14 18:24:39 -0700174
175 if s.Next == "" {
176 return "", nil
177 }
178
jrperrittc5c590a2016-11-04 14:41:15 -0500179 return nextPageURL(r.URL.String(), s.Next), nil
180}
181
182// ExtractImages interprets the results of a single page from a List() call, producing a slice of Image entities.
183func ExtractImages(r pagination.Page) ([]Image, error) {
184 var s struct {
185 Images []Image `json:"images"`
186 }
187 err := (r.(ImagePage)).ExtractInto(&s)
188 return s.Images, err
189}