blob: 09996f4af3f4b94a77b0581d9daf72edbea7887b [file] [log] [blame]
jrperrittc5c590a2016-11-04 14:41:15 -05001package images
2
3import (
4 "encoding/json"
5 "fmt"
6 "reflect"
7 "time"
8
9 "github.com/gophercloud/gophercloud"
10 "github.com/gophercloud/gophercloud/pagination"
11)
12
13// Image model
14// Does not include the literal image data; just metadata.
15// returned by listing images, and by fetching a specific image.
16type Image struct {
17 // ID is the image UUID
18 ID string `json:"id"`
19
20 // Name is the human-readable display name for the image.
21 Name string `json:"name"`
22
23 // Status is the image status. It can be "queued" or "active"
24 // See imageservice/v2/images/type.go
25 Status ImageStatus `json:"status"`
26
27 // Tags is a list of image tags. Tags are arbitrarily defined strings
28 // attached to an image.
29 Tags []string `json:"tags"`
30
31 // ContainerFormat is the format of the container.
32 // Valid values are ami, ari, aki, bare, and ovf.
33 ContainerFormat string `json:"container_format"`
34
35 // DiskFormat is the format of the disk.
36 // If set, valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, and iso.
37 DiskFormat string `json:"disk_format"`
38
39 // MinDiskGigabytes is the amount of disk space in GB that is required to boot the image.
40 MinDiskGigabytes int `json:"min_disk"`
41
42 // MinRAMMegabytes [optional] is the amount of RAM in MB that is required to boot the image.
43 MinRAMMegabytes int `json:"min_ram"`
44
45 // Owner is the tenant the image belongs to.
46 Owner string `json:"owner"`
47
48 // Protected is whether the image is deletable or not.
49 Protected bool `json:"protected"`
50
51 // Visibility defines who can see/use the image.
52 Visibility ImageVisibility `json:"visibility"`
53
54 // Checksum is the checksum of the data that's associated with the image
55 Checksum string `json:"checksum"`
56
57 // SizeBytes is the size of the data that's associated with the image.
58 SizeBytes int64 `json:"size"`
59
60 // Metadata is a set of metadata associated with the image.
61 // Image metadata allow for meaningfully define the image properties
62 // and tags. See http://docs.openstack.org/developer/glance/metadefs-concepts.html.
63 Metadata map[string]string `json:"metadata"`
64
65 // Properties is a set of key-value pairs, if any, that are associated with the image.
66 Properties map[string]string `json:"properties"`
67
68 // CreatedAt is the date when the image has been created.
jrperritt98d01622017-01-12 14:24:42 -060069 CreatedAt time.Time `json:"created_at"`
jrperrittc5c590a2016-11-04 14:41:15 -050070
71 // UpdatedAt is the date when the last change has been made to the image or it's properties.
jrperritt98d01622017-01-12 14:24:42 -060072 UpdatedAt time.Time `json:"updated_at"`
jrperrittc5c590a2016-11-04 14:41:15 -050073
74 // File is the trailing path after the glance endpoint that represent the location
75 // of the image or the path to retrieve it.
76 File string `json:"file"`
77
78 // Schema is the path to the JSON-schema that represent the image or image entity.
79 Schema string `json:"schema"`
80}
81
jrperritt98d01622017-01-12 14:24:42 -060082func (r *Image) UnmarshalJSON(b []byte) error {
jrperrittc5c590a2016-11-04 14:41:15 -050083 type tmp Image
jrperritt98d01622017-01-12 14:24:42 -060084 var s struct {
jrperrittc5c590a2016-11-04 14:41:15 -050085 tmp
86 SizeBytes interface{} `json:"size"`
jrperrittc5c590a2016-11-04 14:41:15 -050087 }
jrperritt98d01622017-01-12 14:24:42 -060088 err := json.Unmarshal(b, &s)
jrperrittc5c590a2016-11-04 14:41:15 -050089 if err != nil {
90 return err
91 }
jrperritt98d01622017-01-12 14:24:42 -060092 *r = Image(s.tmp)
jrperrittc5c590a2016-11-04 14:41:15 -050093
jrperritt98d01622017-01-12 14:24:42 -060094 switch t := s.SizeBytes.(type) {
jrperrittc5c590a2016-11-04 14:41:15 -050095 case nil:
96 return nil
97 case float32:
jrperritt98d01622017-01-12 14:24:42 -060098 r.SizeBytes = int64(t)
jrperrittc5c590a2016-11-04 14:41:15 -050099 case float64:
jrperritt98d01622017-01-12 14:24:42 -0600100 r.SizeBytes = int64(t)
jrperrittc5c590a2016-11-04 14:41:15 -0500101 default:
102 return fmt.Errorf("Unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t)
103 }
104
jrperrittc5c590a2016-11-04 14:41:15 -0500105 return err
106}
107
108type commonResult struct {
109 gophercloud.Result
110}
111
112// Extract interprets any commonResult as an Image.
113func (r commonResult) Extract() (*Image, error) {
114 var s *Image
115 err := r.ExtractInto(&s)
116 return s, err
117}
118
119// CreateResult represents the result of a Create operation
120type CreateResult struct {
121 commonResult
122}
123
124// UpdateResult represents the result of an Update operation
125type UpdateResult struct {
126 commonResult
127}
128
129// GetResult represents the result of a Get operation
130type GetResult struct {
131 commonResult
132}
133
134//DeleteResult model
135type DeleteResult struct {
136 gophercloud.ErrResult
137}
138
139// ImagePage represents page
140type ImagePage struct {
141 pagination.LinkedPageBase
142}
143
144// IsEmpty returns true if a page contains no Images results.
145func (r ImagePage) IsEmpty() (bool, error) {
146 images, err := ExtractImages(r)
147 return len(images) == 0, err
148}
149
150// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
151func (r ImagePage) NextPageURL() (string, error) {
152 var s struct {
153 Next string `json:"next"`
154 }
155 err := r.ExtractInto(&s)
156 if err != nil {
157 return "", err
158 }
Joe Topjianff779172017-02-14 18:24:39 -0700159
160 if s.Next == "" {
161 return "", nil
162 }
163
jrperrittc5c590a2016-11-04 14:41:15 -0500164 return nextPageURL(r.URL.String(), s.Next), nil
165}
166
167// ExtractImages interprets the results of a single page from a List() call, producing a slice of Image entities.
168func ExtractImages(r pagination.Page) ([]Image, error) {
169 var s struct {
170 Images []Image `json:"images"`
171 }
172 err := (r.(ImagePage)).ExtractInto(&s)
173 return s.Images, err
174}