github.com/gophercloud/gophercloud@v1.11.0/openstack/objectstorage/v1/containers/requests.go (about) 1 package containers 2 3 import ( 4 "strings" 5 6 "github.com/gophercloud/gophercloud" 7 "github.com/gophercloud/gophercloud/pagination" 8 ) 9 10 // ListOptsBuilder allows extensions to add additional parameters to the List 11 // request. 12 type ListOptsBuilder interface { 13 ToContainerListParams() (bool, string, error) 14 } 15 16 // ListOpts is a structure that holds options for listing containers. 17 type ListOpts struct { 18 Full bool 19 Limit int `q:"limit"` 20 Marker string `q:"marker"` 21 EndMarker string `q:"end_marker"` 22 Format string `q:"format"` 23 Prefix string `q:"prefix"` 24 Delimiter string `q:"delimiter"` 25 } 26 27 // ToContainerListParams formats a ListOpts into a query string and boolean 28 // representing whether to list complete information for each container. 29 func (opts ListOpts) ToContainerListParams() (bool, string, error) { 30 q, err := gophercloud.BuildQueryString(opts) 31 return opts.Full, q.String(), err 32 } 33 34 // List is a function that retrieves containers associated with the account as 35 // well as account metadata. It returns a pager which can be iterated with the 36 // EachPage function. 37 func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { 38 headers := map[string]string{"Accept": "text/plain", "Content-Type": "text/plain"} 39 40 url := listURL(c) 41 if opts != nil { 42 full, query, err := opts.ToContainerListParams() 43 if err != nil { 44 return pagination.Pager{Err: err} 45 } 46 url += query 47 48 if full { 49 headers = map[string]string{"Accept": "application/json", "Content-Type": "application/json"} 50 } 51 } 52 53 pager := pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { 54 p := ContainerPage{pagination.MarkerPageBase{PageResult: r}} 55 p.MarkerPageBase.Owner = p 56 return p 57 }) 58 pager.Headers = headers 59 return pager 60 } 61 62 // CreateOptsBuilder allows extensions to add additional parameters to the 63 // Create request. 64 type CreateOptsBuilder interface { 65 ToContainerCreateMap() (map[string]string, error) 66 } 67 68 // CreateOpts is a structure that holds parameters for creating a container. 69 type CreateOpts struct { 70 Metadata map[string]string 71 ContainerRead string `h:"X-Container-Read"` 72 ContainerSyncTo string `h:"X-Container-Sync-To"` 73 ContainerSyncKey string `h:"X-Container-Sync-Key"` 74 ContainerWrite string `h:"X-Container-Write"` 75 ContentType string `h:"Content-Type"` 76 DetectContentType bool `h:"X-Detect-Content-Type"` 77 IfNoneMatch string `h:"If-None-Match"` 78 VersionsLocation string `h:"X-Versions-Location"` 79 HistoryLocation string `h:"X-History-Location"` 80 TempURLKey string `h:"X-Container-Meta-Temp-URL-Key"` 81 TempURLKey2 string `h:"X-Container-Meta-Temp-URL-Key-2"` 82 StoragePolicy string `h:"X-Storage-Policy"` 83 VersionsEnabled bool `h:"X-Versions-Enabled"` 84 } 85 86 // ToContainerCreateMap formats a CreateOpts into a map of headers. 87 func (opts CreateOpts) ToContainerCreateMap() (map[string]string, error) { 88 h, err := gophercloud.BuildHeaders(opts) 89 if err != nil { 90 return nil, err 91 } 92 for k, v := range opts.Metadata { 93 h["X-Container-Meta-"+k] = v 94 } 95 return h, nil 96 } 97 98 // Create is a function that creates a new container. 99 func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsBuilder) (r CreateResult) { 100 url, err := createURL(c, containerName) 101 if err != nil { 102 r.Err = err 103 return 104 } 105 h := make(map[string]string) 106 if opts != nil { 107 headers, err := opts.ToContainerCreateMap() 108 if err != nil { 109 r.Err = err 110 return 111 } 112 for k, v := range headers { 113 h[k] = v 114 } 115 } 116 resp, err := c.Request("PUT", url, &gophercloud.RequestOpts{ 117 MoreHeaders: h, 118 OkCodes: []int{201, 202, 204}, 119 }) 120 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 121 return 122 } 123 124 // BulkDelete is a function that bulk deletes containers. 125 func BulkDelete(c *gophercloud.ServiceClient, containers []string) (r BulkDeleteResult) { 126 // urlencode container names to be on the safe side 127 // https://github.com/openstack/swift/blob/stable/train/swift/common/middleware/bulk.py#L160 128 // https://github.com/openstack/swift/blob/stable/train/swift/common/swob.py#L302 129 encodedContainers := make([]string, len(containers)) 130 for i, v := range containers { 131 encodedContainers[i] = v 132 } 133 b := strings.NewReader(strings.Join(encodedContainers, "\n") + "\n") 134 resp, err := c.Post(bulkDeleteURL(c), b, &r.Body, &gophercloud.RequestOpts{ 135 MoreHeaders: map[string]string{ 136 "Accept": "application/json", 137 "Content-Type": "text/plain", 138 }, 139 OkCodes: []int{200}, 140 }) 141 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 142 return 143 } 144 145 // Delete is a function that deletes a container. 146 func Delete(c *gophercloud.ServiceClient, containerName string) (r DeleteResult) { 147 url, err := deleteURL(c, containerName) 148 if err != nil { 149 r.Err = err 150 return 151 } 152 resp, err := c.Delete(url, nil) 153 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 154 return 155 } 156 157 // UpdateOptsBuilder allows extensions to add additional parameters to the 158 // Update request. 159 type UpdateOptsBuilder interface { 160 ToContainerUpdateMap() (map[string]string, error) 161 } 162 163 // UpdateOpts is a structure that holds parameters for updating, creating, or 164 // deleting a container's metadata. 165 type UpdateOpts struct { 166 Metadata map[string]string 167 RemoveMetadata []string 168 ContainerRead *string `h:"X-Container-Read"` 169 ContainerSyncTo *string `h:"X-Container-Sync-To"` 170 ContainerSyncKey *string `h:"X-Container-Sync-Key"` 171 ContainerWrite *string `h:"X-Container-Write"` 172 ContentType *string `h:"Content-Type"` 173 DetectContentType *bool `h:"X-Detect-Content-Type"` 174 RemoveVersionsLocation string `h:"X-Remove-Versions-Location"` 175 VersionsLocation string `h:"X-Versions-Location"` 176 RemoveHistoryLocation string `h:"X-Remove-History-Location"` 177 HistoryLocation string `h:"X-History-Location"` 178 TempURLKey string `h:"X-Container-Meta-Temp-URL-Key"` 179 TempURLKey2 string `h:"X-Container-Meta-Temp-URL-Key-2"` 180 VersionsEnabled *bool `h:"X-Versions-Enabled"` 181 } 182 183 // ToContainerUpdateMap formats a UpdateOpts into a map of headers. 184 func (opts UpdateOpts) ToContainerUpdateMap() (map[string]string, error) { 185 h, err := gophercloud.BuildHeaders(opts) 186 if err != nil { 187 return nil, err 188 } 189 190 for k, v := range opts.Metadata { 191 h["X-Container-Meta-"+k] = v 192 } 193 194 for _, k := range opts.RemoveMetadata { 195 h["X-Remove-Container-Meta-"+k] = "remove" 196 } 197 198 return h, nil 199 } 200 201 // Update is a function that creates, updates, or deletes a container's 202 // metadata. 203 func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsBuilder) (r UpdateResult) { 204 url, err := updateURL(c, containerName) 205 if err != nil { 206 r.Err = err 207 return 208 } 209 h := make(map[string]string) 210 if opts != nil { 211 headers, err := opts.ToContainerUpdateMap() 212 if err != nil { 213 r.Err = err 214 return 215 } 216 217 for k, v := range headers { 218 h[k] = v 219 } 220 } 221 resp, err := c.Request("POST", url, &gophercloud.RequestOpts{ 222 MoreHeaders: h, 223 OkCodes: []int{201, 202, 204}, 224 }) 225 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 226 return 227 } 228 229 // GetOptsBuilder allows extensions to add additional parameters to the Get 230 // request. 231 type GetOptsBuilder interface { 232 ToContainerGetMap() (map[string]string, error) 233 } 234 235 // GetOpts is a structure that holds options for listing containers. 236 type GetOpts struct { 237 Newest bool `h:"X-Newest"` 238 } 239 240 // ToContainerGetMap formats a GetOpts into a map of headers. 241 func (opts GetOpts) ToContainerGetMap() (map[string]string, error) { 242 return gophercloud.BuildHeaders(opts) 243 } 244 245 // Get is a function that retrieves the metadata of a container. To extract just 246 // the custom metadata, pass the GetResult response to the ExtractMetadata 247 // function. 248 func Get(c *gophercloud.ServiceClient, containerName string, opts GetOptsBuilder) (r GetResult) { 249 url, err := getURL(c, containerName) 250 if err != nil { 251 r.Err = err 252 return 253 } 254 h := make(map[string]string) 255 if opts != nil { 256 headers, err := opts.ToContainerGetMap() 257 if err != nil { 258 r.Err = err 259 return 260 } 261 262 for k, v := range headers { 263 h[k] = v 264 } 265 } 266 resp, err := c.Head(url, &gophercloud.RequestOpts{ 267 MoreHeaders: h, 268 OkCodes: []int{200, 204}, 269 }) 270 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 271 return 272 }