Global flag that outputs minimum policy HCL required for an operation (#14899)

* WIP: output policy

* Outputs example policy HCL for given request

* Simplify conditional

* Add PATCH capability

* Use OpenAPI spec and regex patterns to determine if path is sudo

* Add test for isSudoPath

* Add changelog

* Fix broken CLI tests

* Add output-policy to client cloning code

* Smaller fixes from PR comments

* Clone client instead of saving and restoring custom values

* Fix test

* Address comments

* Don't unset output-policy flag on KV requests otherwise the preflight request will fail and not populate LastOutputPolicyError

* Print errors saved in buffer from preflight KV requests

* Unescape characters in request URL

* Rename methods and properties to improve readability

* Put KV-specificness at front of KV-specific error

* Simplify logic by doing more direct returns of strings and errors

* Use precompiled regexes and move OpenAPI call to tests

* Remove commented out code

* Remove legacy MFA paths

* Remove unnecessary use of client

* Move sudo paths map to plugin helper

* Remove unused error return

* Add explanatory comment

* Remove need to pass in address

* Make {name} regex less greedy

* Use method and path instead of info from retryablerequest

* Add test for IsSudoPaths, use more idiomatic naming

* Use precompiled regexes and move OpenAPI call to tests (#15170)

* Use precompiled regexes and move OpenAPI call to tests

* Remove commented out code

* Remove legacy MFA paths

* Remove unnecessary use of client

* Move sudo paths map to plugin helper

* Remove unused error return

* Add explanatory comment

* Remove need to pass in address

* Make {name} regex less greedy

* Use method and path instead of info from retryablerequest

* Add test for IsSudoPaths, use more idiomatic naming

* Make stderr writing more obvious, fix nil pointer deref
This commit is contained in:
VAL
2022-04-27 16:35:18 -07:00
committed by GitHub
parent f36d07249f
commit 7089487509
15 changed files with 508 additions and 58 deletions

View File

@@ -143,6 +143,14 @@ type Config struct {
// with the same client. Cloning a client will not clone this value.
OutputCurlString bool
// OutputPolicy causes the actual request to return an error of type
// *OutputPolicyError. Type asserting the error message will display
// an example of the required policy HCL needed for the operation.
//
// Note: It is not thread-safe to set this and make concurrent requests
// with the same client. Cloning a client will not clone this value.
OutputPolicy bool
// curlCACert, curlCAPath, curlClientCert and curlClientKey are used to keep
// track of the name of the TLS certs and keys when OutputCurlString is set.
// Cloning a client will also not clone those values.
@@ -779,6 +787,24 @@ func (c *Client) SetOutputCurlString(curl bool) {
c.config.OutputCurlString = curl
}
func (c *Client) OutputPolicy() bool {
c.modifyLock.RLock()
defer c.modifyLock.RUnlock()
c.config.modifyLock.RLock()
defer c.config.modifyLock.RUnlock()
return c.config.OutputPolicy
}
func (c *Client) SetOutputPolicy(isSet bool) {
c.modifyLock.RLock()
defer c.modifyLock.RUnlock()
c.config.modifyLock.Lock()
defer c.config.modifyLock.Unlock()
c.config.OutputPolicy = isSet
}
// CurrentWrappingLookupFunc sets a lookup function that returns desired wrap TTLs
// for a given operation and path.
func (c *Client) CurrentWrappingLookupFunc() WrappingLookupFunc {
@@ -1172,6 +1198,7 @@ func (c *Client) rawRequestWithContext(ctx context.Context, r *Request) (*Respon
httpClient := c.config.HttpClient
ns := c.headers.Get(consts.NamespaceHeaderName)
outputCurlString := c.config.OutputCurlString
outputPolicy := c.config.OutputPolicy
logger := c.config.Logger
c.config.modifyLock.RUnlock()
@@ -1225,6 +1252,14 @@ START:
return nil, LastOutputStringError
}
if outputPolicy {
LastOutputPolicyError = &OutputPolicyError{
method: req.Method,
path: strings.TrimPrefix(req.URL.Path, "/v1"),
}
return nil, LastOutputPolicyError
}
req.Request = req.Request.WithContext(ctx)
if backoff == nil {
@@ -1317,6 +1352,8 @@ func (c *Client) httpRequestWithContext(ctx context.Context, r *Request) (*Respo
limiter := c.config.Limiter
httpClient := c.config.HttpClient
outputCurlString := c.config.OutputCurlString
outputPolicy := c.config.OutputPolicy
// add headers
if c.headers != nil {
for header, vals := range c.headers {
@@ -1333,10 +1370,13 @@ func (c *Client) httpRequestWithContext(ctx context.Context, r *Request) (*Respo
c.config.modifyLock.RUnlock()
c.modifyLock.RUnlock()
// OutputCurlString logic relies on the request type to be retryable.Request as
// OutputCurlString and OutputPolicy logic rely on the request type to be retryable.Request
if outputCurlString {
return nil, fmt.Errorf("output-curl-string is not implemented for this request")
}
if outputPolicy {
return nil, fmt.Errorf("output-policy is not implemented for this request")
}
req.URL.User = r.URL.User
req.URL.Scheme = r.URL.Scheme