objectstorage v1 and orchestration v1 struct tags
diff --git a/openstack/objectstorage/v1/accounts/requests.go b/openstack/objectstorage/v1/accounts/requests.go
index f50cf97..41479a2 100644
--- a/openstack/objectstorage/v1/accounts/requests.go
+++ b/openstack/objectstorage/v1/accounts/requests.go
@@ -24,30 +24,27 @@
// all the headers that are returned (including the metadata), call the
// ExtractHeader method on the GetResult.
func Get(c *gophercloud.ServiceClient, opts GetOptsBuilder) GetResult {
- var res GetResult
- h := c.AuthenticatedHeaders()
-
+ var r GetResult
+ h := make(map[string]string)
if opts != nil {
headers, err := opts.ToAccountGetMap()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
-
for k, v := range headers {
h[k] = v
}
}
-
resp, err := c.Request("HEAD", getURL(c), &gophercloud.RequestOpts{
MoreHeaders: h,
OkCodes: []int{204},
})
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
// UpdateOptsBuilder allows extensions to add additional headers to the Update
@@ -81,27 +78,25 @@
// Update is a function that creates, updates, or deletes an account's metadata.
// To extract the headers returned, call the Extract method on the UpdateResult.
func Update(c *gophercloud.ServiceClient, opts UpdateOptsBuilder) UpdateResult {
- var res UpdateResult
+ var r UpdateResult
h := make(map[string]string)
-
if opts != nil {
headers, err := opts.ToAccountUpdateMap()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
for k, v := range headers {
h[k] = v
}
}
-
resp, err := c.Request("POST", updateURL(c), &gophercloud.RequestOpts{
MoreHeaders: h,
OkCodes: []int{201, 202, 204},
})
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
diff --git a/openstack/objectstorage/v1/containers/requests.go b/openstack/objectstorage/v1/containers/requests.go
index b2160c3..f575ea7 100644
--- a/openstack/objectstorage/v1/containers/requests.go
+++ b/openstack/objectstorage/v1/containers/requests.go
@@ -26,10 +26,7 @@
// representing whether to list complete information for each container.
func (opts ListOpts) ToContainerListParams() (bool, string, error) {
q, err := gophercloud.BuildQueryString(opts)
- if err != nil {
- return false, "", err
- }
- return opts.Full, q.String(), nil
+ return opts.Full, q.String(), err
}
// List is a function that retrieves containers associated with the account as
@@ -51,13 +48,11 @@
}
}
- createPage := func(r pagination.PageResult) pagination.Page {
+ pager := pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
p := ContainerPage{pagination.MarkerPageBase{PageResult: r}}
p.MarkerPageBase.Owner = p
return p
- }
-
- pager := pagination.NewPager(c, url, createPage)
+ })
pager.Headers = headers
return pager
}
@@ -95,37 +90,34 @@
// Create is a function that creates a new container.
func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsBuilder) CreateResult {
- var res CreateResult
- h := c.AuthenticatedHeaders()
-
+ var r CreateResult
+ h := make(map[string]string)
if opts != nil {
headers, err := opts.ToContainerCreateMap()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
-
for k, v := range headers {
h[k] = v
}
}
-
resp, err := c.Request("PUT", createURL(c, containerName), &gophercloud.RequestOpts{
MoreHeaders: h,
OkCodes: []int{201, 202, 204},
})
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
// Delete is a function that deletes a container.
func Delete(c *gophercloud.ServiceClient, containerName string) DeleteResult {
- var res DeleteResult
- _, res.Err = c.Delete(deleteURL(c, containerName), nil)
- return res
+ var r DeleteResult
+ _, r.Err = c.Delete(deleteURL(c, containerName), nil)
+ return r
}
// UpdateOptsBuilder allows extensions to add additional parameters to the
@@ -163,43 +155,41 @@
// Update is a function that creates, updates, or deletes a container's
// metadata.
func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsBuilder) UpdateResult {
- var res UpdateResult
- h := c.AuthenticatedHeaders()
-
+ var r UpdateResult
+ h := make(map[string]string)
if opts != nil {
headers, err := opts.ToContainerUpdateMap()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
for k, v := range headers {
h[k] = v
}
}
-
resp, err := c.Request("POST", updateURL(c, containerName), &gophercloud.RequestOpts{
MoreHeaders: h,
OkCodes: []int{201, 202, 204},
})
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
// Get is a function that retrieves the metadata of a container. To extract just
// the custom metadata, pass the GetResult response to the ExtractMetadata
// function.
func Get(c *gophercloud.ServiceClient, containerName string) GetResult {
- var res GetResult
+ var r GetResult
resp, err := c.Request("HEAD", getURL(c, containerName), &gophercloud.RequestOpts{
OkCodes: []int{200, 204},
})
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
diff --git a/openstack/objectstorage/v1/objects/requests.go b/openstack/objectstorage/v1/objects/requests.go
index d82aeb2..2505bdb 100644
--- a/openstack/objectstorage/v1/objects/requests.go
+++ b/openstack/objectstorage/v1/objects/requests.go
@@ -1,13 +1,12 @@
package objects
import (
- "bufio"
+ "bytes"
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"fmt"
"io"
- "io/ioutil"
"strings"
"time"
@@ -42,10 +41,7 @@
// representing whether to list complete information for each object.
func (opts ListOpts) ToObjectListParams() (bool, string, error) {
q, err := gophercloud.BuildQueryString(opts)
- if err != nil {
- return false, "", err
- }
- return opts.Full, q.String(), nil
+ return opts.Full, q.String(), err
}
// List is a function that retrieves all objects in a container. It also returns the details
@@ -67,13 +63,11 @@
}
}
- createPage := func(r pagination.PageResult) pagination.Page {
+ pager := pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
p := ObjectPage{pagination.MarkerPageBase{PageResult: r}}
p.MarkerPageBase.Owner = p
return p
- }
-
- pager := pagination.NewPager(c, url, createPage)
+ })
pager.Headers = headers
return pager
}
@@ -114,46 +108,42 @@
// To extract just the content, pass the DownloadResult response to the
// ExtractContent function.
func Download(c *gophercloud.ServiceClient, containerName, objectName string, opts DownloadOptsBuilder) DownloadResult {
- var res DownloadResult
-
+ var r DownloadResult
url := downloadURL(c, containerName, objectName)
- h := c.AuthenticatedHeaders()
-
+ h := make(map[string]string)
if opts != nil {
headers, query, err := opts.ToObjectDownloadParams()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
-
for k, v := range headers {
h[k] = v
}
-
url += query
}
- resp, err := c.Request("GET", url, &gophercloud.RequestOpts{
+ resp, err := c.Get(url, nil, &gophercloud.RequestOpts{
MoreHeaders: h,
OkCodes: []int{200, 304},
})
if resp != nil {
- res.Header = resp.Header
- res.Body = resp.Body
+ r.Header = resp.Header
+ r.Body = resp.Body
}
- res.Err = err
-
- return res
+ r.Err = err
+ return r
}
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
- ToObjectCreateParams() (map[string]string, string, error)
+ ToObjectCreateParams() (io.Reader, map[string]string, string, error)
}
// CreateOpts is a structure that holds parameters for creating an object.
type CreateOpts struct {
+ Content io.Reader
Metadata map[string]string
ContentDisposition string `h:"Content-Disposition"`
ContentEncoding string `h:"Content-Encoding"`
@@ -174,81 +164,61 @@
// ToObjectCreateParams formats a CreateOpts into a query string and map of
// headers.
-func (opts CreateOpts) ToObjectCreateParams() (map[string]string, string, error) {
+func (opts CreateOpts) ToObjectCreateParams() (io.Reader, map[string]string, string, error) {
q, err := gophercloud.BuildQueryString(opts)
if err != nil {
- return nil, "", err
+ return nil, nil, "", err
}
h, err := gophercloud.BuildHeaders(opts)
if err != nil {
- return nil, q.String(), err
+ return nil, nil, "", err
}
for k, v := range opts.Metadata {
h["X-Object-Meta-"+k] = v
}
- return h, q.String(), nil
+ hash := md5.New()
+ buf := bytes.NewBuffer([]byte{})
+ _, err = io.Copy(io.MultiWriter(hash, buf), opts.Content)
+ if err != nil {
+ return nil, nil, "", err
+ }
+ localChecksum := fmt.Sprintf("%x", hash.Sum(nil))
+ h["ETag"] = localChecksum
+
+ return buf, h, q.String(), nil
}
// Create is a function that creates a new object or replaces an existing object. If the returned response's ETag
// header fails to match the local checksum, the failed request will automatically be retried up to a maximum of 3 times.
-func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.ReadSeeker, opts CreateOptsBuilder) CreateResult {
- var res CreateResult
-
+func Create(c *gophercloud.ServiceClient, containerName, objectName string, opts CreateOptsBuilder) CreateResult {
+ var r CreateResult
url := createURL(c, containerName, objectName)
h := make(map[string]string)
-
+ var b io.Reader
if opts != nil {
- headers, query, err := opts.ToObjectCreateParams()
+ tmpB, headers, query, err := opts.ToObjectCreateParams()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
-
for k, v := range headers {
h[k] = v
}
-
url += query
+ b = tmpB
}
- hash := md5.New()
- bufioReader := bufio.NewReader(io.TeeReader(content, hash))
- io.Copy(ioutil.Discard, bufioReader)
- localChecksum := hash.Sum(nil)
-
- h["ETag"] = fmt.Sprintf("%x", localChecksum)
-
- _, err := content.Seek(0, 0)
- if err != nil {
- res.Err = err
- return res
- }
-
- ropts := &gophercloud.RequestOpts{
- RawBody: content,
+ resp, err := c.Put(url, nil, nil, &gophercloud.RequestOpts{
+ RawBody: b,
MoreHeaders: h,
- }
-
- resp, err := c.Request("PUT", url, ropts)
- if err != nil {
- res.Err = err
- return res
- }
+ })
+ r.Err = err
if resp != nil {
- res.Header = resp.Header
- if resp.Header.Get("ETag") == fmt.Sprintf("%x", localChecksum) {
- res.Err = err
- return res
- }
- err := ErrWrongChecksum{}
- err.Function = "objects.Create"
- res.Err = err
-
+ r.Header = resp.Header
}
-
- return res
+ return r
}
// CopyOptsBuilder allows extensions to add additional parameters to the
@@ -264,17 +234,11 @@
ContentDisposition string `h:"Content-Disposition"`
ContentEncoding string `h:"Content-Encoding"`
ContentType string `h:"Content-Type"`
- Destination string `h:"Destination,required"`
+ Destination string `h:"Destination" required:"true"`
}
// ToObjectCopyMap formats a CopyOpts into a map of headers.
func (opts CopyOpts) ToObjectCopyMap() (map[string]string, error) {
- if opts.Destination == "" {
- err := gophercloud.ErrMissingInput{}
- err.Function = "objects.ToObjectCopyMap"
- err.Argument = "objects.CopyOpts.Destination"
- return nil, err
- }
h, err := gophercloud.BuildHeaders(opts)
if err != nil {
return nil, err
@@ -287,13 +251,12 @@
// Copy is a function that copies one object to another.
func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts CopyOptsBuilder) CopyResult {
- var res CopyResult
- h := c.AuthenticatedHeaders()
-
+ var r CopyResult
+ h := make(map[string]string)
headers, err := opts.ToObjectCopyMap()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
for k, v := range headers {
@@ -306,10 +269,10 @@
OkCodes: []int{201},
})
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
// DeleteOptsBuilder allows extensions to add additional parameters to the
@@ -326,32 +289,27 @@
// ToObjectDeleteQuery formats a DeleteOpts into a query string.
func (opts DeleteOpts) ToObjectDeleteQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
- if err != nil {
- return "", err
- }
- return q.String(), nil
+ return q.String(), err
}
// Delete is a function that deletes an object.
func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts DeleteOptsBuilder) DeleteResult {
- var res DeleteResult
+ var r DeleteResult
url := deleteURL(c, containerName, objectName)
-
if opts != nil {
query, err := opts.ToObjectDeleteQuery()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
url += query
}
-
resp, err := c.Delete(url, nil)
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
// GetOptsBuilder allows extensions to add additional parameters to the
@@ -369,35 +327,30 @@
// ToObjectGetQuery formats a GetOpts into a query string.
func (opts GetOpts) ToObjectGetQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
- if err != nil {
- return "", err
- }
- return q.String(), nil
+ return q.String(), err
}
// Get is a function that retrieves the metadata of an object. To extract just the custom
// metadata, pass the GetResult response to the ExtractMetadata function.
func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts GetOptsBuilder) GetResult {
- var res GetResult
+ var r GetResult
url := getURL(c, containerName, objectName)
-
if opts != nil {
query, err := opts.ToObjectGetQuery()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
url += query
}
-
resp, err := c.Request("HEAD", url, &gophercloud.RequestOpts{
OkCodes: []int{200, 204},
})
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
// UpdateOptsBuilder allows extensions to add additional parameters to the
@@ -432,30 +385,28 @@
// Update is a function that creates, updates, or deletes an object's metadata.
func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts UpdateOptsBuilder) UpdateResult {
- var res UpdateResult
+ var r UpdateResult
h := c.AuthenticatedHeaders()
-
if opts != nil {
headers, err := opts.ToObjectUpdateMap()
if err != nil {
- res.Err = err
- return res
+ r.Err = err
+ return r
}
for k, v := range headers {
h[k] = v
}
}
-
url := updateURL(c, containerName, objectName)
- resp, err := c.Request("POST", url, &gophercloud.RequestOpts{
+ resp, err := c.Post(url, nil, nil, &gophercloud.RequestOpts{
MoreHeaders: h,
})
if resp != nil {
- res.Header = resp.Header
+ r.Header = resp.Header
}
- res.Err = err
- return res
+ r.Err = err
+ return r
}
// HTTPMethod represents an HTTP method string (e.g. "GET").
diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go
index c0d532b..3cfe1f4 100644
--- a/openstack/objectstorage/v1/objects/results.go
+++ b/openstack/objectstorage/v1/objects/results.go
@@ -200,12 +200,16 @@
// CreateResult represents the result of a create operation.
type CreateResult struct {
+ checksum string
gophercloud.HeaderResult
}
// Extract will return a struct of headers returned from a call to Create. To obtain
// a map of headers, call the ExtractHeader method on the CreateResult.
func (r CreateResult) Extract() (*CreateHeader, error) {
+ //if r.Header.Get("ETag") != fmt.Sprintf("%x", localChecksum) {
+ // return nil, ErrWrongChecksum{}
+ //}
var s *CreateHeader
err := r.ExtractInto(&s)
return s, err