Skip to content

Commit

Permalink
Merge branch 'etcd_tls_auth' into tpo-master
Browse files Browse the repository at this point in the history
  • Loading branch information
tpo committed Apr 3, 2020
2 parents fb359af + e0ab6d2 commit 2d3f021
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 9 deletions.
78 changes: 77 additions & 1 deletion checker/etcd_leader_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,26 @@ package checker

import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"time"

"github.com/coreos/etcd/client"
"github.com/cybertec-postgresql/vip-manager/vipconfig"
)

const (
envEtcdCaFile = "ETCD_TRUSTED_CA_FILE"
envEtcdCertFile = "ETCD_CERT_FILE"
envEtcdKeyFile = "ETCD_KEY_FILE"
)

type EtcdLeaderChecker struct {
key string
nodename string
Expand All @@ -18,14 +31,77 @@ type EtcdLeaderChecker struct {
//naming this c_conf to avoid conflict with conf in etcd_leader_checker.go
var e_conf vipconfig.Config

func getConfigParameter(conf string, env string) string {
if conf == "none" || conf == "" {
return os.Getenv(env)
}

return conf
}

func getTransport(conf vipconfig.Config) (client.CancelableTransport, error) {
var caCertPool *x509.CertPool

// create valid CertPool only if the ca certificate file exists
if caCertFile := getConfigParameter(conf.Etcd_ca_file, envEtcdCaFile); caCertFile != "" {
caCert, err := ioutil.ReadFile(caCertFile)
if err != nil {
return nil, fmt.Errorf("cannot load CA file: %s", err)
}

caCertPool = x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
}

certFile := getConfigParameter(conf.Etcd_cert_file, envEtcdCertFile)

keyFile := getConfigParameter(conf.Etcd_key_file, envEtcdKeyFile)

var certificates []tls.Certificate

// create valid []Certificate only if the client cert and key files exists
if certFile != "" && keyFile != "" {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, fmt.Errorf("cannot load client cert or key file: %s", err)
}

certificates = []tls.Certificate{cert}
}

var tlsClientConfig *tls.Config

if certificates != nil || caCertPool != nil {
tlsClientConfig = &tls.Config{
RootCAs: caCertPool,
Certificates: certificates,
}
}

return &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSClientConfig: tlsClientConfig,
TLSHandshakeTimeout: 10 * time.Second,
}, nil
}

//func NewEtcdLeaderChecker(endpoint, key, nodename string, etcd_user string, etcd_password string) (*EtcdLeaderChecker, error) {
func NewEtcdLeaderChecker(con vipconfig.Config) (*EtcdLeaderChecker, error) {
e_conf = con
e := &EtcdLeaderChecker{key: e_conf.Key, nodename: e_conf.Nodename}

transport, err := getTransport(e_conf)
if err != nil {
return nil, err
}

cfg := client.Config{
Endpoints: e_conf.Endpoints,
Transport: client.DefaultTransport,
Transport: transport,
HeaderTimeoutPerRequest: time.Second,
Username: e_conf.Etcd_user,
Password: e_conf.Etcd_password,
Expand Down
8 changes: 6 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ var key = flag.String("key", "none", "key to monitor, e.g. /service/batman/leade
var host = flag.String("host", "none", "Value to monitor for")
var etcd_user = flag.String("etcd_user", "none", "username that can be used to access the key in etcd")
var etcd_password = flag.String("etcd_password", "none", "password for the etcd_user")
var etcd_ca_file = flag.String("etcd_ca_file", "none", "trusted CA certificate for the etcd server")
var etcd_cert_file = flag.String("etcd_cert_file", "none", "etcd client certificate")
var etcd_key_file = flag.String("etcd_key_file", "none", "etcd client private key")

var endpointType = flag.String("type", "etcd", "type of endpoint used for key storage. Supported values: etcd, consul")
var endpoint = flag.String("endpoint", "http://localhost:2379[,http://host:port,..]", "endpoint")
Expand Down Expand Up @@ -63,13 +66,14 @@ func main() {
flag.Parse()

if *versionHint == true {
fmt.Println("version 0.6.1")
fmt.Println("version 0.6.2")
return
}
//introduce parsed values into conf
conf = vipconfig.Config{Ip: *ip, Mask: *mask, Iface: *iface, HostingType: *hostingType,
Key: *key, Nodename: *host, Endpoint_type: *endpointType, Endpoints: []string{*endpoint},
Etcd_user: *etcd_user, Etcd_password: *etcd_password, Interval: *interval}
Etcd_user: *etcd_user, Etcd_password: *etcd_password, Etcd_ca_file: *etcd_ca_file,
Etcd_cert_file: *etcd_cert_file, Etcd_key_file: *etcd_key_file, Interval: *interval}

if *configFile != "" {
yamlFile, err := ioutil.ReadFile(*configFile)
Expand Down
7 changes: 7 additions & 0 deletions package/DEBIAN/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
vip-manager (0.6.2-1) unstable; urgency=low

* enable TLS configuration from cli flags and from yaml file
* add TLS support for etcd connections

-- gandalfmagic <[email protected]> Sun, 17 Nov 2019 23:52:12 +0100

vip-manager (0.6-1) unstable; urgency=low

* switched to yaml file for config, still supporting all command line options from previous releases.
Expand Down
15 changes: 9 additions & 6 deletions vipconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ type Config struct {
Key string `yaml:key`
Nodename string `yaml:nodename` //hostname to trigger on. usually the name of the host where this vip-manager runs.

Endpoint_type string `yaml:endpoint_type`
Endpoints []string `yaml:endpoints`
Etcd_user string `yaml:etcd_user`
Etcd_password string `yaml:etcd_password`
Endpoint_type string `yaml:endpoint_type`
Endpoints []string `yaml:endpoints`
Etcd_user string `yaml:etcd_user`
Etcd_password string `yaml:etcd_password`
Etcd_ca_file string `yaml:etcd_ca_file`
Etcd_cert_file string `yaml:etcd_cert_file`
Etcd_key_file string `yaml:etcd_key_file`

Consul_token string `yaml:consul_token`

Interval int`yaml:interval` //milliseconds
Interval int `yaml:interval` //milliseconds

Retry_after int `yaml:retry_after` //milliseconds
Retry_after int `yaml:retry_after` //milliseconds
Retry_num int `yaml:retry_num`
}
4 changes: 4 additions & 0 deletions vipconfig/vip-manager.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ endpoints:

etcd_user: "patroni"
etcd_password: "Julian's secret password"
etcd_ca_file: "/path/to/etcd/trusted/ca/file"
etcd_cert_file: "/path/to/etcd/client/cert/file"
etcd_key_file: "/path/to/etcd/client/key/file"

# don't worry about parameter with a prefix that doesn't match the endpoint_type. You can write anything there, I won't even look at it.
consul_token: "Julian's secret token"

Expand Down

0 comments on commit 2d3f021

Please sign in to comment.