More syncing

This commit is contained in:
Jeff Mitchell 2017-10-23 16:52:56 -04:00
parent 8e9317792d
commit 8e271dcbdc
7 changed files with 65 additions and 19 deletions

View File

@ -32,6 +32,7 @@ const EnvVaultTLSServerName = "VAULT_TLS_SERVER_NAME"
const EnvVaultWrapTTL = "VAULT_WRAP_TTL"
const EnvVaultMaxRetries = "VAULT_MAX_RETRIES"
const EnvVaultToken = "VAULT_TOKEN"
const EnvVaultMFA = "VAULT_MFA"
// 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.
@ -236,14 +237,23 @@ func (c *Config) ReadEnvironment() error {
return nil
}
// Client is the client to the Vault API. Create a client with
// NewClient.
// Client is the client to the Vault API. Create a client with NewClient. Note:
// it is not safe to modify client configuration from multiple goroutines at
// once. Set configuration first, then run requests.
type Client struct {
addr *url.URL
config *Config
token string
headers http.Header
wrappingLookupFunc WrappingLookupFunc
mfaCreds []string
policyOverride bool
}
// SetMFACreds sets the MFA credentials supplied either via the environment
// variable or via the command line.
func (c *Client) SetMFACreds(creds []string) {
c.mfaCreds = creds
}
// NewClient returns a new client for the given configuration.
@ -365,6 +375,13 @@ func (c *Client) Clone() (*Client, error) {
return NewClient(c.config)
}
// SetPolicyOverride sets whether requests should be sent with the policy
// override flag to request overriding soft-mandatory Sentinel policies (both
// RGPs and EGPs)
func (c *Client) SetPolicyOverride(override bool) {
c.policyOverride = override
}
// 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.
@ -401,6 +418,9 @@ func (c *Client) NewRequest(method, requestPath string) *Request {
default:
lookupPath = requestPath
}
req.MFAHeaderVals = c.mfaCreds
if c.wrappingLookupFunc != nil {
req.WrapTTL = c.wrappingLookupFunc(method, lookupPath)
} else {
@ -413,6 +433,8 @@ func (c *Client) NewRequest(method, requestPath string) *Request {
req.Headers = c.headers
}
req.PolicyOverride = c.policyOverride
return req
}

View File

@ -16,10 +16,16 @@ type Request struct {
Params url.Values
Headers http.Header
ClientToken string
MFAHeaderVals []string
WrapTTL string
Obj interface{}
Body io.Reader
BodySize int64
// Whether to request overriding soft-mandatory Sentinel policies (RGPs and
// EGPs). If set, the override flag will take effect for all policies
// evaluated during the request.
PolicyOverride bool
}
// SetJSONBody is used to set a request body that is a JSON-encoded value.
@ -77,5 +83,15 @@ func (r *Request) ToHTTP() (*http.Request, error) {
req.Header.Set("X-Vault-Wrap-TTL", r.WrapTTL)
}
if len(r.MFAHeaderVals) != 0 {
for _, mfaHeaderVal := range r.MFAHeaderVals {
req.Header.Add("X-Vault-MFA", mfaHeaderVal)
}
}
if r.PolicyOverride {
req.Header.Set("X-Vault-Policy-Override", "true")
}
return req, nil
}

View File

