Skip to content

Commit

Permalink
raft join tls
Browse files Browse the repository at this point in the history
  • Loading branch information
vishalnayak committed Jun 21, 2019
1 parent b243edf commit b0cd36d
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 14 deletions.
8 changes: 5 additions & 3 deletions api/sys_raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ type RaftJoinResponse struct {

// RaftJoinRequest represents the parameters consumed by the raft join API
type RaftJoinRequest struct {
LeaderAddr string `json:"leader_api_addr"`
CACert string `json:"ca_cert":`
Retry bool `json:"retry"`
LeaderAPIAddr string `json:"leader_api_addr"`
LeaderCACert string `json:"leader_ca_cert":`
LeaderClientCert string `json:"leader_client_cert"`
LeaderClientKey string `json:"leader_client_key"`
Retry bool `json:"retry"`
}

// RaftJoin adds the node from which this call is invoked from to the raft
Expand Down
32 changes: 25 additions & 7 deletions command/operator_raft_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ var _ cli.Command = (*OperatorRaftJoinCommand)(nil)
var _ cli.CommandAutocomplete = (*OperatorRaftJoinCommand)(nil)

type OperatorRaftJoinCommand struct {
flagRaftRetry bool
flagRaftCACert string
flagRaftRetry bool
flagLeaderCACert string
flagLeaderClientCert string
flagLeaderClientKey string
*BaseCommand
}

Expand Down Expand Up @@ -42,12 +44,26 @@ func (c *OperatorRaftJoinCommand) Flags() *FlagSets {
f := set.NewFlagSet("Command Options")

f.StringVar(&StringVar{
Name: "raft-ca-cert",
Target: &c.flagRaftCACert,
Name: "leader-ca-cert",
Target: &c.flagLeaderCACert,
Completion: complete.PredictNothing,
Usage: "CA cert to communicate with raft leader.",
})

f.StringVar(&StringVar{
Name: "leader-client-cert",
Target: &c.flagLeaderClientCert,
Completion: complete.PredictNothing,
Usage: "Client cert to to authenticate to raft leader.",
})

f.StringVar(&StringVar{
Name: "leader-client-key",
Target: &c.flagLeaderClientKey,
Completion: complete.PredictNothing,
Usage: "Client key to to authenticate to raft leader.",
})

f.BoolVar(&BoolVar{
Name: "retry",
Target: &c.flagRaftRetry,
Expand Down Expand Up @@ -97,9 +113,11 @@ func (c *OperatorRaftJoinCommand) Run(args []string) int {
}

resp, err := client.Sys().RaftJoin(&api.RaftJoinRequest{
LeaderAddr: leaderAPIAddr,
Retry: c.flagRaftRetry,
CACert: c.flagRaftCACert,
LeaderAPIAddr: leaderAPIAddr,
LeaderCACert: c.flagLeaderCACert,
LeaderClientCert: c.flagLeaderClientCert,
LeaderClientKey: c.flagLeaderClientKey,
Retry: c.flagRaftRetry,
})
if err != nil {
c.UI.Error(fmt.Sprintf("Error joining the node to the raft cluster: %s", err))
Expand Down
47 changes: 43 additions & 4 deletions http/sys_raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package http

import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io"
"net/http"

Expand All @@ -27,7 +31,40 @@ func handleSysRaftJoinPost(core *vault.Core, w http.ResponseWriter, r *http.Requ
return
}

joined, err := core.JoinRaftCluster(context.Background(), req.LeaderAddr, nil, req.Retry)
var tlsConfig *tls.Config
switch {
case req.LeaderCACert != "" && req.LeaderClientCert != "" && req.LeaderClientKey != "":
// Create TLS Config
pool := x509.NewCertPool()
pool.AppendCertsFromPEM([]byte(req.LeaderCACert))

cert, err := tls.X509KeyPair([]byte(req.LeaderClientCert), []byte(req.LeaderClientKey))
if err != nil {
respondError(w, http.StatusBadRequest, fmt.Errorf("invalid key pair: %v", err))
return
}

tlsConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: pool,
ClientAuth: tls.RequireAndVerifyClientCert,
MinVersion: tls.VersionTLS12,
}

tlsConfig.BuildNameToCertificate()

case req.LeaderCACert != "":
respondError(w, http.StatusBadRequest, errors.New("ca_cert, client_key, client_cert must all be set; or none should be set"))
return
case req.LeaderClientCert != "":
respondError(w, http.StatusBadRequest, errors.New("ca_cert, client_key, client_cert must all be set; or none should be set"))
return
case req.LeaderClientKey != "":
respondError(w, http.StatusBadRequest, errors.New("ca_cert, client_key, client_cert must all be set; or none should be set"))
return
}

joined, err := core.JoinRaftCluster(context.Background(), req.LeaderAPIAddr, tlsConfig, req.Retry)
if err != nil {
respondError(w, http.StatusInternalServerError, err)
return
Expand All @@ -44,7 +81,9 @@ type JoinResponse struct {
}

type JoinRequest struct {
LeaderAddr string `json:"leader_api_addr"`
CACert string `json:"ca_cert":`
Retry bool `json:"retry"`
LeaderAPIAddr string `json:"leader_api_addr"`
LeaderCACert string `json:"leader_ca_cert":`
LeaderClientCert string `json:"leader_client_cert"`
LeaderClientKey string `json:"leader_client_key"`
Retry bool `json:"retry"`
}

0 comments on commit b0cd36d

Please sign in to comment.