blob: 653c68c73d63701b61919ed2c9cbb5af62ad0e49 [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.
69 CreatedAt time.Time `json:"-"`
70
71 // UpdatedAt is the date when the last change has been made to the image or it's properties.
72 UpdatedAt time.Time `json:"-"`
73
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
82func (s *Image) UnmarshalJSON(b []byte) error {
83 type tmp Image
84 var p *struct {
85 tmp
86 SizeBytes interface{} `json:"size"`
87 CreatedAt string `json:"created_at"`
88 UpdatedAt string `json:"updated_at"`
89 }
90 err := json.Unmarshal(b, &p)
91 if err != nil {
92 return err
93 }
94 *s = Image(p.tmp)
95
96 switch t := p.SizeBytes.(type) {
97 case nil:
98 return nil
99 case float32:
100 s.SizeBytes = int64(t)
101 case float64:
102 s.SizeBytes = int64(t)
103 default:
104 return fmt.Errorf("Unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t)
105 }
106
107 s.CreatedAt, err = time.Parse(time.RFC3339, p.CreatedAt)
108 if err != nil {
109 return err
110 }
111 s.UpdatedAt, err = time.Parse(time.RFC3339, p.UpdatedAt)
112 return err
113}
114
115type commonResult struct {
116 gophercloud.Result
117}
118
119// Extract interprets any commonResult as an Image.
120func (r commonResult) Extract() (*Image, error) {
121 var s *Image
122 err := r.ExtractInto(&s)
123 return s, err
124}
125
126// CreateResult represents the result of a Create operation
127type CreateResult struct {
128 commonResult
129}
130
131// UpdateResult represents the result of an Update operation
132type UpdateResult struct {
133 commonResult
134}
135
136// GetResult represents the result of a Get operation
137type GetResult struct {
138 commonResult
139}
140
141//DeleteResult model
142type DeleteResult struct {
143 gophercloud.ErrResult
144}
145
146// ImagePage represents page
147type ImagePage struct {
148 pagination.LinkedPageBase
149}
150
151// IsEmpty returns true if a page contains no Images results.
152func (r ImagePage) IsEmpty() (bool, error) {
153 images, err := ExtractImages(r)
154 return len(images) == 0, err
155}
156
157// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
158func (r ImagePage) NextPageURL() (string, error) {
159 var s struct {
160 Next string `json:"next"`
161 }
162 err := r.ExtractInto(&s)
163 if err != nil {
164 return "", err
165 }
166 return nextPageURL(r.URL.String(), s.Next), nil
167}
168
169// ExtractImages interprets the results of a single page from a List() call, producing a slice of Image entities.
170func ExtractImages(r pagination.Page) ([]Image, error) {
171 var s struct {
172 Images []Image `json:"images"`
173 }
174 err := (r.(ImagePage)).ExtractInto(&s)
175 return s.Images, err
176}