-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the ability to print curl commands from CLI #6113
Merged
Changes from 6 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
440f0ce
Add framework for spitting out curl commands, translation not done yet
jefferai 1432ebe
More plumbing, possibly complete
jefferai a1de8e5
Update clone logic
jefferai 5fea799
Rename a few things
jefferai 9d2ebe2
Fix error text
jefferai 0b8a3da
Add print token command for curl output
jefferai 3412bfb
Merge branch 'master-oss' into curl-cmds
jefferai 0d938e1
Merge branch 'master' into curl-cmds
jefferai 6b38d5c
Merge branch 'master-oss' into curl-cmds
jefferai File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package api | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
retryablehttp "github.com/hashicorp/go-retryablehttp" | ||
) | ||
|
||
const ( | ||
ErrOutputStringRequest = "output a string, please" | ||
) | ||
|
||
var ( | ||
LastOutputStringError *OutputStringError | ||
) | ||
|
||
type OutputStringError struct { | ||
*retryablehttp.Request | ||
parsingError error | ||
parsedCurlString string | ||
} | ||
|
||
func (d *OutputStringError) Error() string { | ||
if d.parsedCurlString == "" { | ||
d.parseRequest() | ||
if d.parsingError != nil { | ||
return d.parsingError.Error() | ||
} | ||
} | ||
|
||
return ErrOutputStringRequest | ||
} | ||
|
||
func (d *OutputStringError) parseRequest() { | ||
body, err := d.Request.BodyBytes() | ||
if err != nil { | ||
d.parsingError = err | ||
return | ||
} | ||
|
||
// Build cURL string | ||
d.parsedCurlString = "curl " | ||
d.parsedCurlString = fmt.Sprintf("%s-X %s ", d.parsedCurlString, d.Request.Method) | ||
for k, v := range d.Request.Header { | ||
for _, h := range v { | ||
if strings.ToLower(k) == "x-vault-token" { | ||
h = `$(vault print token)` | ||
} | ||
d.parsedCurlString = fmt.Sprintf("%s-H \"%s: %s\" ", d.parsedCurlString, k, h) | ||
} | ||
} | ||
|
||
if len(body) > 0 { | ||
// We need to escape single quotes since that's what we're using to | ||
// quote the body | ||
escapedBody := strings.Replace(string(body), "'", "'\"'\"'", -1) | ||
d.parsedCurlString = fmt.Sprintf("%s-d '%s' ", d.parsedCurlString, escapedBody) | ||
} | ||
|
||
d.parsedCurlString = fmt.Sprintf("%s%s", d.parsedCurlString, d.Request.URL.String()) | ||
} | ||
|
||
func (d *OutputStringError) CurlString() string { | ||
if d.parsedCurlString == "" { | ||
d.parseRequest() | ||
} | ||
return d.parsedCurlString | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package command | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/mitchellh/cli" | ||
"github.com/posener/complete" | ||
) | ||
|
||
var _ cli.Command = (*PrintTokenCommand)(nil) | ||
var _ cli.CommandAutocomplete = (*PrintTokenCommand)(nil) | ||
|
||
type PrintTokenCommand struct { | ||
*BaseCommand | ||
} | ||
|
||
func (c *PrintTokenCommand) Synopsis() string { | ||
return "Prints the contents of a policy" | ||
} | ||
|
||
func (c *PrintTokenCommand) Help() string { | ||
helpText := ` | ||
Usage: vault print token | ||
|
||
Prints the value of the Vault token that will be used for commands, after | ||
taking into account the configured token-helper and the environment. | ||
|
||
$ vault print token | ||
|
||
` + c.Flags().Help() | ||
|
||
return strings.TrimSpace(helpText) | ||
} | ||
|
||
func (c *PrintTokenCommand) Flags() *FlagSets { | ||
return nil | ||
} | ||
|
||
func (c *PrintTokenCommand) AutocompleteArgs() complete.Predictor { | ||
return nil | ||
} | ||
|
||
func (c *PrintTokenCommand) AutocompleteFlags() complete.Flags { | ||
return nil | ||
} | ||
|
||
func (c *PrintTokenCommand) Run(args []string) int { | ||
client, err := c.Client() | ||
if err != nil { | ||
c.UI.Error(err.Error()) | ||
return 2 | ||
} | ||
|
||
c.UI.Output(client.Token()) | ||
return 0 | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to redact known-sensitive headers such as
X-Vault-Token
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, when it comes down to it if someone is sitting at your terminal they can easily get your token other ways. We could maybe require they put the token in an env var but it kind of breaks the point.
Maybe I'll just enhance the flag doc to explicitly mention it will do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just added a commit that changes things a little, and I'm curious about feedback. Instead of printing the token, I added a
vault print token
command (although maybe if we think there might be more things like this coming up it should bevault debug print-token
or so), and the curl string now uses that in a bash escape.Three items for feedback:
This will work with bash and zsh but not fish. Fish doesn't use backticks either, so...I guess if someone is interested they can submit a PR to check for the running shell env var and change up the output. It also obviously does not work on Windows; same story there, if people want it they could submit a PR to modify the output based on GOOS
Is this even a good idea? I'm not sure it's a bad idea. There are plenty of ways to fetch the Vault token: read the env var, read the file, or if you are using an external token helper this will still require any extra authentication to be performed as with a normal Vault call. You could also, on a machine with a connection to Vault and a normal default policy, call
vault token lookup
and get it. On the flip side, doing it this way means the curl commands are emailable/portable -- you can send someone the line without having to do substitution. So I think it's a net neutral or positive.vault print token
vs.vault debug print-token
. Depends what we think we might have in the future. If we think we might have debuggish type stuff the latter makes sense. If we think we'll have more things to specifically print later, the former makes sense.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the approach as you've implemented it. Keeps the token out of the history but output is still generally copy-pasteable. I think I prefer
vault print token
, as this feels like a generally useful capability, especially when token helpers are in the mix.