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 }