aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/hashicorp/vault/api
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/vault/api')
-rw-r--r--vendor/github.com/hashicorp/vault/api/SPEC.md611
-rw-r--r--vendor/github.com/hashicorp/vault/api/auth.go11
-rw-r--r--vendor/github.com/hashicorp/vault/api/auth_token.go223
-rw-r--r--vendor/github.com/hashicorp/vault/api/client.go416
-rw-r--r--vendor/github.com/hashicorp/vault/api/help.go25
-rw-r--r--vendor/github.com/hashicorp/vault/api/logical.go176
-rw-r--r--vendor/github.com/hashicorp/vault/api/request.go71
-rw-r--r--vendor/github.com/hashicorp/vault/api/response.go72
-rw-r--r--vendor/github.com/hashicorp/vault/api/secret.go68
-rw-r--r--vendor/github.com/hashicorp/vault/api/ssh.go38
-rw-r--r--vendor/github.com/hashicorp/vault/api/ssh_agent.go257
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys.go11
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_audit.go114
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_auth.go87
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_capabilities.go43
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_generate_root.go77
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_init.go54
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_leader.go20
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_lease.go48
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_mounts.go142
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_policy.go95
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_rekey.go202
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_rotate.go30
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_seal.go59
-rw-r--r--vendor/github.com/hashicorp/vault/api/sys_stepdown.go10
25 files changed, 2960 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/vault/api/SPEC.md b/vendor/github.com/hashicorp/vault/api/SPEC.md
new file mode 100644
index 0000000..15345f3
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/SPEC.md
@@ -0,0 +1,611 @@
+FORMAT: 1A
+
+# vault
+
+The Vault API gives you full access to the Vault project.
+
+If you're browsing this API specifiction in GitHub or in raw
+format, please excuse some of the odd formatting. This document
+is in api-blueprint format that is read by viewers such as
+Apiary.
+
+## Sealed vs. Unsealed
+
+Whenever an individual Vault server is started, it is started
+in the _sealed_ state. In this state, it knows where its data
+is located, but the data is encrypted and Vault doesn't have the
+encryption keys to access it. Before Vault can operate, it must
+be _unsealed_.
+
+**Note:** Sealing/unsealing has no relationship to _authentication_
+which is separate and still required once the Vault is unsealed.
+
+Instead of being sealed with a single key, we utilize
+[Shamir's Secret Sharing](http://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing)
+to shard a key into _n_ parts such that _t_ parts are required
+to reconstruct the original key, where `t <= n`. This means that
+Vault itself doesn't know the original key, and no single person
+has the original key (unless `n = 1`, or `t` parts are given to
+a single person).
+
+Unsealing is done via an unauthenticated
+[unseal API](#reference/seal/unseal/unseal). This API takes a single
+master shard and progresses the unsealing process. Once all shards
+are given, the Vault is either unsealed or resets the unsealing
+process if the key was invalid.
+
+The entire seal/unseal state is server-wide. This allows multiple
+distinct operators to use the unseal API (or more likely the
+`vault unseal` command) from separate computers/networks and never
+have to transmit their key in order to unseal the vault in a
+distributed fashion.
+
+## Transport
+
+The API is expected to be accessed over a TLS connection at
+all times, with a valid certificate that is verified by a well
+behaved client.
+
+## Authentication
+
+Once the Vault is unsealed, every other operation requires
+authentication. There are multiple methods for authentication
+that can be enabled (see
+[authentication](#reference/authentication)).
+
+Authentication is done with the login endpoint. The login endpoint
+returns an access token that is set as the `X-Vault-Token` header.
+
+## Help
+
+To retrieve the help for any API within Vault, including mounted
+backends, credential providers, etc. then append `?help=1` to any
+URL. If you have valid permission to access the path, then the help text
+will be returned with the following structure:
+
+ {
+ "help": "help text"
+ }
+
+## Error Response
+
+A common JSON structure is always returned to return errors:
+
+ {
+ "errors": [
+ "message",
+ "another message"
+ ]
+ }
+
+This structure will be sent down for any non-20x HTTP status.
+
+## HTTP Status Codes
+
+The following HTTP status codes are used throughout the API.
+
+- `200` - Success with data.
+- `204` - Success, no data returned.
+- `400` - Invalid request, missing or invalid data.
+- `403` - Forbidden, your authentication details are either
+ incorrect or you don't have access to this feature.
+- `404` - Invalid path. This can both mean that the path truly
+ doesn't exist or that you don't have permission to view a
+ specific path. We use 404 in some cases to avoid state leakage.
+- `429` - Rate limit exceeded. Try again after waiting some period
+ of time.
+- `500` - Internal server error. An internal error has occurred,
+ try again later. If the error persists, report a bug.
+- `503` - Vault is down for maintenance or is currently sealed.
+ Try again later.
+
+# Group Initialization
+
+## Initialization [/sys/init]
+### Initialization Status [GET]
+Returns the status of whether the vault is initialized or not. The
+vault doesn't have to be unsealed for this operation.
+
++ Response 200 (application/json)
+
+ {
+ "initialized": true
+ }
+
+### Initialize [POST]
+Initialize the vault. This is an unauthenticated request to initially
+setup a new vault. Although this is unauthenticated, it is still safe:
+data cannot be in vault prior to initialization, and any future
+authentication will fail if you didn't initialize it yourself.
+Additionally, once initialized, a vault cannot be reinitialized.
+
+This API is the only time Vault will ever be aware of your keys, and
+the only time the keys will ever be returned in one unit. Care should
+be taken to ensure that the output of this request is never logged,
+and that the keys are properly distributed.
+
+The response also contains the initial root token that can be used
+as authentication in order to initially configure Vault once it is
+unsealed. Just as with the unseal keys, this is the only time Vault is
+ever aware of this token.
+
++ Request (application/json)
+
+ {
+ "secret_shares": 5,
+ "secret_threshold": 3,
+ }
+
++ Response 200 (application/json)
+
+ {
+ "keys": ["one", "two", "three"],
+ "root_token": "foo"
+ }
+
+# Group Seal/Unseal
+
+## Seal Status [/sys/seal-status]
+### Seal Status [GET]
+Returns the status of whether the vault is currently
+sealed or not, as well as the progress of unsealing.
+
+The response has the following attributes:
+
+- sealed (boolean) - If true, the vault is sealed. Otherwise,
+ it is unsealed.
+- t (int) - The "t" value for the master key, or the number
+ of shards needed total to unseal the vault.
+- n (int) - The "n" value for the master key, or the total
+ number of shards of the key distributed.
+- progress (int) - The number of master key shards that have
+ been entered so far towards unsealing the vault.
+
++ Response 200 (application/json)
+
+ {
+ "sealed": true,
+ "t": 3,
+ "n": 5,
+ "progress": 1
+ }
+
+## Seal [/sys/seal]
+### Seal [PUT]
+Seal the vault.
+
+Sealing the vault locks Vault from any future operations on any
+secrets or system configuration until the vault is once again
+unsealed. Internally, sealing throws away the keys to access the
+encrypted vault data, so Vault is unable to access the data without
+unsealing to get the encryption keys.
+
++ Response 204
+
+## Unseal [/sys/unseal]
+### Unseal [PUT]
+Unseal the vault.
+
+Unseal the vault by entering a portion of the master key. The
+response object will tell you if the unseal is complete or
+only partial.
+
+If the vault is already unsealed, this does nothing. It is
+not an error, the return value just says the vault is unsealed.
+Due to the architecture of Vault, we cannot validate whether
+any portion of the unseal key given is valid until all keys
+are inputted, therefore unsealing an already unsealed vault
+is still a success even if the input key is invalid.
+
++ Request (application/json)
+
+ {
+ "key": "value"
+ }
+
++ Response 200 (application/json)
+
+ {
+ "sealed": true,
+ "t": 3,
+ "n": 5,
+ "progress": 1
+ }
+
+# Group Authentication
+
+## List Auth Methods [/sys/auth]
+### List all auth methods [GET]
+Lists all available authentication methods.
+
+This returns the name of the authentication method as well as
+a human-friendly long-form help text for the method that can be
+shown to the user as documentation.
+
++ Response 200 (application/json)
+
+ {
+ "token": {
+ "type": "token",
+ "description": "Token authentication"
+ },
+ "oauth": {
+ "type": "oauth",
+ "description": "OAuth authentication"
+ }
+ }
+
+## Single Auth Method [/sys/auth/{id}]
+
++ Parameters
+ + id (required, string) ... The ID of the auth method.
+
+### Enable an auth method [PUT]
+Enables an authentication method.
+
+The body of the request depends on the authentication method
+being used. Please reference the documentation for the specific
+authentication method you're enabling in order to determine what
+parameters you must give it.
+
+If an authentication method is already enabled, then this can be
+used to change the configuration, including even the type of
+the configuration.
+
++ Request (application/json)
+
+ {
+ "type": "type",
+ "key": "value",
+ "key2": "value2"
+ }
+
++ Response 204
+
+### Disable an auth method [DELETE]
+Disables an authentication method. Previously authenticated sessions
+are immediately invalidated.
+
++ Response 204
+
+# Group Policies
+
+Policies are named permission sets that identities returned by
+credential stores are bound to. This separates _authentication_
+from _authorization_.
+
+## Policies [/sys/policy]
+### List all Policies [GET]
+
+List all the policies.
+
++ Response 200 (application/json)
+
+ {
+ "policies": ["root"]
+ }
+
+## Single Policy [/sys/policy/{id}]
+
++ Parameters
+ + id (required, string) ... The name of the policy
+
+### Upsert [PUT]
+
+Create or update a policy with the given ID.
+
++ Request (application/json)
+
+ {
+ "rules": "HCL"
+ }
+
++ Response 204
+
+### Delete [DELETE]
+
+Delete a policy with the given ID. Any identities bound to this
+policy will immediately become "deny all" despite already being
+authenticated.
+
++ Response 204
+
+# Group Mounts
+
+Logical backends are mounted at _mount points_, similar to
+filesystems. This allows you to mount the "aws" logical backend
+at the "aws-us-east" path, so all access is at `/aws-us-east/keys/foo`
+for example. This enables multiple logical backends to be enabled.
+
+## Mounts [/sys/mounts]
+### List all mounts [GET]
+
+Lists all the active mount points.
+
++ Response 200 (application/json)
+
+ {
+ "aws": {
+ "type": "aws",
+ "description": "AWS"
+ },
+ "pg": {
+ "type": "postgresql",
+ "description": "PostgreSQL dynamic users"
+ }
+ }
+
+## Single Mount [/sys/mounts/{path}]
+### New Mount [POST]
+
+Mount a logical backend to a new path.
+
+Configuration for this new backend is done via the normal
+read/write mechanism once it is mounted.
+
++ Request (application/json)
+
+ {
+ "type": "aws",
+ "description": "EU AWS tokens"
+ }
+
++ Response 204
+
+### Unmount [DELETE]
+
+Unmount a mount point.
+
++ Response 204
+
+## Remount [/sys/remount]
+### Remount [POST]
+
+Move an already-mounted backend to a new path.
+
++ Request (application/json)
+
+ {
+ "from": "aws",
+ "to": "aws-east"
+ }
+
++ Response 204
+
+# Group Audit Backends
+
+Audit backends are responsible for shuttling the audit logs that
+Vault generates to a durable system for future querying. By default,
+audit logs are not stored anywhere.
+
+## Audit Backends [/sys/audit]
+### List Enabled Audit Backends [GET]
+
+List all the enabled audit backends
+
++ Response 200 (application/json)
+
+ {
+ "file": {
+ "type": "file",
+ "description": "Send audit logs to a file",
+ "options": {}
+ }
+ }
+
+## Single Audit Backend [/sys/audit/{path}]
+
++ Parameters
+ + path (required, string) ... The path where the audit backend is mounted
+
+### Enable [PUT]
+
+Enable an audit backend.
+
++ Request (application/json)
+
+ {
+ "type": "file",
+ "description": "send to a file",
+ "options": {
+ "path": "/var/log/vault.audit.log"
+ }
+ }
+
++ Response 204
+
+### Disable [DELETE]
+
+Disable an audit backend.
+
++ Request (application/json)
+
++ Response 204
+
+# Group Secrets
+
+## Generic [/{mount}/{path}]
+
+This group documents the general format of reading and writing
+to Vault. The exact structure of the keyspace is defined by the
+logical backends in use, so documentation related to
+a specific backend should be referenced for details on what keys
+and routes are expected.
+
+The path for examples are `/prefix/path`, but in practice
+these will be defined by the backends that are mounted. For
+example, reading an AWS key might be at the `/aws/root` path.
+These paths are defined by the logical backends.
+
++ Parameters
+ + mount (required, string) ... The mount point for the
+ logical backend. Example: `aws`.
+ + path (optional, string) ... The path within the backend
+ to read or write data.
+
+### Read [GET]
+
+Read data from vault.
+
+The data read from the vault can either be a secret or
+arbitrary configuration data. The type of data returned
+depends on the path, and is defined by the logical backend.
+
+If the return value is a secret, then the return structure
+is a mixture of arbitrary key/value along with the following
+fields which are guaranteed to exist:
+
+- `lease_id` (string) - A unique ID used for renewal and
+ revocation.
+
+- `renewable` (bool) - If true, then this key can be renewed.
+ If a key can't be renewed, then a new key must be requested
+ after the lease duration period.
+
+- `lease_duration` (int) - The time in seconds that a secret is
+ valid for before it must be renewed.
+
+- `lease_duration_max` (int) - The maximum amount of time in
+ seconds that a secret is valid for. This will always be
+ greater than or equal to `lease_duration`. The difference
+ between this and `lease_duration` is an overlap window
+ where multiple keys may be valid.
+
+If the return value is not a secret, then the return structure
+is an arbitrary JSON object.
+
++ Response 200 (application/json)
+
+ {
+ "lease_id": "UUID",
+ "lease_duration": 3600,
+ "key": "value"
+ }
+
+### Write [PUT]
+
+Write data to vault.
+
+The behavior and arguments to the write are defined by
+the logical backend.
+
++ Request (application/json)
+
+ {
+ "key": "value"
+ }
+
++ Response 204
+
+# Group Lease Management
+
+## Renew Key [/sys/renew/{id}]
+
++ Parameters
+ + id (required, string) ... The `lease_id` of the secret
+ to renew.
+
+### Renew [PUT]
+
++ Response 200 (application/json)
+
+ {
+ "lease_id": "...",
+ "lease_duration": 3600,
+ "access_key": "foo",
+ "secret_key": "bar"
+ }
+
+## Revoke Key [/sys/revoke/{id}]
+
++ Parameters
+ + id (required, string) ... The `lease_id` of the secret
+ to revoke.
+
+### Revoke [PUT]
+
++ Response 204
+
+# Group Backend: AWS
+
+## Root Key [/aws/root]
+### Set the Key [PUT]
+
+Set the root key that the logical backend will use to create
+new secrets, IAM policies, etc.
+
++ Request (application/json)
+
+ {
+ "access_key": "key",
+ "secret_key": "key",
+ "region": "us-east-1"
+ }
+
++ Response 204
+
+## Policies [/aws/policies]
+### List Policies [GET]
+
+List all the policies that can be used to create keys.
+
++ Response 200 (application/json)
+
+ [{
+ "name": "root",
+ "description": "Root access"
+ }, {
+ "name": "web-deploy",
+ "description": "Enough permissions to deploy the web app."
+ }]
+
+## Single Policy [/aws/policies/{name}]
+
++ Parameters
+ + name (required, string) ... Name of the policy.
+
+### Read [GET]
+
+Read a policy.
+
++ Response 200 (application/json)
+
+ {
+ "policy": "base64-encoded policy"
+ }
+
+### Upsert [PUT]
+
+Create or update a policy.
+
++ Request (application/json)
+
+ {
+ "policy": "base64-encoded policy"
+ }
+
++ Response 204
+
+### Delete [DELETE]
+
+Delete the policy with the given name.
+
++ Response 204
+
+## Generate Access Keys [/aws/keys/{policy}]
+### Create [GET]
+
+This generates a new keypair for the given policy.
+
++ Parameters
+ + policy (required, string) ... The policy under which to create
+ the key pair.
+
++ Response 200 (application/json)
+
+ {
+ "lease_id": "...",
+ "lease_duration": 3600,
+ "access_key": "foo",
+ "secret_key": "bar"
+ }
diff --git a/vendor/github.com/hashicorp/vault/api/auth.go b/vendor/github.com/hashicorp/vault/api/auth.go
new file mode 100644
index 0000000..da870c1
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/auth.go
@@ -0,0 +1,11 @@
+package api
+
+// Auth is used to perform credential backend related operations.
+type Auth struct {
+ c *Client
+}
+
+// Auth is used to return the client for credential-backend API calls.
+func (c *Client) Auth() *Auth {
+ return &Auth{c: c}
+}
diff --git a/vendor/github.com/hashicorp/vault/api/auth_token.go b/vendor/github.com/hashicorp/vault/api/auth_token.go
new file mode 100644
index 0000000..aff10f4
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/auth_token.go
@@ -0,0 +1,223 @@
+package api
+
+// TokenAuth is used to perform token backend operations on Vault
+type TokenAuth struct {
+ c *Client
+}
+
+// Token is used to return the client for token-backend API calls
+func (a *Auth) Token() *TokenAuth {
+ return &TokenAuth{c: a.c}
+}
+
+func (c *TokenAuth) Create(opts *TokenCreateRequest) (*Secret, error) {
+ r := c.c.NewRequest("POST", "/v1/auth/token/create")
+ if err := r.SetJSONBody(opts); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *TokenAuth) CreateOrphan(opts *TokenCreateRequest) (*Secret, error) {
+ r := c.c.NewRequest("POST", "/v1/auth/token/create-orphan")
+ if err := r.SetJSONBody(opts); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *TokenAuth) CreateWithRole(opts *TokenCreateRequest, roleName string) (*Secret, error) {
+ r := c.c.NewRequest("POST", "/v1/auth/token/create/"+roleName)
+ if err := r.SetJSONBody(opts); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *TokenAuth) Lookup(token string) (*Secret, error) {
+ r := c.c.NewRequest("POST", "/v1/auth/token/lookup")
+ if err := r.SetJSONBody(map[string]interface{}{
+ "token": token,
+ }); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *TokenAuth) LookupAccessor(accessor string) (*Secret, error) {
+ r := c.c.NewRequest("POST", "/v1/auth/token/lookup-accessor")
+ if err := r.SetJSONBody(map[string]interface{}{
+ "accessor": accessor,
+ }); err != nil {
+ return nil, err
+ }
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *TokenAuth) LookupSelf() (*Secret, error) {
+ r := c.c.NewRequest("GET", "/v1/auth/token/lookup-self")
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *TokenAuth) Renew(token string, increment int) (*Secret, error) {
+ r := c.c.NewRequest("PUT", "/v1/auth/token/renew")
+ if err := r.SetJSONBody(map[string]interface{}{
+ "token": token,
+ "increment": increment,
+ }); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *TokenAuth) RenewSelf(increment int) (*Secret, error) {
+ r := c.c.NewRequest("PUT", "/v1/auth/token/renew-self")
+
+ body := map[string]interface{}{"increment": increment}
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+// RevokeAccessor revokes a token associated with the given accessor
+// along with all the child tokens.
+func (c *TokenAuth) RevokeAccessor(accessor string) error {
+ r := c.c.NewRequest("POST", "/v1/auth/token/revoke-accessor")
+ if err := r.SetJSONBody(map[string]interface{}{
+ "accessor": accessor,
+ }); err != nil {
+ return err
+ }
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
+}
+
+// RevokeOrphan revokes a token without revoking the tree underneath it (so
+// child tokens are orphaned rather than revoked)
+func (c *TokenAuth) RevokeOrphan(token string) error {
+ r := c.c.NewRequest("PUT", "/v1/auth/token/revoke-orphan")
+ if err := r.SetJSONBody(map[string]interface{}{
+ "token": token,
+ }); err != nil {
+ return err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
+}
+
+// RevokeSelf revokes the token making the call. The `token` parameter is kept
+// for backwards compatibility but is ignored; only the client's set token has
+// an effect.
+func (c *TokenAuth) RevokeSelf(token string) error {
+ r := c.c.NewRequest("PUT", "/v1/auth/token/revoke-self")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
+}
+
+// RevokeTree is the "normal" revoke operation that revokes the given token and
+// the entire tree underneath -- all of its child tokens, their child tokens,
+// etc.
+func (c *TokenAuth) RevokeTree(token string) error {
+ r := c.c.NewRequest("PUT", "/v1/auth/token/revoke")
+ if err := r.SetJSONBody(map[string]interface{}{
+ "token": token,
+ }); err != nil {
+ return err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
+}
+
+// TokenCreateRequest is the options structure for creating a token.
+type TokenCreateRequest struct {
+ ID string `json:"id,omitempty"`
+ Policies []string `json:"policies,omitempty"`
+ Metadata map[string]string `json:"meta,omitempty"`
+ Lease string `json:"lease,omitempty"`
+ TTL string `json:"ttl,omitempty"`
+ ExplicitMaxTTL string `json:"explicit_max_ttl,omitempty"`
+ Period string `json:"period,omitempty"`
+ NoParent bool `json:"no_parent,omitempty"`
+ NoDefaultPolicy bool `json:"no_default_policy,omitempty"`
+ DisplayName string `json:"display_name"`
+ NumUses int `json:"num_uses"`
+ Renewable *bool `json:"renewable,omitempty"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/client.go b/vendor/github.com/hashicorp/vault/api/client.go
new file mode 100644
index 0000000..4aee40c
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/client.go
@@ -0,0 +1,416 @@
+package api
+
+import (
+ "crypto/tls"
+ "fmt"
+ "net/http"
+ "net/url"
+ "os"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/hashicorp/go-cleanhttp"
+ "github.com/hashicorp/go-rootcerts"
+ "github.com/sethgrid/pester"
+)
+
+const EnvVaultAddress = "VAULT_ADDR"
+const EnvVaultCACert = "VAULT_CACERT"
+const EnvVaultCAPath = "VAULT_CAPATH"
+const EnvVaultClientCert = "VAULT_CLIENT_CERT"
+const EnvVaultClientKey = "VAULT_CLIENT_KEY"
+const EnvVaultInsecure = "VAULT_SKIP_VERIFY"
+const EnvVaultTLSServerName = "VAULT_TLS_SERVER_NAME"
+const EnvVaultWrapTTL = "VAULT_WRAP_TTL"
+const EnvVaultMaxRetries = "VAULT_MAX_RETRIES"
+
+// WrappingLookupFunc is a function that, given an HTTP verb and a path,
+// returns an optional string duration to be used for response wrapping (e.g.
+// "15s", or simply "15"). The path will not begin with "/v1/" or "v1/" or "/",
+// however, end-of-path forward slashes are not trimmed, so must match your
+// called path precisely.
+type WrappingLookupFunc func(operation, path string) string
+
+// Config is used to configure the creation of the client.
+type Config struct {
+ // Address is the address of the Vault server. This should be a complete
+ // URL such as "http://vault.example.com". If you need a custom SSL
+ // cert or want to enable insecure mode, you need to specify a custom
+ // HttpClient.
+ Address string
+
+ // HttpClient is the HTTP client to use, which will currently always have the
+ // same values as http.DefaultClient. This is used to control redirect behavior.
+ HttpClient *http.Client
+
+ redirectSetup sync.Once
+
+ // MaxRetries controls the maximum number of times to retry when a 5xx error
+ // occurs. Set to 0 or less to disable retrying.
+ MaxRetries int
+}
+
+// TLSConfig contains the parameters needed to configure TLS on the HTTP client
+// used to communicate with Vault.
+type TLSConfig struct {
+ // CACert is the path to a PEM-encoded CA cert file to use to verify the
+ // Vault server SSL certificate.
+ CACert string
+
+ // CAPath is the path to a directory of PEM-encoded CA cert files to verify
+ // the Vault server SSL certificate.
+ CAPath string
+
+ // ClientCert is the path to the certificate for Vault communication
+ ClientCert string
+
+ // ClientKey is the path to the private key for Vault communication
+ ClientKey string
+
+ // TLSServerName, if set, is used to set the SNI host when connecting via
+ // TLS.
+ TLSServerName string
+
+ // Insecure enables or disables SSL verification
+ Insecure bool
+}
+
+// DefaultConfig returns a default configuration for the client. It is
+// safe to modify the return value of this function.
+//
+// The default Address is https://127.0.0.1:8200, but this can be overridden by
+// setting the `VAULT_ADDR` environment variable.
+func DefaultConfig() *Config {
+ config := &Config{
+ Address: "https://127.0.0.1:8200",
+
+ HttpClient: cleanhttp.DefaultClient(),
+ }
+ config.HttpClient.Timeout = time.Second * 60
+ transport := config.HttpClient.Transport.(*http.Transport)
+ transport.TLSHandshakeTimeout = 10 * time.Second
+ transport.TLSClientConfig = &tls.Config{
+ MinVersion: tls.VersionTLS12,
+ }
+
+ if v := os.Getenv(EnvVaultAddress); v != "" {
+ config.Address = v
+ }
+
+ config.MaxRetries = pester.DefaultClient.MaxRetries
+
+ return config
+}
+
+// ConfigureTLS takes a set of TLS configurations and applies those to the the HTTP client.
+func (c *Config) ConfigureTLS(t *TLSConfig) error {
+
+ if c.HttpClient == nil {
+ return fmt.Errorf("config HTTP Client must be set")
+ }
+
+ var clientCert tls.Certificate
+ foundClientCert := false
+ if t.CACert != "" || t.CAPath != "" || t.ClientCert != "" || t.ClientKey != "" || t.Insecure {
+ if t.ClientCert != "" && t.ClientKey != "" {
+ var err error
+ clientCert, err = tls.LoadX509KeyPair(t.ClientCert, t.ClientKey)
+ if err != nil {
+ return err
+ }
+ foundClientCert = true
+ } else if t.ClientCert != "" || t.ClientKey != "" {
+ return fmt.Errorf("Both client cert and client key must be provided")
+ }
+ }
+
+ clientTLSConfig := c.HttpClient.Transport.(*http.Transport).TLSClientConfig
+ rootConfig := &rootcerts.Config{
+ CAFile: t.CACert,
+ CAPath: t.CAPath,
+ }
+ if err := rootcerts.ConfigureTLS(clientTLSConfig, rootConfig); err != nil {
+ return err
+ }
+
+ clientTLSConfig.InsecureSkipVerify = t.Insecure
+
+ if foundClientCert {
+ clientTLSConfig.Certificates = []tls.Certificate{clientCert}
+ }
+ if t.TLSServerName != "" {
+ clientTLSConfig.ServerName = t.TLSServerName
+ }
+
+ return nil
+}
+
+// ReadEnvironment reads configuration information from the
+// environment. If there is an error, no configuration value
+// is updated.
+func (c *Config) ReadEnvironment() error {
+ var envAddress string
+ var envCACert string
+ var envCAPath string
+ var envClientCert string
+ var envClientKey string
+ var envInsecure bool
+ var envTLSServerName string
+ var envMaxRetries *uint64
+
+ // Parse the environment variables
+ if v := os.Getenv(EnvVaultAddress); v != "" {
+ envAddress = v
+ }
+ if v := os.Getenv(EnvVaultMaxRetries); v != "" {
+ maxRetries, err := strconv.ParseUint(v, 10, 32)
+ if err != nil {
+ return err
+ }
+ envMaxRetries = &maxRetries
+ }
+ if v := os.Getenv(EnvVaultCACert); v != "" {
+ envCACert = v
+ }
+ if v := os.Getenv(EnvVaultCAPath); v != "" {
+ envCAPath = v
+ }
+ if v := os.Getenv(EnvVaultClientCert); v != "" {
+ envClientCert = v
+ }
+ if v := os.Getenv(EnvVaultClientKey); v != "" {
+ envClientKey = v
+ }
+ if v := os.Getenv(EnvVaultInsecure); v != "" {
+ var err error
+ envInsecure, err = strconv.ParseBool(v)
+ if err != nil {
+ return fmt.Errorf("Could not parse VAULT_SKIP_VERIFY")
+ }
+ }
+ if v := os.Getenv(EnvVaultTLSServerName); v != "" {
+ envTLSServerName = v
+ }
+
+ // Configure the HTTP clients TLS configuration.
+ t := &TLSConfig{
+ CACert: envCACert,
+ CAPath: envCAPath,
+ ClientCert: envClientCert,
+ ClientKey: envClientKey,
+ TLSServerName: envTLSServerName,
+ Insecure: envInsecure,
+ }
+ if err := c.ConfigureTLS(t); err != nil {
+ return err
+ }
+
+ if envAddress != "" {
+ c.Address = envAddress
+ }
+
+ if envMaxRetries != nil {
+ c.MaxRetries = int(*envMaxRetries) + 1
+ }
+
+ return nil
+}
+
+// Client is the client to the Vault API. Create a client with
+// NewClient.
+type Client struct {
+ addr *url.URL
+ config *Config
+ token string
+ wrappingLookupFunc WrappingLookupFunc
+}
+
+// NewClient returns a new client for the given configuration.
+//
+// If the environment variable `VAULT_TOKEN` is present, the token will be
+// automatically added to the client. Otherwise, you must manually call
+// `SetToken()`.
+func NewClient(c *Config) (*Client, error) {
+ if c == nil {
+ c = DefaultConfig()
+ if err := c.ReadEnvironment(); err != nil {
+ return nil, fmt.Errorf("error reading environment: %v", err)
+ }
+ }
+
+ u, err := url.Parse(c.Address)
+ if err != nil {
+ return nil, err
+ }
+
+ if c.HttpClient == nil {
+ c.HttpClient = DefaultConfig().HttpClient
+ }
+
+ redirFunc := func() {
+ // Ensure redirects are not automatically followed
+ // Note that this is sane for the API client as it has its own
+ // redirect handling logic (and thus also for command/meta),
+ // but in e.g. http_test actual redirect handling is necessary
+ c.HttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+ // Returning this value causes the Go net library to not close the
+ // response body and nil out the error. Otherwise pester tries
+ // three times on every redirect because it sees an error from this
+ // function being passed through.
+ return http.ErrUseLastResponse
+ }
+ }
+
+ c.redirectSetup.Do(redirFunc)
+
+ client := &Client{
+ addr: u,
+ config: c,
+ }
+
+ if token := os.Getenv("VAULT_TOKEN"); token != "" {
+ client.SetToken(token)
+ }
+
+ return client, nil
+}
+
+// Sets the address of Vault in the client. The format of address should be
+// "<Scheme>://<Host>:<Port>". Setting this on a client will override the
+// value of VAULT_ADDR environment variable.
+func (c *Client) SetAddress(addr string) error {
+ var err error
+ if c.addr, err = url.Parse(addr); err != nil {
+ return fmt.Errorf("failed to set address: %v", err)
+ }
+
+ return nil
+}
+
+// SetWrappingLookupFunc sets a lookup function that returns desired wrap TTLs
+// for a given operation and path
+func (c *Client) SetWrappingLookupFunc(lookupFunc WrappingLookupFunc) {
+ c.wrappingLookupFunc = lookupFunc
+}
+
+// Token returns the access token being used by this client. It will
+// return the empty string if there is no token set.
+func (c *Client) Token() string {
+ return c.token
+}
+
+// SetToken sets the token directly. This won't perform any auth
+// verification, it simply sets the token properly for future requests.
+func (c *Client) SetToken(v string) {
+ c.token = v
+}
+
+// ClearToken deletes the token if it is set or does nothing otherwise.
+func (c *Client) ClearToken() {
+ c.token = ""
+}
+
+// NewRequest creates a new raw request object to query the Vault server
+// configured for this client. This is an advanced method and generally
+// doesn't need to be called externally.
+func (c *Client) NewRequest(method, path string) *Request {
+ req := &Request{
+ Method: method,
+ URL: &url.URL{
+ Scheme: c.addr.Scheme,
+ Host: c.addr.Host,
+ Path: path,
+ },
+ ClientToken: c.token,
+ Params: make(map[string][]string),
+ }
+
+ var lookupPath string
+ switch {
+ case strings.HasPrefix(path, "/v1/"):
+ lookupPath = strings.TrimPrefix(path, "/v1/")
+ case strings.HasPrefix(path, "v1/"):
+ lookupPath = strings.TrimPrefix(path, "v1/")
+ default:
+ lookupPath = path
+ }
+ if c.wrappingLookupFunc != nil {
+ req.WrapTTL = c.wrappingLookupFunc(method, lookupPath)
+ } else {
+ req.WrapTTL = DefaultWrappingLookupFunc(method, lookupPath)
+ }
+
+ return req
+}
+
+// RawRequest performs the raw request given. This request may be against
+// a Vault server not configured with this client. This is an advanced operation
+// that generally won't need to be called externally.
+func (c *Client) RawRequest(r *Request) (*Response, error) {
+ redirectCount := 0
+START:
+ req, err := r.ToHTTP()
+ if err != nil {
+ return nil, err
+ }
+
+ client := pester.NewExtendedClient(c.config.HttpClient)
+ client.Backoff = pester.LinearJitterBackoff
+ client.MaxRetries = c.config.MaxRetries
+
+ var result *Response
+ resp, err := client.Do(req)
+ if resp != nil {
+ result = &Response{Response: resp}
+ }
+ if err != nil {
+ if strings.Contains(err.Error(), "tls: oversized") {
+ err = fmt.Errorf(
+ "%s\n\n"+
+ "This error usually means that the server is running with TLS disabled\n"+
+ "but the client is configured to use TLS. Please either enable TLS\n"+
+ "on the server or run the client with -address set to an address\n"+
+ "that uses the http protocol:\n\n"+
+ " vault <command> -address http://<address>\n\n"+
+ "You can also set the VAULT_ADDR environment variable:\n\n\n"+
+ " VAULT_ADDR=http://<address> vault <command>\n\n"+
+ "where <address> is replaced by the actual address to the server.",
+ err)
+ }
+ return result, err
+ }
+
+ // Check for a redirect, only allowing for a single redirect
+ if (resp.StatusCode == 301 || resp.StatusCode == 302 || resp.StatusCode == 307) && redirectCount == 0 {
+ // Parse the updated location
+ respLoc, err := resp.Location()
+ if err != nil {
+ return result, err
+ }
+
+ // Ensure a protocol downgrade doesn't happen
+ if req.URL.Scheme == "https" && respLoc.Scheme != "https" {
+ return result, fmt.Errorf("redirect would cause protocol downgrade")
+ }
+
+ // Update the request
+ r.URL = respLoc
+
+ // Reset the request body if any
+ if err := r.ResetJSONBody(); err != nil {
+ return result, err
+ }
+
+ // Retry the request
+ redirectCount++
+ goto START
+ }
+
+ if err := result.Error(); err != nil {
+ return result, err
+ }
+
+ return result, nil
+}
diff --git a/vendor/github.com/hashicorp/vault/api/help.go b/vendor/github.com/hashicorp/vault/api/help.go
new file mode 100644
index 0000000..b9ae100
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/help.go
@@ -0,0 +1,25 @@
+package api
+
+import (
+ "fmt"
+)
+
+// Help reads the help information for the given path.
+func (c *Client) Help(path string) (*Help, error) {
+ r := c.NewRequest("GET", fmt.Sprintf("/v1/%s", path))
+ r.Params.Add("help", "1")
+ resp, err := c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result Help
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+type Help struct {
+ Help string `json:"help"`
+ SeeAlso []string `json:"see_also"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/logical.go b/vendor/github.com/hashicorp/vault/api/logical.go
new file mode 100644
index 0000000..f1cea7d
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/logical.go
@@ -0,0 +1,176 @@
+package api
+
+import (
+ "bytes"
+ "fmt"
+ "net/http"
+ "os"
+
+ "github.com/hashicorp/vault/helper/jsonutil"
+)
+
+const (
+ wrappedResponseLocation = "cubbyhole/response"
+)
+
+var (
+ // The default TTL that will be used with `sys/wrapping/wrap`, can be
+ // changed
+ DefaultWrappingTTL = "5m"
+
+ // The default function used if no other function is set, which honors the
+ // env var and wraps `sys/wrapping/wrap`
+ DefaultWrappingLookupFunc = func(operation, path string) string {
+ if os.Getenv(EnvVaultWrapTTL) != "" {
+ return os.Getenv(EnvVaultWrapTTL)
+ }
+
+ if (operation == "PUT" || operation == "POST") && path == "sys/wrapping/wrap" {
+ return DefaultWrappingTTL
+ }
+
+ return ""
+ }
+)
+
+// Logical is used to perform logical backend operations on Vault.
+type Logical struct {
+ c *Client
+}
+
+// Logical is used to return the client for logical-backend API calls.
+func (c *Client) Logical() *Logical {
+ return &Logical{c: c}
+}
+
+func (c *Logical) Read(path string) (*Secret, error) {
+ r := c.c.NewRequest("GET", "/v1/"+path)
+ resp, err := c.c.RawRequest(r)
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+ if resp != nil && resp.StatusCode == 404 {
+ return nil, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *Logical) List(path string) (*Secret, error) {
+ r := c.c.NewRequest("LIST", "/v1/"+path)
+ // Set this for broader compatibility, but we use LIST above to be able to
+ // handle the wrapping lookup function
+ r.Method = "GET"
+ r.Params.Set("list", "true")
+ resp, err := c.c.RawRequest(r)
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+ if resp != nil && resp.StatusCode == 404 {
+ return nil, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *Logical) Write(path string, data map[string]interface{}) (*Secret, error) {
+ r := c.c.NewRequest("PUT", "/v1/"+path)
+ if err := r.SetJSONBody(data); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode == 200 {
+ return ParseSecret(resp.Body)
+ }
+
+ return nil, nil
+}
+
+func (c *Logical) Delete(path string) (*Secret, error) {
+ r := c.c.NewRequest("DELETE", "/v1/"+path)
+ resp, err := c.c.RawRequest(r)
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.StatusCode == 200 {
+ return ParseSecret(resp.Body)
+ }
+
+ return nil, nil
+}
+
+func (c *Logical) Unwrap(wrappingToken string) (*Secret, error) {
+ var data map[string]interface{}
+ if wrappingToken != "" {
+ data = map[string]interface{}{
+ "token": wrappingToken,
+ }
+ }
+
+ r := c.c.NewRequest("PUT", "/v1/sys/wrapping/unwrap")
+ if err := r.SetJSONBody(data); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if resp != nil {
+ defer resp.Body.Close()
+ }
+ if err != nil && resp.StatusCode != 404 {
+ return nil, err
+ }
+
+ switch resp.StatusCode {
+ case http.StatusOK: // New method is supported
+ return ParseSecret(resp.Body)
+ case http.StatusNotFound: // Fall back to old method
+ default:
+ return nil, nil
+ }
+
+ if wrappingToken == "" {
+ origToken := c.c.Token()
+ defer c.c.SetToken(origToken)
+ c.c.SetToken(wrappingToken)
+ }
+
+ secret, err := c.Read(wrappedResponseLocation)
+ if err != nil {
+ return nil, fmt.Errorf("error reading %s: %s", wrappedResponseLocation, err)
+ }
+ if secret == nil {
+ return nil, fmt.Errorf("no value found at %s", wrappedResponseLocation)
+ }
+ if secret.Data == nil {
+ return nil, fmt.Errorf("\"data\" not found in wrapping response")
+ }
+ if _, ok := secret.Data["response"]; !ok {
+ return nil, fmt.Errorf("\"response\" not found in wrapping response \"data\" map")
+ }
+
+ wrappedSecret := new(Secret)
+ buf := bytes.NewBufferString(secret.Data["response"].(string))
+ if err := jsonutil.DecodeJSONFromReader(buf, wrappedSecret); err != nil {
+ return nil, fmt.Errorf("error unmarshaling wrapped secret: %s", err)
+ }
+
+ return wrappedSecret, nil
+}
diff --git a/vendor/github.com/hashicorp/vault/api/request.go b/vendor/github.com/hashicorp/vault/api/request.go
new file mode 100644
index 0000000..8f22dd5
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/request.go
@@ -0,0 +1,71 @@
+package api
+
+import (
+ "bytes"
+ "encoding/json"
+ "io"
+ "net/http"
+ "net/url"
+)
+
+// Request is a raw request configuration structure used to initiate
+// API requests to the Vault server.
+type Request struct {
+ Method string
+ URL *url.URL
+ Params url.Values
+ ClientToken string
+ WrapTTL string
+ Obj interface{}
+ Body io.Reader
+ BodySize int64
+}
+
+// SetJSONBody is used to set a request body that is a JSON-encoded value.
+func (r *Request) SetJSONBody(val interface{}) error {
+ buf := bytes.NewBuffer(nil)
+ enc := json.NewEncoder(buf)
+ if err := enc.Encode(val); err != nil {
+ return err
+ }
+
+ r.Obj = val
+ r.Body = buf
+ r.BodySize = int64(buf.Len())
+ return nil
+}
+
+// ResetJSONBody is used to reset the body for a redirect
+func (r *Request) ResetJSONBody() error {
+ if r.Body == nil {
+ return nil
+ }
+ return r.SetJSONBody(r.Obj)
+}
+
+// ToHTTP turns this request into a valid *http.Request for use with the
+// net/http package.
+func (r *Request) ToHTTP() (*http.Request, error) {
+ // Encode the query parameters
+ r.URL.RawQuery = r.Params.Encode()
+
+ // Create the HTTP request
+ req, err := http.NewRequest(r.Method, r.URL.RequestURI(), r.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ req.URL.Scheme = r.URL.Scheme
+ req.URL.Host = r.URL.Host
+ req.Host = r.URL.Host
+
+ if len(r.ClientToken) != 0 {
+ req.Header.Set("X-Vault-Token", r.ClientToken)
+ }
+
+ if len(r.WrapTTL) != 0 {
+ req.Header.Set("X-Vault-Wrap-TTL", r.WrapTTL)
+ }
+
+ return req, nil
+}
diff --git a/vendor/github.com/hashicorp/vault/api/response.go b/vendor/github.com/hashicorp/vault/api/response.go
new file mode 100644
index 0000000..7c8ac9f
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/response.go
@@ -0,0 +1,72 @@
+package api
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "net/http"
+
+ "github.com/hashicorp/vault/helper/jsonutil"
+)
+
+// Response is a raw response that wraps an HTTP response.
+type Response struct {
+ *http.Response
+}
+
+// DecodeJSON will decode the response body to a JSON structure. This
+// will consume the response body, but will not close it. Close must
+// still be called.
+func (r *Response) DecodeJSON(out interface{}) error {
+ return jsonutil.DecodeJSONFromReader(r.Body, out)
+}
+
+// Error returns an error response if there is one. If there is an error,
+// this will fully consume the response body, but will not close it. The
+// body must still be closed manually.
+func (r *Response) Error() error {
+ // 200 to 399 are okay status codes
+ if r.StatusCode >= 200 && r.StatusCode < 400 {
+ return nil
+ }
+
+ // We have an error. Let's copy the body into our own buffer first,
+ // so that if we can't decode JSON, we can at least copy it raw.
+ var bodyBuf bytes.Buffer
+ if _, err := io.Copy(&bodyBuf, r.Body); err != nil {
+ return err
+ }
+
+ // Decode the error response if we can. Note that we wrap the bodyBuf
+ // in a bytes.Reader here so that the JSON decoder doesn't move the
+ // read pointer for the original buffer.
+ var resp ErrorResponse
+ if err := jsonutil.DecodeJSON(bodyBuf.Bytes(), &resp); err != nil {
+ // Ignore the decoding error and just drop the raw response
+ return fmt.Errorf(
+ "Error making API request.\n\n"+
+ "URL: %s %s\n"+
+ "Code: %d. Raw Message:\n\n%s",
+ r.Request.Method, r.Request.URL.String(),
+ r.StatusCode, bodyBuf.String())
+ }
+
+ var errBody bytes.Buffer
+ errBody.WriteString(fmt.Sprintf(
+ "Error making API request.\n\n"+
+ "URL: %s %s\n"+
+ "Code: %d. Errors:\n\n",
+ r.Request.Method, r.Request.URL.String(),
+ r.StatusCode))
+ for _, err := range resp.Errors {
+ errBody.WriteString(fmt.Sprintf("* %s", err))
+ }
+
+ return fmt.Errorf(errBody.String())
+}
+
+// ErrorResponse is the raw structure of errors when they're returned by the
+// HTTP API.
+type ErrorResponse struct {
+ Errors []string
+}
diff --git a/vendor/github.com/hashicorp/vault/api/secret.go b/vendor/github.com/hashicorp/vault/api/secret.go
new file mode 100644
index 0000000..14924f9
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/secret.go
@@ -0,0 +1,68 @@
+package api
+
+import (
+ "io"
+ "time"
+
+ "github.com/hashicorp/vault/helper/jsonutil"
+)
+
+// Secret is the structure returned for every secret within Vault.
+type Secret struct {
+ // The request ID that generated this response
+ RequestID string `json:"request_id"`
+
+ LeaseID string `json:"lease_id"`
+ LeaseDuration int `json:"lease_duration"`
+ Renewable bool `json:"renewable"`
+
+ // Data is the actual contents of the secret. The format of the data
+ // is arbitrary and up to the secret backend.
+ Data map[string]interface{} `json:"data"`
+
+ // Warnings contains any warnings related to the operation. These
+ // are not issues that caused the command to fail, but that the
+ // client should be aware of.
+ Warnings []string `json:"warnings"`
+
+ // Auth, if non-nil, means that there was authentication information
+ // attached to this response.
+ Auth *SecretAuth `json:"auth,omitempty"`
+
+ // WrapInfo, if non-nil, means that the initial response was wrapped in the
+ // cubbyhole of the given token (which has a TTL of the given number of
+ // seconds)
+ WrapInfo *SecretWrapInfo `json:"wrap_info,omitempty"`
+}
+
+// SecretWrapInfo contains wrapping information if we have it. If what is
+// contained is an authentication token, the accessor for the token will be
+// available in WrappedAccessor.
+type SecretWrapInfo struct {
+ Token string `json:"token"`
+ TTL int `json:"ttl"`
+ CreationTime time.Time `json:"creation_time"`
+ WrappedAccessor string `json:"wrapped_accessor"`
+}
+
+// SecretAuth is the structure containing auth information if we have it.
+type SecretAuth struct {
+ ClientToken string `json:"client_token"`
+ Accessor string `json:"accessor"`
+ Policies []string `json:"policies"`
+ Metadata map[string]string `json:"metadata"`
+
+ LeaseDuration int `json:"lease_duration"`
+ Renewable bool `json:"renewable"`
+}
+
+// ParseSecret is used to parse a secret value from JSON from an io.Reader.
+func ParseSecret(r io.Reader) (*Secret, error) {
+ // First decode the JSON into a map[string]interface{}
+ var secret Secret
+ if err := jsonutil.DecodeJSONFromReader(r, &secret); err != nil {
+ return nil, err
+ }
+
+ return &secret, nil
+}
diff --git a/vendor/github.com/hashicorp/vault/api/ssh.go b/vendor/github.com/hashicorp/vault/api/ssh.go
new file mode 100644
index 0000000..7c3e56b
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/ssh.go
@@ -0,0 +1,38 @@
+package api
+
+import "fmt"
+
+// SSH is used to return a client to invoke operations on SSH backend.
+type SSH struct {
+ c *Client
+ MountPoint string
+}
+
+// SSH returns the client for logical-backend API calls.
+func (c *Client) SSH() *SSH {
+ return c.SSHWithMountPoint(SSHHelperDefaultMountPoint)
+}
+
+// SSHWithMountPoint returns the client with specific SSH mount point.
+func (c *Client) SSHWithMountPoint(mountPoint string) *SSH {
+ return &SSH{
+ c: c,
+ MountPoint: mountPoint,
+ }
+}
+
+// Credential invokes the SSH backend API to create a credential to establish an SSH session.
+func (c *SSH) Credential(role string, data map[string]interface{}) (*Secret, error) {
+ r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/%s/creds/%s", c.MountPoint, role))
+ if err := r.SetJSONBody(data); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
diff --git a/vendor/github.com/hashicorp/vault/api/ssh_agent.go b/vendor/github.com/hashicorp/vault/api/ssh_agent.go
new file mode 100644
index 0000000..729fd99
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/ssh_agent.go
@@ -0,0 +1,257 @@
+package api
+
+import (
+ "crypto/tls"
+ "crypto/x509"
+ "fmt"
+ "io/ioutil"
+ "os"
+
+ "github.com/hashicorp/go-cleanhttp"
+ "github.com/hashicorp/go-multierror"
+ "github.com/hashicorp/go-rootcerts"
+ "github.com/hashicorp/hcl"
+ "github.com/hashicorp/hcl/hcl/ast"
+ "github.com/mitchellh/mapstructure"
+)
+
+const (
+ // SSHHelperDefaultMountPoint is the default path at which SSH backend will be
+ // mounted in the Vault server.
+ SSHHelperDefaultMountPoint = "ssh"
+
+ // VerifyEchoRequest is the echo request message sent as OTP by the helper.
+ VerifyEchoRequest = "verify-echo-request"
+
+ // VerifyEchoResponse is the echo response message sent as a response to OTP
+ // matching echo request.
+ VerifyEchoResponse = "verify-echo-response"
+)
+
+// SSHHelper is a structure representing a vault-ssh-helper which can talk to vault server
+// in order to verify the OTP entered by the user. It contains the path at which
+// SSH backend is mounted at the server.
+type SSHHelper struct {
+ c *Client
+ MountPoint string
+}
+
+// SSHVerifyResponse is a structure representing the fields in Vault server's
+// response.
+type SSHVerifyResponse struct {
+ // Usually empty. If the request OTP is echo request message, this will
+ // be set to the corresponding echo response message.
+ Message string `json:"message" structs:"message" mapstructure:"message"`
+
+ // Username associated with the OTP
+ Username string `json:"username" structs:"username" mapstructure:"username"`
+
+ // IP associated with the OTP
+ IP string `json:"ip" structs:"ip" mapstructure:"ip"`
+
+ // Name of the role against which the OTP was issued
+ RoleName string `json:"role_name" structs:"role_name" mapstructure:"role_name"`
+}
+
+// SSHHelperConfig is a structure which represents the entries from the vault-ssh-helper's configuration file.
+type SSHHelperConfig struct {
+ VaultAddr string `hcl:"vault_addr"`
+ SSHMountPoint string `hcl:"ssh_mount_point"`
+ CACert string `hcl:"ca_cert"`
+ CAPath string `hcl:"ca_path"`
+ AllowedCidrList string `hcl:"allowed_cidr_list"`
+ AllowedRoles string `hcl:"allowed_roles"`
+ TLSSkipVerify bool `hcl:"tls_skip_verify"`
+ TLSServerName string `hcl:"tls_server_name"`
+}
+
+// SetTLSParameters sets the TLS parameters for this SSH agent.
+func (c *SSHHelperConfig) SetTLSParameters(clientConfig *Config, certPool *x509.CertPool) {
+ tlsConfig := &tls.Config{
+ InsecureSkipVerify: c.TLSSkipVerify,
+ MinVersion: tls.VersionTLS12,
+ RootCAs: certPool,
+ ServerName: c.TLSServerName,
+ }
+
+ transport := cleanhttp.DefaultTransport()
+ transport.TLSClientConfig = tlsConfig
+ clientConfig.HttpClient.Transport = transport
+}
+
+// Returns true if any of the following conditions are true:
+// * CA cert is configured
+// * CA path is configured
+// * configured to skip certificate verification
+// * TLS server name is configured
+//
+func (c *SSHHelperConfig) shouldSetTLSParameters() bool {
+ return c.CACert != "" || c.CAPath != "" || c.TLSServerName != "" || c.TLSSkipVerify
+}
+
+// NewClient returns a new client for the configuration. This client will be used by the
+// vault-ssh-helper to communicate with Vault server and verify the OTP entered by user.
+// If the configuration supplies Vault SSL certificates, then the client will
+// have TLS configured in its transport.
+func (c *SSHHelperConfig) NewClient() (*Client, error) {
+ // Creating a default client configuration for communicating with vault server.
+ clientConfig := DefaultConfig()
+
+ // Pointing the client to the actual address of vault server.
+ clientConfig.Address = c.VaultAddr
+
+ // Check if certificates are provided via config file.
+ if c.shouldSetTLSParameters() {
+ rootConfig := &rootcerts.Config{
+ CAFile: c.CACert,
+ CAPath: c.CAPath,
+ }
+ certPool, err := rootcerts.LoadCACerts(rootConfig)
+ if err != nil {
+ return nil, err
+ }
+ // Enable TLS on the HTTP client information
+ c.SetTLSParameters(clientConfig, certPool)
+ }
+
+ // Creating the client object for the given configuration
+ client, err := NewClient(clientConfig)
+ if err != nil {
+ return nil, err
+ }
+
+ return client, nil
+}
+
+// LoadSSHHelperConfig loads ssh-helper's configuration from the file and populates the corresponding
+// in-memory structure.
+//
+// Vault address is a required parameter.
+// Mount point defaults to "ssh".
+func LoadSSHHelperConfig(path string) (*SSHHelperConfig, error) {
+ contents, err := ioutil.ReadFile(path)
+ if err != nil && !os.IsNotExist(err) {
+ return nil, multierror.Prefix(err, "ssh_helper:")
+ }
+ return ParseSSHHelperConfig(string(contents))
+}
+
+// ParseSSHHelperConfig parses the given contents as a string for the SSHHelper
+// configuration.
+func ParseSSHHelperConfig(contents string) (*SSHHelperConfig, error) {
+ root, err := hcl.Parse(string(contents))
+ if err != nil {
+ return nil, fmt.Errorf("ssh_helper: error parsing config: %s", err)
+ }
+
+ list, ok := root.Node.(*ast.ObjectList)
+ if !ok {
+ return nil, fmt.Errorf("ssh_helper: error parsing config: file doesn't contain a root object")
+ }
+
+ valid := []string{
+ "vault_addr",
+ "ssh_mount_point",
+ "ca_cert",
+ "ca_path",
+ "allowed_cidr_list",
+ "allowed_roles",
+ "tls_skip_verify",
+ "tls_server_name",
+ }
+ if err := checkHCLKeys(list, valid); err != nil {
+ return nil, multierror.Prefix(err, "ssh_helper:")
+ }
+
+ var c SSHHelperConfig
+ c.SSHMountPoint = SSHHelperDefaultMountPoint
+ if err := hcl.DecodeObject(&c, list); err != nil {
+ return nil, multierror.Prefix(err, "ssh_helper:")
+ }
+
+ if c.VaultAddr == "" {
+ return nil, fmt.Errorf("ssh_helper: missing config 'vault_addr'")
+ }
+ return &c, nil
+}
+
+// SSHHelper creates an SSHHelper object which can talk to Vault server with SSH backend
+// mounted at default path ("ssh").
+func (c *Client) SSHHelper() *SSHHelper {
+ return c.SSHHelperWithMountPoint(SSHHelperDefaultMountPoint)
+}
+
+// SSHHelperWithMountPoint creates an SSHHelper object which can talk to Vault server with SSH backend
+// mounted at a specific mount point.
+func (c *Client) SSHHelperWithMountPoint(mountPoint string) *SSHHelper {
+ return &SSHHelper{
+ c: c,
+ MountPoint: mountPoint,
+ }
+}
+
+// Verify verifies if the key provided by user is present in Vault server. The response
+// will contain the IP address and username associated with the OTP. In case the
+// OTP matches the echo request message, instead of searching an entry for the OTP,
+// an echo response message is returned. This feature is used by ssh-helper to verify if
+// its configured correctly.
+func (c *SSHHelper) Verify(otp string) (*SSHVerifyResponse, error) {
+ data := map[string]interface{}{
+ "otp": otp,
+ }
+ verifyPath := fmt.Sprintf("/v1/%s/verify", c.MountPoint)
+ r := c.c.NewRequest("PUT", verifyPath)
+ if err := r.SetJSONBody(data); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ secret, err := ParseSecret(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ if secret.Data == nil {
+ return nil, nil
+ }
+
+ var verifyResp SSHVerifyResponse
+ err = mapstructure.Decode(secret.Data, &verifyResp)
+ if err != nil {
+ return nil, err
+ }
+ return &verifyResp, nil
+}
+
+func checkHCLKeys(node ast.Node, valid []string) error {
+ var list *ast.ObjectList
+ switch n := node.(type) {
+ case *ast.ObjectList:
+ list = n
+ case *ast.ObjectType:
+ list = n.List
+ default:
+ return fmt.Errorf("cannot check HCL keys of type %T", n)
+ }
+
+ validMap := make(map[string]struct{}, len(valid))
+ for _, v := range valid {
+ validMap[v] = struct{}{}
+ }
+
+ var result error
+ for _, item := range list.Items {
+ key := item.Keys[0].Token.Value().(string)
+ if _, ok := validMap[key]; !ok {
+ result = multierror.Append(result, fmt.Errorf(
+ "invalid key '%s' on line %d", key, item.Assign.Line))
+ }
+ }
+
+ return result
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys.go b/vendor/github.com/hashicorp/vault/api/sys.go
new file mode 100644
index 0000000..5fb1118
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys.go
@@ -0,0 +1,11 @@
+package api
+
+// Sys is used to perform system-related operations on Vault.
+type Sys struct {
+ c *Client
+}
+
+// Sys is used to return the client for sys-related API calls.
+func (c *Client) Sys() *Sys {
+ return &Sys{c: c}
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_audit.go b/vendor/github.com/hashicorp/vault/api/sys_audit.go
new file mode 100644
index 0000000..1ffdef8
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_audit.go
@@ -0,0 +1,114 @@
+package api
+
+import (
+ "fmt"
+
+ "github.com/mitchellh/mapstructure"
+)
+
+func (c *Sys) AuditHash(path string, input string) (string, error) {
+ body := map[string]interface{}{
+ "input": input,
+ }
+
+ r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/sys/audit-hash/%s", path))
+ if err := r.SetJSONBody(body); err != nil {
+ return "", err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ type d struct {
+ Hash string `json:"hash"`
+ }
+
+ var result d
+ err = resp.DecodeJSON(&result)
+ if err != nil {
+ return "", err
+ }
+
+ return result.Hash, err
+}
+
+func (c *Sys) ListAudit() (map[string]*Audit, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/audit")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result map[string]interface{}
+ err = resp.DecodeJSON(&result)
+ if err != nil {
+ return nil, err
+ }
+
+ mounts := map[string]*Audit{}
+ for k, v := range result {
+ switch v.(type) {
+ case map[string]interface{}:
+ default:
+ continue
+ }
+ var res Audit
+ err = mapstructure.Decode(v, &res)
+ if err != nil {
+ return nil, err
+ }
+ // Not a mount, some other api.Secret data
+ if res.Type == "" {
+ continue
+ }
+ mounts[k] = &res
+ }
+
+ return mounts, nil
+}
+
+func (c *Sys) EnableAudit(
+ path string, auditType string, desc string, opts map[string]string) error {
+ body := map[string]interface{}{
+ "type": auditType,
+ "description": desc,
+ "options": opts,
+ }
+
+ r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/sys/audit/%s", path))
+ if err := r.SetJSONBody(body); err != nil {
+ return err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
+}
+
+func (c *Sys) DisableAudit(path string) error {
+ r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/audit/%s", path))
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+// Structures for the requests/resposne are all down here. They aren't
+// individually documented because the map almost directly to the raw HTTP API
+// documentation. Please refer to that documentation for more details.
+
+type Audit struct {
+ Path string
+ Type string
+ Description string
+ Options map[string]string
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_auth.go b/vendor/github.com/hashicorp/vault/api/sys_auth.go
new file mode 100644
index 0000000..1940e84
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_auth.go
@@ -0,0 +1,87 @@
+package api
+
+import (
+ "fmt"
+
+ "github.com/mitchellh/mapstructure"
+)
+
+func (c *Sys) ListAuth() (map[string]*AuthMount, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/auth")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result map[string]interface{}
+ err = resp.DecodeJSON(&result)
+ if err != nil {
+ return nil, err
+ }
+
+ mounts := map[string]*AuthMount{}
+ for k, v := range result {
+ switch v.(type) {
+ case map[string]interface{}:
+ default:
+ continue
+ }
+ var res AuthMount
+ err = mapstructure.Decode(v, &res)
+ if err != nil {
+ return nil, err
+ }
+ // Not a mount, some other api.Secret data
+ if res.Type == "" {
+ continue
+ }
+ mounts[k] = &res
+ }
+
+ return mounts, nil
+}
+
+func (c *Sys) EnableAuth(path, authType, desc string) error {
+ body := map[string]string{
+ "type": authType,
+ "description": desc,
+ }
+
+ r := c.c.NewRequest("POST", fmt.Sprintf("/v1/sys/auth/%s", path))
+ if err := r.SetJSONBody(body); err != nil {
+ return err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
+}
+
+func (c *Sys) DisableAuth(path string) error {
+ r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/auth/%s", path))
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+// Structures for the requests/resposne are all down here. They aren't
+// individually documentd because the map almost directly to the raw HTTP API
+// documentation. Please refer to that documentation for more details.
+
+type AuthMount struct {
+ Type string `json:"type" structs:"type" mapstructure:"type"`
+ Description string `json:"description" structs:"description" mapstructure:"description"`
+ Config AuthConfigOutput `json:"config" structs:"config" mapstructure:"config"`
+}
+
+type AuthConfigOutput struct {
+ DefaultLeaseTTL int `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
+ MaxLeaseTTL int `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_capabilities.go b/vendor/github.com/hashicorp/vault/api/sys_capabilities.go
new file mode 100644
index 0000000..80f6218
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_capabilities.go
@@ -0,0 +1,43 @@
+package api
+
+import "fmt"
+
+func (c *Sys) CapabilitiesSelf(path string) ([]string, error) {
+ return c.Capabilities(c.c.Token(), path)
+}
+
+func (c *Sys) Capabilities(token, path string) ([]string, error) {
+ body := map[string]string{
+ "token": token,
+ "path": path,
+ }
+
+ reqPath := "/v1/sys/capabilities"
+ if token == c.c.Token() {
+ reqPath = fmt.Sprintf("%s-self", reqPath)
+ }
+
+ r := c.c.NewRequest("POST", reqPath)
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result map[string]interface{}
+ err = resp.DecodeJSON(&result)
+ if err != nil {
+ return nil, err
+ }
+
+ var capabilities []string
+ capabilitiesRaw := result["capabilities"].([]interface{})
+ for _, capability := range capabilitiesRaw {
+ capabilities = append(capabilities, capability.(string))
+ }
+ return capabilities, nil
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_generate_root.go b/vendor/github.com/hashicorp/vault/api/sys_generate_root.go
new file mode 100644
index 0000000..8dc2095
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_generate_root.go
@@ -0,0 +1,77 @@
+package api
+
+func (c *Sys) GenerateRootStatus() (*GenerateRootStatusResponse, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/generate-root/attempt")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result GenerateRootStatusResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) GenerateRootInit(otp, pgpKey string) (*GenerateRootStatusResponse, error) {
+ body := map[string]interface{}{
+ "otp": otp,
+ "pgp_key": pgpKey,
+ }
+
+ r := c.c.NewRequest("PUT", "/v1/sys/generate-root/attempt")
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result GenerateRootStatusResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) GenerateRootCancel() error {
+ r := c.c.NewRequest("DELETE", "/v1/sys/generate-root/attempt")
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) GenerateRootUpdate(shard, nonce string) (*GenerateRootStatusResponse, error) {
+ body := map[string]interface{}{
+ "key": shard,
+ "nonce": nonce,
+ }
+
+ r := c.c.NewRequest("PUT", "/v1/sys/generate-root/update")
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result GenerateRootStatusResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+type GenerateRootStatusResponse struct {
+ Nonce string
+ Started bool
+ Progress int
+ Required int
+ Complete bool
+ EncodedRootToken string `json:"encoded_root_token"`
+ PGPFingerprint string `json:"pgp_fingerprint"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_init.go b/vendor/github.com/hashicorp/vault/api/sys_init.go
new file mode 100644
index 0000000..f824ab7
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_init.go
@@ -0,0 +1,54 @@
+package api
+
+func (c *Sys) InitStatus() (bool, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/init")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return false, err
+ }
+ defer resp.Body.Close()
+
+ var result InitStatusResponse
+ err = resp.DecodeJSON(&result)
+ return result.Initialized, err
+}
+
+func (c *Sys) Init(opts *InitRequest) (*InitResponse, error) {
+ r := c.c.NewRequest("PUT", "/v1/sys/init")
+ if err := r.SetJSONBody(opts); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result InitResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+type InitRequest struct {
+ SecretShares int `json:"secret_shares"`
+ SecretThreshold int `json:"secret_threshold"`
+ StoredShares int `json:"stored_shares"`
+ PGPKeys []string `json:"pgp_keys"`
+ RecoveryShares int `json:"recovery_shares"`
+ RecoveryThreshold int `json:"recovery_threshold"`
+ RecoveryPGPKeys []string `json:"recovery_pgp_keys"`
+ RootTokenPGPKey string `json:"root_token_pgp_key"`
+}
+
+type InitStatusResponse struct {
+ Initialized bool
+}
+
+type InitResponse struct {
+ Keys []string `json:"keys"`
+ KeysB64 []string `json:"keys_base64"`
+ RecoveryKeys []string `json:"recovery_keys"`
+ RecoveryKeysB64 []string `json:"recovery_keys_base64"`
+ RootToken string `json:"root_token"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_leader.go b/vendor/github.com/hashicorp/vault/api/sys_leader.go
new file mode 100644
index 0000000..201ac73
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_leader.go
@@ -0,0 +1,20 @@
+package api
+
+func (c *Sys) Leader() (*LeaderResponse, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/leader")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result LeaderResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+type LeaderResponse struct {
+ HAEnabled bool `json:"ha_enabled"`
+ IsSelf bool `json:"is_self"`
+ LeaderAddress string `json:"leader_address"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_lease.go b/vendor/github.com/hashicorp/vault/api/sys_lease.go
new file mode 100644
index 0000000..e5c19c4
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_lease.go
@@ -0,0 +1,48 @@
+package api
+
+func (c *Sys) Renew(id string, increment int) (*Secret, error) {
+ r := c.c.NewRequest("PUT", "/v1/sys/renew")
+
+ body := map[string]interface{}{
+ "increment": increment,
+ "lease_id": id,
+ }
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ParseSecret(resp.Body)
+}
+
+func (c *Sys) Revoke(id string) error {
+ r := c.c.NewRequest("PUT", "/v1/sys/revoke/"+id)
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) RevokePrefix(id string) error {
+ r := c.c.NewRequest("PUT", "/v1/sys/revoke-prefix/"+id)
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) RevokeForce(id string) error {
+ r := c.c.NewRequest("PUT", "/v1/sys/revoke-force/"+id)
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_mounts.go b/vendor/github.com/hashicorp/vault/api/sys_mounts.go
new file mode 100644
index 0000000..ca5e427
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_mounts.go
@@ -0,0 +1,142 @@
+package api
+
+import (
+ "fmt"
+
+ "github.com/fatih/structs"
+ "github.com/mitchellh/mapstructure"
+)
+
+func (c *Sys) ListMounts() (map[string]*MountOutput, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/mounts")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result map[string]interface{}
+ err = resp.DecodeJSON(&result)
+ if err != nil {
+ return nil, err
+ }
+
+ mounts := map[string]*MountOutput{}
+ for k, v := range result {
+ switch v.(type) {
+ case map[string]interface{}:
+ default:
+ continue
+ }
+ var res MountOutput
+ err = mapstructure.Decode(v, &res)
+ if err != nil {
+ return nil, err
+ }
+ // Not a mount, some other api.Secret data
+ if res.Type == "" {
+ continue
+ }
+ mounts[k] = &res
+ }
+
+ return mounts, nil
+}
+
+func (c *Sys) Mount(path string, mountInfo *MountInput) error {
+ body := structs.Map(mountInfo)
+
+ r := c.c.NewRequest("POST", fmt.Sprintf("/v1/sys/mounts/%s", path))
+ if err := r.SetJSONBody(body); err != nil {
+ return err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
+}
+
+func (c *Sys) Unmount(path string) error {
+ r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/mounts/%s", path))
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) Remount(from, to string) error {
+ body := map[string]interface{}{
+ "from": from,
+ "to": to,
+ }
+
+ r := c.c.NewRequest("POST", "/v1/sys/remount")
+ if err := r.SetJSONBody(body); err != nil {
+ return err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) TuneMount(path string, config MountConfigInput) error {
+ body := structs.Map(config)
+ r := c.c.NewRequest("POST", fmt.Sprintf("/v1/sys/mounts/%s/tune", path))
+ if err := r.SetJSONBody(body); err != nil {
+ return err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) MountConfig(path string) (*MountConfigOutput, error) {
+ r := c.c.NewRequest("GET", fmt.Sprintf("/v1/sys/mounts/%s/tune", path))
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result MountConfigOutput
+ err = resp.DecodeJSON(&result)
+ if err != nil {
+ return nil, err
+ }
+
+ return &result, err
+}
+
+type MountInput struct {
+ Type string `json:"type" structs:"type"`
+ Description string `json:"description" structs:"description"`
+ Config MountConfigInput `json:"config" structs:"config"`
+}
+
+type MountConfigInput struct {
+ DefaultLeaseTTL string `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
+ MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
+}
+
+type MountOutput struct {
+ Type string `json:"type" structs:"type"`
+ Description string `json:"description" structs:"description"`
+ Config MountConfigOutput `json:"config" structs:"config"`
+}
+
+type MountConfigOutput struct {
+ DefaultLeaseTTL int `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
+ MaxLeaseTTL int `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_policy.go b/vendor/github.com/hashicorp/vault/api/sys_policy.go
new file mode 100644
index 0000000..ba0e17f
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_policy.go
@@ -0,0 +1,95 @@
+package api
+
+import "fmt"
+
+func (c *Sys) ListPolicies() ([]string, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/policy")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result map[string]interface{}
+ err = resp.DecodeJSON(&result)
+ if err != nil {
+ return nil, err
+ }
+
+ var ok bool
+ if _, ok = result["policies"]; !ok {
+ return nil, fmt.Errorf("policies not found in response")
+ }
+
+ listRaw := result["policies"].([]interface{})
+ var policies []string
+
+ for _, val := range listRaw {
+ policies = append(policies, val.(string))
+ }
+
+ return policies, err
+}
+
+func (c *Sys) GetPolicy(name string) (string, error) {
+ r := c.c.NewRequest("GET", fmt.Sprintf("/v1/sys/policy/%s", name))
+ resp, err := c.c.RawRequest(r)
+ if resp != nil {
+ defer resp.Body.Close()
+ if resp.StatusCode == 404 {
+ return "", nil
+ }
+ }
+ if err != nil {
+ return "", err
+ }
+
+ var result map[string]interface{}
+ err = resp.DecodeJSON(&result)
+ if err != nil {
+ return "", err
+ }
+
+ var ok bool
+ if _, ok = result["rules"]; !ok {
+ return "", fmt.Errorf("rules not found in response")
+ }
+
+ return result["rules"].(string), nil
+}
+
+func (c *Sys) PutPolicy(name, rules string) error {
+ body := map[string]string{
+ "rules": rules,
+ }
+
+ r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/sys/policy/%s", name))
+ if err := r.SetJSONBody(body); err != nil {
+ return err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ return nil
+}
+
+func (c *Sys) DeletePolicy(name string) error {
+ r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/policy/%s", name))
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+type getPoliciesResp struct {
+ Rules string `json:"rules"`
+}
+
+type listPoliciesResp struct {
+ Policies []string `json:"policies"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_rekey.go b/vendor/github.com/hashicorp/vault/api/sys_rekey.go
new file mode 100644
index 0000000..e6d039e
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_rekey.go
@@ -0,0 +1,202 @@
+package api
+
+func (c *Sys) RekeyStatus() (*RekeyStatusResponse, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/rekey/init")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result RekeyStatusResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) RekeyRecoveryKeyStatus() (*RekeyStatusResponse, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/rekey-recovery-key/init")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result RekeyStatusResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) RekeyInit(config *RekeyInitRequest) (*RekeyStatusResponse, error) {
+ r := c.c.NewRequest("PUT", "/v1/sys/rekey/init")
+ if err := r.SetJSONBody(config); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result RekeyStatusResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) RekeyRecoveryKeyInit(config *RekeyInitRequest) (*RekeyStatusResponse, error) {
+ r := c.c.NewRequest("PUT", "/v1/sys/rekey-recovery-key/init")
+ if err := r.SetJSONBody(config); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result RekeyStatusResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) RekeyCancel() error {
+ r := c.c.NewRequest("DELETE", "/v1/sys/rekey/init")
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) RekeyRecoveryKeyCancel() error {
+ r := c.c.NewRequest("DELETE", "/v1/sys/rekey-recovery-key/init")
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) RekeyUpdate(shard, nonce string) (*RekeyUpdateResponse, error) {
+ body := map[string]interface{}{
+ "key": shard,
+ "nonce": nonce,
+ }
+
+ r := c.c.NewRequest("PUT", "/v1/sys/rekey/update")
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result RekeyUpdateResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) RekeyRecoveryKeyUpdate(shard, nonce string) (*RekeyUpdateResponse, error) {
+ body := map[string]interface{}{
+ "key": shard,
+ "nonce": nonce,
+ }
+
+ r := c.c.NewRequest("PUT", "/v1/sys/rekey-recovery-key/update")
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result RekeyUpdateResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) RekeyRetrieveBackup() (*RekeyRetrieveResponse, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/rekey/backup")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result RekeyRetrieveResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) RekeyRetrieveRecoveryBackup() (*RekeyRetrieveResponse, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/rekey/recovery-backup")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result RekeyRetrieveResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+func (c *Sys) RekeyDeleteBackup() error {
+ r := c.c.NewRequest("DELETE", "/v1/sys/rekey/backup")
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+
+ return err
+}
+
+func (c *Sys) RekeyDeleteRecoveryBackup() error {
+ r := c.c.NewRequest("DELETE", "/v1/sys/rekey/recovery-backup")
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+
+ return err
+}
+
+type RekeyInitRequest struct {
+ SecretShares int `json:"secret_shares"`
+ SecretThreshold int `json:"secret_threshold"`
+ PGPKeys []string `json:"pgp_keys"`
+ Backup bool
+}
+
+type RekeyStatusResponse struct {
+ Nonce string
+ Started bool
+ T int
+ N int
+ Progress int
+ Required int
+ PGPFingerprints []string `json:"pgp_fingerprints"`
+ Backup bool
+}
+
+type RekeyUpdateResponse struct {
+ Nonce string
+ Complete bool
+ Keys []string
+ KeysB64 []string `json:"keys_base64"`
+ PGPFingerprints []string `json:"pgp_fingerprints"`
+ Backup bool
+}
+
+type RekeyRetrieveResponse struct {
+ Nonce string
+ Keys map[string][]string
+ KeysB64 map[string][]string `json:"keys_base64"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_rotate.go b/vendor/github.com/hashicorp/vault/api/sys_rotate.go
new file mode 100644
index 0000000..8108dce
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_rotate.go
@@ -0,0 +1,30 @@
+package api
+
+import "time"
+
+func (c *Sys) Rotate() error {
+ r := c.c.NewRequest("POST", "/v1/sys/rotate")
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) KeyStatus() (*KeyStatus, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/key-status")
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ result := new(KeyStatus)
+ err = resp.DecodeJSON(result)
+ return result, err
+}
+
+type KeyStatus struct {
+ Term int `json:"term"`
+ InstallTime time.Time `json:"install_time"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_seal.go b/vendor/github.com/hashicorp/vault/api/sys_seal.go
new file mode 100644
index 0000000..b80e33a
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_seal.go
@@ -0,0 +1,59 @@
+package api
+
+func (c *Sys) SealStatus() (*SealStatusResponse, error) {
+ r := c.c.NewRequest("GET", "/v1/sys/seal-status")
+ return sealStatusRequest(c, r)
+}
+
+func (c *Sys) Seal() error {
+ r := c.c.NewRequest("PUT", "/v1/sys/seal")
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}
+
+func (c *Sys) ResetUnsealProcess() (*SealStatusResponse, error) {
+ body := map[string]interface{}{"reset": true}
+
+ r := c.c.NewRequest("PUT", "/v1/sys/unseal")
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ return sealStatusRequest(c, r)
+}
+
+func (c *Sys) Unseal(shard string) (*SealStatusResponse, error) {
+ body := map[string]interface{}{"key": shard}
+
+ r := c.c.NewRequest("PUT", "/v1/sys/unseal")
+ if err := r.SetJSONBody(body); err != nil {
+ return nil, err
+ }
+
+ return sealStatusRequest(c, r)
+}
+
+func sealStatusRequest(c *Sys, r *Request) (*SealStatusResponse, error) {
+ resp, err := c.c.RawRequest(r)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var result SealStatusResponse
+ err = resp.DecodeJSON(&result)
+ return &result, err
+}
+
+type SealStatusResponse struct {
+ Sealed bool `json:"sealed"`
+ T int `json:"t"`
+ N int `json:"n"`
+ Progress int `json:"progress"`
+ Version string `json:"version"`
+ ClusterName string `json:"cluster_name,omitempty"`
+ ClusterID string `json:"cluster_id,omitempty"`
+}
diff --git a/vendor/github.com/hashicorp/vault/api/sys_stepdown.go b/vendor/github.com/hashicorp/vault/api/sys_stepdown.go
new file mode 100644
index 0000000..421e5f1
--- /dev/null
+++ b/vendor/github.com/hashicorp/vault/api/sys_stepdown.go
@@ -0,0 +1,10 @@
+package api
+
+func (c *Sys) StepDown() error {
+ r := c.c.NewRequest("PUT", "/v1/sys/step-down")
+ resp, err := c.c.RawRequest(r)
+ if err == nil {
+ defer resp.Body.Close()
+ }
+ return err
+}