github.com/gophercloud/gophercloud@v1.11.0/openstack/keymanager/v1/secrets/requests.go (about)

     1  package secrets
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/gophercloud/gophercloud"
    10  	"github.com/gophercloud/gophercloud/pagination"
    11  )
    12  
    13  // DateFilter represents a valid filter to use for filtering
    14  // secrets by their date during a list.
    15  type DateFilter string
    16  
    17  const (
    18  	DateFilterGT  DateFilter = "gt"
    19  	DateFilterGTE DateFilter = "gte"
    20  	DateFilterLT  DateFilter = "lt"
    21  	DateFilterLTE DateFilter = "lte"
    22  )
    23  
    24  // DateQuery represents a date field to be used for listing secrets.
    25  // If no filter is specified, the query will act as if "equal" is used.
    26  type DateQuery struct {
    27  	Date   time.Time
    28  	Filter DateFilter
    29  }
    30  
    31  // SecretType represents a valid secret type.
    32  type SecretType string
    33  
    34  const (
    35  	SymmetricSecret   SecretType = "symmetric"
    36  	PublicSecret      SecretType = "public"
    37  	PrivateSecret     SecretType = "private"
    38  	PassphraseSecret  SecretType = "passphrase"
    39  	CertificateSecret SecretType = "certificate"
    40  	OpaqueSecret      SecretType = "opaque"
    41  )
    42  
    43  // ListOptsBuilder allows extensions to add additional parameters to
    44  // the List request
    45  type ListOptsBuilder interface {
    46  	ToSecretListQuery() (string, error)
    47  }
    48  
    49  // ListOpts provides options to filter the List results.
    50  type ListOpts struct {
    51  	// Offset is the starting index within the total list of the secrets that
    52  	// you would like to retrieve.
    53  	Offset int `q:"offset"`
    54  
    55  	// Limit is the maximum number of records to return.
    56  	Limit int `q:"limit"`
    57  
    58  	// Name will select all secrets with a matching name.
    59  	Name string `q:"name"`
    60  
    61  	// Alg will select all secrets with a matching algorithm.
    62  	Alg string `q:"alg"`
    63  
    64  	// Mode will select all secrets with a matching mode.
    65  	Mode string `q:"mode"`
    66  
    67  	// Bits will select all secrets with a matching bit length.
    68  	Bits int `q:"bits"`
    69  
    70  	// SecretType will select all secrets with a matching secret type.
    71  	SecretType SecretType `q:"secret_type"`
    72  
    73  	// ACLOnly will select all secrets with an ACL that contains the user.
    74  	ACLOnly *bool `q:"acl_only"`
    75  
    76  	// CreatedQuery will select all secrets with a created date matching
    77  	// the query.
    78  	CreatedQuery *DateQuery
    79  
    80  	// UpdatedQuery will select all secrets with an updated date matching
    81  	// the query.
    82  	UpdatedQuery *DateQuery
    83  
    84  	// ExpirationQuery will select all secrets with an expiration date
    85  	// matching the query.
    86  	ExpirationQuery *DateQuery
    87  
    88  	// Sort will sort the results in the requested order.
    89  	Sort string `q:"sort"`
    90  }
    91  
    92  // ToSecretListQuery formats a ListOpts into a query string.
    93  func (opts ListOpts) ToSecretListQuery() (string, error) {
    94  	q, err := gophercloud.BuildQueryString(opts)
    95  	params := q.Query()
    96  
    97  	if opts.CreatedQuery != nil {
    98  		created := opts.CreatedQuery.Date.Format(time.RFC3339)
    99  		if v := opts.CreatedQuery.Filter; v != "" {
   100  			created = fmt.Sprintf("%s:%s", v, created)
   101  		}
   102  
   103  		params.Add("created", created)
   104  	}
   105  
   106  	if opts.UpdatedQuery != nil {
   107  		updated := opts.UpdatedQuery.Date.Format(time.RFC3339)
   108  		if v := opts.UpdatedQuery.Filter; v != "" {
   109  			updated = fmt.Sprintf("%s:%s", v, updated)
   110  		}
   111  
   112  		params.Add("updated", updated)
   113  	}
   114  
   115  	if opts.ExpirationQuery != nil {
   116  		expiration := opts.ExpirationQuery.Date.Format(time.RFC3339)
   117  		if v := opts.ExpirationQuery.Filter; v != "" {
   118  			expiration = fmt.Sprintf("%s:%s", v, expiration)
   119  		}
   120  
   121  		params.Add("expiration", expiration)
   122  	}
   123  
   124  	q = &url.URL{RawQuery: params.Encode()}
   125  
   126  	return q.String(), err
   127  }
   128  
   129  // List retrieves a list of Secrets.
   130  func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
   131  	url := listURL(client)
   132  	if opts != nil {
   133  		query, err := opts.ToSecretListQuery()
   134  		if err != nil {
   135  			return pagination.Pager{Err: err}
   136  		}
   137  		url += query
   138  	}
   139  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
   140  		return SecretPage{pagination.LinkedPageBase{PageResult: r}}
   141  	})
   142  }
   143  
   144  // Get retrieves details of a secrets.
   145  func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
   146  	resp, err := client.Get(getURL(client, id), &r.Body, nil)
   147  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   148  	return
   149  }
   150  
   151  // GetPayloadOpts represents options used for obtaining a payload.
   152  type GetPayloadOpts struct {
   153  	PayloadContentType string `h:"Accept"`
   154  }
   155  
   156  // GetPayloadOptsBuilder allows extensions to add additional parameters to
   157  // the GetPayload request.
   158  type GetPayloadOptsBuilder interface {
   159  	ToSecretPayloadGetParams() (map[string]string, error)
   160  }
   161  
   162  // ToSecretPayloadGetParams formats a GetPayloadOpts into a query string.
   163  func (opts GetPayloadOpts) ToSecretPayloadGetParams() (map[string]string, error) {
   164  	return gophercloud.BuildHeaders(opts)
   165  }
   166  
   167  // GetPayload retrieves the payload of a secret.
   168  func GetPayload(client *gophercloud.ServiceClient, id string, opts GetPayloadOptsBuilder) (r PayloadResult) {
   169  	h := map[string]string{"Accept": "text/plain"}
   170  
   171  	if opts != nil {
   172  		headers, err := opts.ToSecretPayloadGetParams()
   173  		if err != nil {
   174  			r.Err = err
   175  			return
   176  		}
   177  		for k, v := range headers {
   178  			h[k] = v
   179  		}
   180  	}
   181  
   182  	url := payloadURL(client, id)
   183  	resp, err := client.Get(url, nil, &gophercloud.RequestOpts{
   184  		MoreHeaders:      h,
   185  		OkCodes:          []int{200},
   186  		KeepResponseBody: true,
   187  	})
   188  	r.Body, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   189  	return
   190  }
   191  
   192  // CreateOptsBuilder allows extensions to add additional parameters to
   193  // the Create request.
   194  type CreateOptsBuilder interface {
   195  	ToSecretCreateMap() (map[string]interface{}, error)
   196  }
   197  
   198  // CreateOpts provides options used to create a secrets.
   199  type CreateOpts struct {
   200  	// Algorithm is the algorithm of the secret.
   201  	Algorithm string `json:"algorithm,omitempty"`
   202  
   203  	// BitLength is the bit length of the secret.
   204  	BitLength int `json:"bit_length,omitempty"`
   205  
   206  	// Mode is the mode of encryption for the secret.
   207  	Mode string `json:"mode,omitempty"`
   208  
   209  	// Name is the name of the secret
   210  	Name string `json:"name,omitempty"`
   211  
   212  	// Payload is the secret.
   213  	Payload string `json:"payload,omitempty"`
   214  
   215  	// PayloadContentType is the content type of the payload.
   216  	PayloadContentType string `json:"payload_content_type,omitempty"`
   217  
   218  	// PayloadContentEncoding is the content encoding of the payload.
   219  	PayloadContentEncoding string `json:"payload_content_encoding,omitempty"`
   220  
   221  	// SecretType is the type of secret.
   222  	SecretType SecretType `json:"secret_type,omitempty"`
   223  
   224  	// Expiration is the expiration date of the secret.
   225  	Expiration *time.Time `json:"-"`
   226  }
   227  
   228  // ToSecretCreateMap formats a CreateOpts into a create request.
   229  func (opts CreateOpts) ToSecretCreateMap() (map[string]interface{}, error) {
   230  	b, err := gophercloud.BuildRequestBody(opts, "")
   231  	if err != nil {
   232  		return nil, err
   233  	}
   234  
   235  	if opts.Expiration != nil {
   236  		b["expiration"] = opts.Expiration.Format(gophercloud.RFC3339NoZ)
   237  	}
   238  
   239  	return b, nil
   240  }
   241  
   242  // Create creates a new secrets.
   243  func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
   244  	b, err := opts.ToSecretCreateMap()
   245  	if err != nil {
   246  		r.Err = err
   247  		return
   248  	}
   249  	resp, err := client.Post(createURL(client), &b, &r.Body, &gophercloud.RequestOpts{
   250  		OkCodes: []int{201},
   251  	})
   252  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   253  	return
   254  }
   255  
   256  // Delete deletes a secrets.
   257  func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
   258  	resp, err := client.Delete(deleteURL(client, id), nil)
   259  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   260  	return
   261  }
   262  
   263  // UpdateOptsBuilder allows extensions to add additional parameters to
   264  // the Update request.
   265  type UpdateOptsBuilder interface {
   266  	ToSecretUpdateRequest() (string, map[string]string, error)
   267  }
   268  
   269  // UpdateOpts represents parameters to add a payload to an existing
   270  // secret which does not already contain a payload.
   271  type UpdateOpts struct {
   272  	// ContentType represents the content type of the payload.
   273  	ContentType string `h:"Content-Type"`
   274  
   275  	// ContentEncoding represents the content encoding of the payload.
   276  	ContentEncoding string `h:"Content-Encoding"`
   277  
   278  	// Payload is the payload of the secret.
   279  	Payload string
   280  }
   281  
   282  // ToUpdateCreateRequest formats a UpdateOpts into an update request.
   283  func (opts UpdateOpts) ToSecretUpdateRequest() (string, map[string]string, error) {
   284  	h, err := gophercloud.BuildHeaders(opts)
   285  	if err != nil {
   286  		return "", nil, err
   287  	}
   288  
   289  	return opts.Payload, h, nil
   290  }
   291  
   292  // Update modifies the attributes of a secrets.
   293  func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
   294  	url := updateURL(client, id)
   295  	h := make(map[string]string)
   296  	var b string
   297  
   298  	if opts != nil {
   299  		payload, headers, err := opts.ToSecretUpdateRequest()
   300  		if err != nil {
   301  			r.Err = err
   302  			return
   303  		}
   304  
   305  		for k, v := range headers {
   306  			h[k] = v
   307  		}
   308  
   309  		b = payload
   310  	}
   311  
   312  	resp, err := client.Put(url, strings.NewReader(b), nil, &gophercloud.RequestOpts{
   313  		MoreHeaders: h,
   314  		OkCodes:     []int{204},
   315  	})
   316  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   317  	return
   318  }
   319  
   320  // GetMetadata will list metadata for a given secret.
   321  func GetMetadata(client *gophercloud.ServiceClient, secretID string) (r MetadataResult) {
   322  	resp, err := client.Get(metadataURL(client, secretID), &r.Body, nil)
   323  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   324  	return
   325  }
   326  
   327  // MetadataOpts is a map that contains key-value pairs for secret metadata.
   328  type MetadataOpts map[string]string
   329  
   330  // CreateMetadataOptsBuilder allows extensions to add additional parameters to
   331  // the CreateMetadata request.
   332  type CreateMetadataOptsBuilder interface {
   333  	ToMetadataCreateMap() (map[string]interface{}, error)
   334  }
   335  
   336  // ToMetadataCreateMap converts a MetadataOpts into a request body.
   337  func (opts MetadataOpts) ToMetadataCreateMap() (map[string]interface{}, error) {
   338  	return map[string]interface{}{"metadata": opts}, nil
   339  }
   340  
   341  // CreateMetadata will set metadata for a given secret.
   342  func CreateMetadata(client *gophercloud.ServiceClient, secretID string, opts CreateMetadataOptsBuilder) (r MetadataCreateResult) {
   343  	b, err := opts.ToMetadataCreateMap()
   344  	if err != nil {
   345  		r.Err = err
   346  		return
   347  	}
   348  	resp, err := client.Put(metadataURL(client, secretID), b, &r.Body, &gophercloud.RequestOpts{
   349  		OkCodes: []int{201},
   350  	})
   351  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   352  	return
   353  }
   354  
   355  // GetMetadatum will get a single key/value metadata from a secret.
   356  func GetMetadatum(client *gophercloud.ServiceClient, secretID string, key string) (r MetadatumResult) {
   357  	resp, err := client.Get(metadatumURL(client, secretID, key), &r.Body, nil)
   358  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   359  	return
   360  }
   361  
   362  // MetadatumOpts represents a single metadata.
   363  type MetadatumOpts struct {
   364  	Key   string `json:"key" required:"true"`
   365  	Value string `json:"value" required:"true"`
   366  }
   367  
   368  // CreateMetadatumOptsBuilder allows extensions to add additional parameters to
   369  // the CreateMetadatum request.
   370  type CreateMetadatumOptsBuilder interface {
   371  	ToMetadatumCreateMap() (map[string]interface{}, error)
   372  }
   373  
   374  // ToMetadatumCreateMap converts a MetadatumOpts into a request body.
   375  func (opts MetadatumOpts) ToMetadatumCreateMap() (map[string]interface{}, error) {
   376  	return gophercloud.BuildRequestBody(opts, "")
   377  }
   378  
   379  // CreateMetadatum will add a single key/value metadata to a secret.
   380  func CreateMetadatum(client *gophercloud.ServiceClient, secretID string, opts CreateMetadatumOptsBuilder) (r MetadatumCreateResult) {
   381  	b, err := opts.ToMetadatumCreateMap()
   382  	if err != nil {
   383  		r.Err = err
   384  		return
   385  	}
   386  	resp, err := client.Post(metadataURL(client, secretID), b, &r.Body, &gophercloud.RequestOpts{
   387  		OkCodes: []int{201},
   388  	})
   389  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   390  	return
   391  }
   392  
   393  // UpdateMetadatumOptsBuilder allows extensions to add additional parameters to
   394  // the UpdateMetadatum request.
   395  type UpdateMetadatumOptsBuilder interface {
   396  	ToMetadatumUpdateMap() (map[string]interface{}, string, error)
   397  }
   398  
   399  // ToMetadatumUpdateMap converts a MetadataOpts into a request body.
   400  func (opts MetadatumOpts) ToMetadatumUpdateMap() (map[string]interface{}, string, error) {
   401  	b, err := gophercloud.BuildRequestBody(opts, "")
   402  	return b, opts.Key, err
   403  }
   404  
   405  // UpdateMetadatum will update a single key/value metadata to a secret.
   406  func UpdateMetadatum(client *gophercloud.ServiceClient, secretID string, opts UpdateMetadatumOptsBuilder) (r MetadatumResult) {
   407  	b, key, err := opts.ToMetadatumUpdateMap()
   408  	if err != nil {
   409  		r.Err = err
   410  		return
   411  	}
   412  	resp, err := client.Put(metadatumURL(client, secretID, key), b, &r.Body, &gophercloud.RequestOpts{
   413  		OkCodes: []int{200},
   414  	})
   415  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   416  	return
   417  }
   418  
   419  // DeleteMetadatum will delete an individual metadatum from a secret.
   420  func DeleteMetadatum(client *gophercloud.ServiceClient, secretID string, key string) (r MetadatumDeleteResult) {
   421  	resp, err := client.Delete(metadatumURL(client, secretID, key), nil)
   422  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   423  	return
   424  }