2015-03-12 00:46:25 +00:00
|
|
|
package api
|
|
|
|
|
2018-07-24 22:49:55 +00:00
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
2022-03-24 17:58:03 +00:00
|
|
|
"net/http"
|
2018-07-24 22:49:55 +00:00
|
|
|
)
|
2018-07-11 19:45:09 +00:00
|
|
|
|
2015-04-14 00:37:39 +00:00
|
|
|
func (c *Sys) Renew(id string, increment int) (*Secret, error) {
|
2022-03-23 21:47:43 +00:00
|
|
|
return c.RenewWithContext(context.Background(), id, increment)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Sys) RenewWithContext(ctx context.Context, id string, increment int) (*Secret, error) {
|
|
|
|
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
|
|
|
|
defer cancelFunc()
|
|
|
|
|
2022-03-24 17:58:03 +00:00
|
|
|
r := c.c.NewRequest(http.MethodPut, "/v1/sys/leases/renew")
|
2015-04-14 00:37:39 +00:00
|
|
|
|
2016-08-08 22:00:44 +00:00
|
|
|
body := map[string]interface{}{
|
|
|
|
"increment": increment,
|
|
|
|
"lease_id": id,
|
|
|
|
}
|
2015-04-14 00:37:39 +00:00
|
|
|
if err := r.SetJSONBody(body); err != nil {
|
2021-03-18 16:11:09 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-03-23 21:47:43 +00:00
|
|
|
resp, err := c.c.rawRequestWithContext(ctx, r)
|
2021-03-18 16:11:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
return ParseSecret(resp.Body)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Sys) Lookup(id string) (*Secret, error) {
|
2022-03-23 21:47:43 +00:00
|
|
|
return c.LookupWithContext(context.Background(), id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Sys) LookupWithContext(ctx context.Context, id string) (*Secret, error) {
|
|
|
|
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
|
|
|
|
defer cancelFunc()
|
|
|
|
|
2022-03-24 17:58:03 +00:00
|
|
|
r := c.c.NewRequest(http.MethodPut, "/v1/sys/leases/lookup")
|
2021-03-18 16:11:09 +00:00
|
|
|
|
|
|
|
body := map[string]interface{}{
|
|
|
|
"lease_id": id,
|
|
|
|
}
|
|
|
|
if err := r.SetJSONBody(body); err != nil {
|
2015-04-14 00:37:39 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-03-23 21:47:43 +00:00
|
|
|
resp, err := c.c.rawRequestWithContext(ctx, r)
|
2015-03-12 00:46:25 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
2015-03-12 00:47:47 +00:00
|
|
|
return ParseSecret(resp.Body)
|
2015-03-12 00:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Sys) Revoke(id string) error {
|
2022-03-23 21:47:43 +00:00
|
|
|
return c.RevokeWithContext(context.Background(), id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Sys) RevokeWithContext(ctx context.Context, id string) error {
|
|
|
|
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
|
|
|
|
defer cancelFunc()
|
|
|
|
|
2022-03-24 17:58:03 +00:00
|
|
|
r := c.c.NewRequest(http.MethodPut, "/v1/sys/leases/revoke")
|
2019-11-05 21:14:28 +00:00
|
|
|
body := map[string]interface{}{
|
|
|
|
"lease_id": id,
|
|
|
|
}
|
|
|
|
if err := r.SetJSONBody(body); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-07-24 22:49:55 +00:00
|
|
|
|
2022-03-23 21:47:43 +00:00
|
|
|
resp, err := c.c.rawRequestWithContext(ctx, r)
|
2015-04-01 02:21:02 +00:00
|
|
|
if err == nil {
|
|
|
|
defer resp.Body.Close()
|
|
|
|
}
|
2015-03-12 00:46:25 +00:00
|
|
|
return err
|
|
|
|
}
|
2015-04-01 02:23:52 +00:00
|
|
|
|
|
|
|
func (c *Sys) RevokePrefix(id string) error {
|
2022-03-23 21:47:43 +00:00
|
|
|
return c.RevokePrefixWithContext(context.Background(), id)
|
|
|
|
}
|
2018-07-24 22:49:55 +00:00
|
|
|
|
2022-03-23 21:47:43 +00:00
|
|
|
func (c *Sys) RevokePrefixWithContext(ctx context.Context, id string) error {
|
|
|
|
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
|
2018-07-24 22:49:55 +00:00
|
|
|
defer cancelFunc()
|
2022-03-23 21:47:43 +00:00
|
|
|
|
2022-03-24 17:58:03 +00:00
|
|
|
r := c.c.NewRequest(http.MethodPut, "/v1/sys/leases/revoke-prefix/"+id)
|
2022-03-23 21:47:43 +00:00
|
|
|
|
|
|
|
resp, err := c.c.rawRequestWithContext(ctx, r)
|
2015-04-01 02:23:52 +00:00
|
|
|
if err == nil {
|
|
|
|
defer resp.Body.Close()
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
Add forced revocation.
In some situations, it can be impossible to revoke leases (for instance,
if someone has gone and manually removed users created by Vault). This
can not only cause Vault to cycle trying to revoke them, but it also
prevents mounts from being unmounted, leaving them in a tainted state
where the only operations allowed are to revoke (or rollback), which
will never successfully complete.
This adds a new endpoint that works similarly to `revoke-prefix` but
ignores errors coming from a backend upon revocation (it does not ignore
errors coming from within the expiration manager, such as errors
accessing the data store). This can be used to force Vault to abandon
leases.
Like `revoke-prefix`, this is a very sensitive operation and requires
`sudo`. It is implemented as a separate endpoint, rather than an
argument to `revoke-prefix`, to ensure that control can be delegated
appropriately, as even most administrators should not normally have
this privilege.
Fixes #1135
2016-03-03 01:26:38 +00:00
|
|
|
|
|
|
|
func (c *Sys) RevokeForce(id string) error {
|
2022-03-23 21:47:43 +00:00
|
|
|
return c.RevokeForceWithContext(context.Background(), id)
|
|
|
|
}
|
2018-07-24 22:49:55 +00:00
|
|
|
|
2022-03-23 21:47:43 +00:00
|
|
|
func (c *Sys) RevokeForceWithContext(ctx context.Context, id string) error {
|
|
|
|
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
|
2018-07-24 22:49:55 +00:00
|
|
|
defer cancelFunc()
|
2022-03-23 21:47:43 +00:00
|
|
|
|
2022-03-24 17:58:03 +00:00
|
|
|
r := c.c.NewRequest(http.MethodPut, "/v1/sys/leases/revoke-force/"+id)
|
2022-03-23 21:47:43 +00:00
|
|
|
|
|
|
|
resp, err := c.c.rawRequestWithContext(ctx, r)
|
Add forced revocation.
In some situations, it can be impossible to revoke leases (for instance,
if someone has gone and manually removed users created by Vault). This
can not only cause Vault to cycle trying to revoke them, but it also
prevents mounts from being unmounted, leaving them in a tainted state
where the only operations allowed are to revoke (or rollback), which
will never successfully complete.
This adds a new endpoint that works similarly to `revoke-prefix` but
ignores errors coming from a backend upon revocation (it does not ignore
errors coming from within the expiration manager, such as errors
accessing the data store). This can be used to force Vault to abandon
leases.
Like `revoke-prefix`, this is a very sensitive operation and requires
`sudo`. It is implemented as a separate endpoint, rather than an
argument to `revoke-prefix`, to ensure that control can be delegated
appropriately, as even most administrators should not normally have
this privilege.
Fixes #1135
2016-03-03 01:26:38 +00:00
|
|
|
if err == nil {
|
|
|
|
defer resp.Body.Close()
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
2018-07-11 19:45:09 +00:00
|
|
|
|
|
|
|
func (c *Sys) RevokeWithOptions(opts *RevokeOptions) error {
|
2022-03-23 21:47:43 +00:00
|
|
|
return c.RevokeWithOptionsWithContext(context.Background(), opts)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Sys) RevokeWithOptionsWithContext(ctx context.Context, opts *RevokeOptions) error {
|
|
|
|
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
|
|
|
|
defer cancelFunc()
|
|
|
|
|
2018-07-11 19:45:09 +00:00
|
|
|
if opts == nil {
|
|
|
|
return errors.New("nil options provided")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Construct path
|
|
|
|
path := "/v1/sys/leases/revoke/"
|
|
|
|
switch {
|
|
|
|
case opts.Force:
|
|
|
|
path = "/v1/sys/leases/revoke-force/"
|
|
|
|
case opts.Prefix:
|
|
|
|
path = "/v1/sys/leases/revoke-prefix/"
|
|
|
|
}
|
|
|
|
path += opts.LeaseID
|
|
|
|
|
2022-03-24 17:58:03 +00:00
|
|
|
r := c.c.NewRequest(http.MethodPut, path)
|
2018-07-11 19:45:09 +00:00
|
|
|
if !opts.Force {
|
|
|
|
body := map[string]interface{}{
|
|
|
|
"sync": opts.Sync,
|
|
|
|
}
|
|
|
|
if err := r.SetJSONBody(body); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-23 21:47:43 +00:00
|
|
|
resp, err := c.c.rawRequestWithContext(ctx, r)
|
2018-07-11 19:45:09 +00:00
|
|
|
if err == nil {
|
|
|
|
defer resp.Body.Close()
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
type RevokeOptions struct {
|
|
|
|
LeaseID string
|
|
|
|
Force bool
|
|
|
|
Prefix bool
|
|
|
|
Sync bool
|
|
|
|
}
|