blob: 80425bde8e68ba6ac14c349a71c897d278b6f617 [file] [log] [blame]
Jon Perritt8c93a302014-09-28 22:35:57 -05001package containers
2
3import (
4 "fmt"
Jon Perritt8c93a302014-09-28 22:35:57 -05005 "net/http"
6 "strings"
Jon Perritt5db08922014-09-30 21:32:48 -05007
8 "github.com/mitchellh/mapstructure"
9 "github.com/rackspace/gophercloud/pagination"
Jon Perritt8c93a302014-09-28 22:35:57 -050010)
11
Jon Perritt8aa40262014-09-29 15:41:32 -050012type Container struct {
Jon Perrittfdac6e52014-09-29 19:43:45 -050013 Bytes int `json:"bytes" mapstructure:"bytes"`
14 Count int `json:"count" mapstructure:"count"`
Jon Perritt5db08922014-09-30 21:32:48 -050015 Name string `json:"name" mapstructure:"name"`
Jon Perritt8aa40262014-09-29 15:41:32 -050016}
Jon Perritt8c93a302014-09-28 22:35:57 -050017
Jon Perritt8c93a302014-09-28 22:35:57 -050018// ListResult is a *http.Response that is returned from a call to the List function.
19type ContainerPage struct {
20 pagination.MarkerPageBase
21}
22
23// IsEmpty returns true if a ListResult contains no container names.
24func (r ContainerPage) IsEmpty() (bool, error) {
25 names, err := ExtractNames(r)
26 if err != nil {
27 return true, err
28 }
29 return len(names) == 0, nil
30}
31
32// LastMarker returns the last container name in a ListResult.
33func (r ContainerPage) LastMarker() (string, error) {
34 names, err := ExtractNames(r)
35 if err != nil {
36 return "", err
37 }
38 if len(names) == 0 {
39 return "", nil
40 }
41 return names[len(names)-1], nil
42}
43
44// ExtractInfo is a function that takes a ListResult and returns the containers' information.
45func ExtractInfo(page pagination.Page) ([]Container, error) {
46 untyped := page.(ContainerPage).Body.([]interface{})
47 results := make([]Container, len(untyped))
48 for index, each := range untyped {
Jon Perritt8aa40262014-09-29 15:41:32 -050049 container := each.(map[string]interface{})
Jon Perrittfdac6e52014-09-29 19:43:45 -050050 err := mapstructure.Decode(container, &results[index])
Jon Perritt8aa40262014-09-29 15:41:32 -050051 if err != nil {
52 return results, err
53 }
Jon Perritt8c93a302014-09-28 22:35:57 -050054 }
55 return results, nil
56}
57
58// ExtractNames is a function that takes a ListResult and returns the containers' names.
59func ExtractNames(page pagination.Page) ([]string, error) {
60 casted := page.(ContainerPage)
61 ct := casted.Header.Get("Content-Type")
62
63 switch {
64 case strings.HasPrefix(ct, "application/json"):
65 parsed, err := ExtractInfo(page)
66 if err != nil {
67 return nil, err
68 }
69
70 names := make([]string, 0, len(parsed))
71 for _, container := range parsed {
Jon Perritt8aa40262014-09-29 15:41:32 -050072 names = append(names, container.Name)
Jon Perritt8c93a302014-09-28 22:35:57 -050073 }
74 return names, nil
75 case strings.HasPrefix(ct, "text/plain"):
76 names := make([]string, 0, 50)
77
78 body := string(page.(ContainerPage).Body.([]uint8))
79 for _, name := range strings.Split(body, "\n") {
80 if len(name) > 0 {
81 names = append(names, name)
82 }
83 }
84
85 return names, nil
86 default:
87 return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct)
88 }
89}
90
Jon Perritt5db08922014-09-30 21:32:48 -050091// GetResult represents the result of a get operation.
92type GetResult struct {
93 Resp *http.Response
94 Err error
95}
96
Jon Perritt8c93a302014-09-28 22:35:57 -050097// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
98// and returns the custom metadata associated with the container.
99func (gr GetResult) ExtractMetadata() (map[string]string, error) {
100 if gr.Err != nil {
101 return nil, gr.Err
102 }
103 metadata := make(map[string]string)
104 for k, v := range gr.Resp.Header {
105 if strings.HasPrefix(k, "X-Container-Meta-") {
106 key := strings.TrimPrefix(k, "X-Container-Meta-")
107 metadata[key] = v[0]
108 }
109 }
110 return metadata, nil
111}
Jon Perritt5db08922014-09-30 21:32:48 -0500112
113type commonResult struct {
114 Resp *http.Response
115 Err error
116}
117
118func (cr commonResult) ExtractHeaders() (http.Header, error) {
119 var headers http.Header
120 if cr.Err != nil {
121 return headers, cr.Err
122 }
123
124 return cr.Resp.Header, nil
125}
126
127type CreateResult struct {
128 commonResult
129}
130
131type UpdateResult struct {
132 commonResult
133}
134
135type DeleteResult struct {
136 commonResult
137}