@ -132,6 +132,7 @@ type MountConfigInput struct {
MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"`
PluginName string `json:"plugin_name,omitempty" structs:"plugin_name,omitempty" mapstructure:"plugin_name"`
SealWrap bool `json:"seal_wrap" structs:"seal_wrap" mapstructure:"seal_wrap"`
}
type MountOutput struct {
@ -147,4 +148,5 @@ type MountConfigOutput struct {
MaxLeaseTTL int `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"`
PluginName string `json:"plugin_name,omitempty" structs:"plugin_name,omitempty" mapstructure:"plugin_name"`
SealWrap bool `json:"seal_wrap" structs:"seal_wrap" mapstructure:"seal_wrap"`
}

View File

@ -50,12 +50,14 @@ func (c *Sys) GetPolicy(name string) (string, error) {
return "", err
}
var ok bool
if _, ok = result["rules"]; !ok {
return "", fmt.Errorf("rules not found in response")
if rulesRaw, ok := result["rules"]; ok {
return rulesRaw.(string), nil
}
if policyRaw, ok := result["policy"]; ok {
return policyRaw.(string), nil
}
return result["rules"].(string), nil
return "", fmt.Errorf("no policy found in response")
}
func (c *Sys) PutPolicy(name, rules string) error {

View File

@ -171,6 +171,7 @@ func (c *Sys) RekeyDeleteRecoveryBackup() error {
type RekeyInitRequest struct {
SecretShares int `json:"secret_shares"`
SecretThreshold int `json:"secret_threshold"`
StoredShares int `json:"stored_shares"`
PGPKeys []string `json:"pgp_keys"`
Backup bool
}

View File

@ -134,6 +134,7 @@ func (f *AuditFormatter) FormatRequest(
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
PolicyOverride: req.PolicyOverride,
RemoteAddr: getRemoteAddr(req),
ReplicationCluster: req.ReplicationCluster,
Headers: req.Headers,
@ -310,11 +311,11 @@ func (f *AuditFormatter) FormatResponse(
Type: "response",
Error: errString,
Auth: AuditAuth{
ClientToken: auth.ClientToken,
Accessor: auth.Accessor,
DisplayName: auth.DisplayName,
Policies: auth.Policies,
Metadata: auth.Metadata,
ClientToken: auth.ClientToken,
Accessor: auth.Accessor,
RemainingUses: req.ClientTokenRemainingUses,
EntityID: auth.EntityID,
},
@ -326,6 +327,7 @@ func (f *AuditFormatter) FormatResponse(
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
PolicyOverride: req.PolicyOverride,
RemoteAddr: getRemoteAddr(req),
ReplicationCluster: req.ReplicationCluster,
Headers: req.Headers,
@ -378,6 +380,7 @@ type AuditRequest struct {
ClientTokenAccessor string `json:"client_token_accessor"`
Path string `json:"path"`
Data map[string]interface{} `json:"data"`
PolicyOverride bool `json:"policy_override"`
RemoteAddr string `json:"remote_address"`
WrapTTL int `json:"wrap_ttl"`
Headers map[string][]string `json:"headers"`

View File

@ -51,7 +51,7 @@ func TestFormatJSONx_formatRequest(t *testing.T) {
errors.New("this is an error"),
"",
"",
fmt.Sprintf(`<json:object name="auth"><json:string name="accessor">bar</json:string><json:string name="client_token">%s</json:string><json:string name="display_name">testtoken</json:string><json:string name="entity_id"></json:string><json:null name="metadata" /><json:array name="policies"><json:string>root</json:string></json:array></json:object><json:string name="error">this is an error</json:string><json:object name="request"><json:string name="client_token"></json:string><json:string name="client_token_accessor"></json:string><json:null name="data" /><json:object name="headers"><json:array name="foo"><json:string>bar</json:string></json:array></json:object><json:string name="id"></json:string><json:string name="operation">update</json:string><json:string name="path">/foo</json:string><json:string name="remote_address">127.0.0.1</json:string><json:number name="wrap_ttl">60</json:number></json:object><json:string name="type">request</json:string>`,
fmt.Sprintf(`<json:object name="auth"><json:string name="accessor">bar</json:string><json:string name="client_token">%s</json:string><json:string name="display_name">testtoken</json:string><json:string name="entity_id"></json:string><json:null name="metadata" /><json:array name="policies"><json:string>root</json:string></json:array></json:object><json:string name="error">this is an error</json:string><json:object name="request"><json:string name="client_token"></json:string><json:string name="client_token_accessor"></json:string><json:null name="data" /><json:object name="headers"><json:array name="foo"><json:string>bar</json:string></json:array></json:object><json:string name="id"></json:string><json:string name="operation">update</json:string><json:string name="path">/foo</json:string><json:boolean name="policy_override">false</json:boolean><json:string name="remote_address">127.0.0.1</json:string><json:number name="wrap_ttl">60</json:number></json:object><json:string name="type">request</json:string>`,
fooSalted),
},
"auth, request with prefix": {
@ -72,7 +72,7 @@ func TestFormatJSONx_formatRequest(t *testing.T) {
errors.New("this is an error"),
"",
"@cee: ",
fmt.Sprintf(`<json:object name="auth"><json:string name="accessor">bar</json:string><json:string name="client_token">%s</json:string><json:string name="display_name">testtoken</json:string><json:string name="entity_id"></json:string><json:null name="metadata" /><json:array name="policies"><json:string>root</json:string></json:array></json:object><json:string name="error">this is an error</json:string><json:object name="request"><json:string name="client_token"></json:string><json:string name="client_token_accessor"></json:string><json:null name="data" /><json:object name="headers"><json:array name="foo"><json:string>bar</json:string></json:array></json:object><json:string name="id"></json:string><json:string name="operation">update</json:string><json:string name="path">/foo</json:string><json:string name="remote_address">127.0.0.1</json:string><json:number name="wrap_ttl">60</json:number></json:object><json:string name="type">request</json:string>`,
fmt.Sprintf(`<json:object name="auth"><json:string name="accessor">bar</json:string><json:string name="client_token">%s</json:string><json:string name="display_name">testtoken</json:string><json:string name="entity_id"></json:string><json:null name="metadata" /><json:array name="policies"><json:string>root</json:string></json:array></json:object><json:string name="error">this is an error</json:string><json:object name="request"><json:string name="client_token"></json:string><json:string name="client_token_accessor"></json:string><json:null name="data" /><json:object name="headers"><json:array name="foo"><json:string>bar</json:string></json:array></json:object><json:string name="id"></json:string><json:string name="operation">update</json:string><json:string name="path">/foo</json:string><json:boolean name="policy_override">false</json:boolean><json:string name="remote_address">127.0.0.1</json:string><json:number name="wrap_ttl">60</json:number></json:object><json:string name="type">request</json:string>`,
fooSalted),
},
}