blob: ec3c1e010801fadcc3026b40265ea7b085f1e248 [file] [log] [blame]
Jon Perritt8c93a302014-09-28 22:35:57 -05001package containers
2
3import (
4 "fmt"
Ash Wilsonaf262872014-10-20 09:32:29 -04005 "net/http"
Jon Perritt8c93a302014-09-28 22:35:57 -05006 "strings"
Jon Perritt5db08922014-09-30 21:32:48 -05007
Ash Wilsonaf262872014-10-20 09:32:29 -04008 "github.com/rackspace/gophercloud"
Jon Perritt5db08922014-09-30 21:32:48 -05009 "github.com/rackspace/gophercloud/pagination"
Jon Perrittb3461402014-10-09 21:36:17 -050010
11 "github.com/mitchellh/mapstructure"
Jon Perritt8c93a302014-09-28 22:35:57 -050012)
13
Jamie Hannaford4ff79962014-10-06 16:28:23 +020014// Container represents a container resource.
Jon Perritt8aa40262014-09-29 15:41:32 -050015type Container struct {
Jamie Hannaford4ff79962014-10-06 16:28:23 +020016 // The total number of bytes stored in the container.
17 Bytes int `json:"bytes" mapstructure:"bytes"`
18
19 // The total number of objects stored in the container.
20 Count int `json:"count" mapstructure:"count"`
21
22 // The name of the container.
23 Name string `json:"name" mapstructure:"name"`
Jon Perritt8aa40262014-09-29 15:41:32 -050024}
Jon Perritt8c93a302014-09-28 22:35:57 -050025
Jamie Hannaford4ff79962014-10-06 16:28:23 +020026// ContainerPage is the page returned by a pager when traversing over a
27// collection of containers.
Jon Perritt8c93a302014-09-28 22:35:57 -050028type ContainerPage struct {
29 pagination.MarkerPageBase
30}
31
32// IsEmpty returns true if a ListResult contains no container names.
33func (r ContainerPage) IsEmpty() (bool, error) {
34 names, err := ExtractNames(r)
35 if err != nil {
36 return true, err
37 }
38 return len(names) == 0, nil
39}
40
41// LastMarker returns the last container name in a ListResult.
42func (r ContainerPage) LastMarker() (string, error) {
43 names, err := ExtractNames(r)
44 if err != nil {
45 return "", err
46 }
47 if len(names) == 0 {
48 return "", nil
49 }
50 return names[len(names)-1], nil
51}
52
53// ExtractInfo is a function that takes a ListResult and returns the containers' information.
54func ExtractInfo(page pagination.Page) ([]Container, error) {
55 untyped := page.(ContainerPage).Body.([]interface{})
56 results := make([]Container, len(untyped))
57 for index, each := range untyped {
Jon Perritt8aa40262014-09-29 15:41:32 -050058 container := each.(map[string]interface{})
Jon Perrittfdac6e52014-09-29 19:43:45 -050059 err := mapstructure.Decode(container, &results[index])
Jon Perritt8aa40262014-09-29 15:41:32 -050060 if err != nil {
61 return results, err
62 }
Jon Perritt8c93a302014-09-28 22:35:57 -050063 }
64 return results, nil
65}
66
67// ExtractNames is a function that takes a ListResult and returns the containers' names.
68func ExtractNames(page pagination.Page) ([]string, error) {
69 casted := page.(ContainerPage)
Ash Wilsonb8b16f82014-10-20 10:19:49 -040070 ct := casted.Headers.Get("Content-Type")
Jon Perritt8c93a302014-09-28 22:35:57 -050071
72 switch {
73 case strings.HasPrefix(ct, "application/json"):
74 parsed, err := ExtractInfo(page)
75 if err != nil {
76 return nil, err
77 }
78
79 names := make([]string, 0, len(parsed))
80 for _, container := range parsed {
Jon Perritt8aa40262014-09-29 15:41:32 -050081 names = append(names, container.Name)
Jon Perritt8c93a302014-09-28 22:35:57 -050082 }
83 return names, nil
84 case strings.HasPrefix(ct, "text/plain"):
85 names := make([]string, 0, 50)
86
87 body := string(page.(ContainerPage).Body.([]uint8))
88 for _, name := range strings.Split(body, "\n") {
89 if len(name) > 0 {
90 names = append(names, name)
91 }
92 }
93
94 return names, nil
95 default:
96 return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct)
97 }
98}
99
Jon Perritt5db08922014-09-30 21:32:48 -0500100// GetResult represents the result of a get operation.
101type GetResult struct {
Ash Wilsonaf262872014-10-20 09:32:29 -0400102 gophercloud.Result
Jon Perritt5db08922014-09-30 21:32:48 -0500103}
104
Jon Perritt8c93a302014-09-28 22:35:57 -0500105// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
106// and returns the custom metadata associated with the container.
107func (gr GetResult) ExtractMetadata() (map[string]string, error) {
108 if gr.Err != nil {
109 return nil, gr.Err
110 }
111 metadata := make(map[string]string)
Ash Wilsonaf262872014-10-20 09:32:29 -0400112 for k, v := range gr.Headers {
Jon Perritt8c93a302014-09-28 22:35:57 -0500113 if strings.HasPrefix(k, "X-Container-Meta-") {
114 key := strings.TrimPrefix(k, "X-Container-Meta-")
115 metadata[key] = v[0]
116 }
117 }
118 return metadata, nil
119}
Jon Perritt5db08922014-09-30 21:32:48 -0500120
Ash Wilsonaf262872014-10-20 09:32:29 -0400121type headerResult struct {
122 gophercloud.Result
123}
124
125// Extract pulls the unmodified headers from a Create, Update, or Delete result.
126func (result headerResult) Extract() (http.Header, error) {
127 return result.Headers, result.Err
128}
129
Jamie Hannaford22ec4792014-10-07 10:07:41 +0200130// CreateResult represents the result of a create operation. To extract the
131// the headers from the HTTP response, you can invoke the 'ExtractHeaders'
132// method on the result struct.
Jon Perritt5db08922014-09-30 21:32:48 -0500133type CreateResult struct {
Ash Wilsonaf262872014-10-20 09:32:29 -0400134 headerResult
Jon Perritt5db08922014-09-30 21:32:48 -0500135}
136
Jamie Hannaford22ec4792014-10-07 10:07:41 +0200137// UpdateResult represents the result of an update operation. To extract the
138// the headers from the HTTP response, you can invoke the 'ExtractHeaders'
139// method on the result struct.
Jon Perritt5db08922014-09-30 21:32:48 -0500140type UpdateResult struct {
Ash Wilsonaf262872014-10-20 09:32:29 -0400141 headerResult
Jon Perritt5db08922014-09-30 21:32:48 -0500142}
143
Jamie Hannaford22ec4792014-10-07 10:07:41 +0200144// DeleteResult represents the result of a delete operation. To extract the
145// the headers from the HTTP response, you can invoke the 'ExtractHeaders'
146// method on the result struct.
Jon Perritt5db08922014-09-30 21:32:48 -0500147type DeleteResult struct {
Ash Wilsonaf262872014-10-20 09:32:29 -0400148 headerResult
Jon Perritt5db08922014-09-30 21:32:48 -0500149}