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  }