Merge PR #9060: Support reading Raft TLS flags from file

This commit is contained in:
Alexander Bezobchuk 2020-05-23 11:09:55 -04:00 committed by GitHub
parent 7e5d68a73e
commit 378ec869db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 7 deletions

View File

@ -11,6 +11,7 @@ CHANGES:
IMPROVEMENTS:
* cli: Support reading TLS parameters from file for the `vault operator raft join` command. [[GH-9060](https://github.com/hashicorp/vault/pull/9060)]
* plugin: Add SDK method, `Sys.ReloadPlugin`, and CLI command, `vault plugin reload`,
for reloading plugins. [[GH-8777](https://github.com/hashicorp/vault/pull/8777)]
* sdk/framework: Support accepting TypeFloat parameters over the API [[GH-8923](https://github.com/hashicorp/vault/pull/8923)]

View File

@ -4,9 +4,11 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"strings"
"time"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/api"
kvbuilder "github.com/hashicorp/vault/internalshared/kv-builder"
"github.com/kr/text"
@ -273,3 +275,20 @@ func humanDurationInt(i interface{}) interface{} {
// If we don't know what type it is, just return the original value
return i
}
// parseFlagFile accepts a flag value returns the contets of that value. If the
// value starts with '@', that indicates the value is a file and its content
// should be read and returned. Otherwise, the raw value is returned.
func parseFlagFile(raw string) (string, error) {
// check if the provided argument should be read from file
if len(raw) > 0 && raw[0] == '@' {
contents, err := ioutil.ReadFile(raw[1:])
if err != nil {
return "", errwrap.Wrapf("error reading file: {{err}}", err)
}
return string(contents), nil
}
return raw, nil
}

View File

@ -160,3 +160,52 @@ func TestTruncateToSeconds(t *testing.T) {
})
}
}
func TestParseFlagFile(t *testing.T) {
t.Parallel()
content := "some raw content"
tmpFile, err := ioutil.TempFile(os.TempDir(), "TestParseFlagFile")
if err != nil {
t.Fatalf("failed to create temporary file: %v", err)
}
defer os.Remove(tmpFile.Name())
if _, err := tmpFile.WriteString(content); err != nil {
t.Fatalf("failed to write to temporary file: %v", err)
}
cases := []struct {
value string
exp string
}{
{
"",
"",
},
{
content,
content,
},
{
fmt.Sprintf("@%s", tmpFile.Name()),
content,
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.value, func(t *testing.T) {
content, err := parseFlagFile(tc.value)
if err != nil {
t.Fatalf("unexpected error parsing flag value: %v", err)
}
if content != tc.exp {
t.Fatalf("expected %s to be %s", content, tc.exp)
}
})
}
}

View File

@ -32,7 +32,15 @@ Usage: vault operator raft join [options] <leader-api-addr>
Join the current node as a peer to the Raft cluster by providing the address
of the Raft leader node.
$ vault operator raft join "http://127.0.0.2:8200"
$ vault operator raft join "http://127.0.0.2:8200"
TLS certificate data can also be consumed from a file on disk by prefixing with
the "@" symbol. For example:
$ vault operator raft join "http://127.0.0.2:8200" \
-leader-ca-cert=@leader_ca.crt \
-leader-client-cert=@leader_client.crt \
-leader-client-key=@leader.key
` + c.Flags().Help()
@ -114,6 +122,24 @@ func (c *OperatorRaftJoinCommand) Run(args []string) int {
return 1
}
leaderCACert, err := parseFlagFile(c.flagLeaderCACert)
if err != nil {
c.UI.Error(fmt.Sprintf("Failed to parse leader CA certificate: %s", err))
return 1
}
leaderClientCert, err := parseFlagFile(c.flagLeaderClientCert)
if err != nil {
c.UI.Error(fmt.Sprintf("Failed to parse leader client certificate: %s", err))
return 1
}
leaderClientKey, err := parseFlagFile(c.flagLeaderClientKey)
if err != nil {
c.UI.Error(fmt.Sprintf("Failed to parse leader client key: %s", err))
return 1
}
client, err := c.Client()
if err != nil {
c.UI.Error(err.Error())
@ -122,9 +148,9 @@ func (c *OperatorRaftJoinCommand) Run(args []string) int {
resp, err := client.Sys().RaftJoin(&api.RaftJoinRequest{
LeaderAPIAddr: leaderAPIAddr,
LeaderCACert: c.flagLeaderCACert,
LeaderClientCert: c.flagLeaderClientCert,
LeaderClientKey: c.flagLeaderClientKey,
LeaderCACert: leaderCACert,
LeaderClientCert: leaderClientCert,
LeaderClientKey: leaderClientKey,
Retry: c.flagRetry,
NonVoter: c.flagNonVoter,
})
@ -139,9 +165,10 @@ func (c *OperatorRaftJoinCommand) Run(args []string) int {
return OutputData(c.UI, resp)
}
out := []string{}
out = append(out, "Key | Value")
out = append(out, fmt.Sprintf("Joined | %t", resp.Joined))
out := []string{
"Key | Value",
fmt.Sprintf("Joined | %t", resp.Joined),
}
c.UI.Output(tableOutput(out, nil))
return 0