Now supports client certificates.

This commit is contained in:
Paul Jack 2018-08-28 08:52:17 -07:00
parent b288401646
commit e93cf8708b
3 changed files with 61 additions and 183 deletions

View File

@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"time"
etcd "github.com/coreos/etcd/clientv3"
@ -15,16 +14,11 @@ type EasyClient struct {
Timeout time.Duration
}
func NewLocalClient() (*EasyClient, error) {
return NewClient([]string{"localhost"}, 2379)
}
func NewClient(hosts []string, port int) (*EasyClient, error) {
hp := make([]string, 0, len(hosts))
for _, h := range hosts {
hp = append(hp, fmt.Sprintf("%s:%d", h, port))
func NewClient(conf EasyConfig) (*EasyClient, error) {
config, err := conf.prepare()
if err != nil {
return nil, err
}
config := etcd.Config{Endpoints: hp, DialTimeout: 5 * time.Second}
cli, err := etcd.New(config)
if err != nil {
return nil, err

57
easy_config.go Normal file
View File

@ -0,0 +1,57 @@
package etcd_tools
import (
"crypto/tls"
"crypto/x509"
"errors"
"time"
etcd "github.com/coreos/etcd/clientv3"
)
type EasyConfig struct {
Endpoints []string
RootCACert string
ClientCert string
ClientKey string
}
func (c EasyConfig) prepare() (etcd.Config, error) {
cert, err := tls.X509KeyPair([]byte(c.ClientCert), []byte(c.ClientKey))
if err != nil {
return etcd.Config{}, err
}
pool := x509.NewCertPool()
if !pool.AppendCertsFromPEM([]byte(c.RootCACert)) {
return etcd.Config{}, errors.New("Could not append root CA.")
}
tc := &tls.Config{}
tc.Certificates = make([]tls.Certificate, 1)
tc.Certificates[0] = cert
tc.RootCAs = pool
tc.ClientCAs = pool
tc.ClientAuth = tls.RequireAndVerifyClientCert
conn, err := tls.Dial("tcp", "168.245.146.1:2379", tc)
if err != nil {
return etcd.Config{}, err
}
defer conn.Close()
err = conn.Handshake()
if err != nil {
return etcd.Config{}, err
}
// r.TLS.ServerName = "168.245.146.1"
// r.TLS.BuildNameToCertificate()
r := etcd.Config{}
r.Endpoints = c.Endpoints
r.DialTimeout = 5 * time.Second
r.TLS = tc
return r, nil
}

View File

@ -1,173 +0,0 @@
package etcd_tools
import (
"fmt"
"testing"
"time"
etcd "github.com/coreos/etcd/clientv3"
)
var s5 = 5 * time.Second
func DeleteAll(t *testing.T, q *Queue) {
_, err := q.cli.Delete(q.prefix, etcd.WithPrefix())
if err != nil {
t.Fatal(err)
}
}
func TestQueue(t *testing.T) {
cli, err := NewLocalClient()
if err != nil {
t.Fatal(err)
}
defer cli.Close()
q := NewQueue(cli, "foo")
DeleteAll(t, q)
_, err = q.Put("bar1")
if err != nil {
t.Fatal(err)
}
_, err = q.Put("bar2")
if err != nil {
t.Fatal(err)
}
pairs, err := q.Poll()
if err != nil {
t.Fatal(err)
}
for _, ev := range pairs {
_, _ = cli.Delete(string(ev.Key))
}
if len(pairs) != 2 {
t.Fatal("Wrong queue count.")
}
if pairs[0].Value != "bar1" {
t.Fatal("Wrong first element.")
}
if pairs[1].Value != "bar2" {
t.Fatal("Wrong first element.")
}
DeleteAll(t, q)
_, err = q.PutWithTTL("snafu", 5)
if err != nil {
t.Fatal(err)
}
time.Sleep(6 * time.Second)
pairs, err = q.Poll()
if err != nil {
t.Fatal(err)
}
if len(pairs) != 0 {
t.Fatal(fmt.Sprintf("Queue item with ttl did not time out. %s", pairs[0].Value))
}
}
func TestMove(t *testing.T) {
cli, err := NewLocalClient()
if err != nil {
t.Fatal(err)
}
defer cli.Close()
q1 := NewQueue(cli, "fubar")
q2 := NewQueue(cli, "bar")
DeleteAll(t, q1)
DeleteAll(t, q2)
_, err = q1.Put("baz")
if err != nil {
t.Fatal(err)
}
pairs, err := q1.Poll()
if err != nil {
t.Fatal(err)
}
if len(pairs) != 1 {
t.Fatal("Wrong queue count.")
}
err = q1.Move(pairs[0], q2)
if err != nil {
t.Fatal(err)
}
pairs, err = q1.Poll()
if err != nil {
t.Fatal(err)
}
if len(pairs) != 0 {
t.Fatal("Wrong q1 count.", pairs)
}
pairs, err = q2.Poll()
if err != nil {
t.Fatal(err)
}
if len(pairs) != 1 {
t.Fatal("Wrong q2 count.")
}
if string(pairs[0].Value) != "baz" {
t.Fatal("Wrong value after move.")
}
DeleteAll(t, q1)
DeleteAll(t, q2)
_, err = q1.Put("baz")
if err != nil {
t.Fatal(err)
}
pairs, err = q1.Poll()
if err != nil {
t.Fatal(err)
}
err = q1.MoveWithTTL(pairs[0], q2, 5)
if err != nil {
t.Fatal(err)
}
time.Sleep(6 * time.Second)
pairs, err = q1.Poll()
if err != nil {
t.Fatal(err)
}
if len(pairs) != 0 {
t.Fatal("Moved item with ttl did not time out.")
}
}
func TestWatch(t *testing.T) {
cli, err := NewLocalClient()
if err != nil {
t.Fatal(err)
}
q := NewQueue(cli, "pre")
DeleteAll(t, q)
_, _ = q.Put("one")
_, _ = q.Put("two")
_, _ = q.Put("three")
ch := make(chan string)
go func() {
_ = q.Watch(func(q *Queue, kv *Pair) {
ch <- kv.Value
})
}()
x := <-ch
if x != "one" {
t.Fatal("Got wrong one")
}
x = <-ch
if x != "two" {
t.Fatal("Got wrong two")
}
x = <-ch
if x != "three" {
t.Fatal("Got wrong three")
}
DeleteAll(t, q)
go func() {
_ = q.Watch(func(q *Queue, kv *Pair) {
ch <- kv.Value
})
}()
_, _ = q.Put("foo")
x = <-ch
if x != "foo" {
t.Fatal(fmt.Sprintf("Expected foo, got %s", x))
}
q.CancelWatch()
}