Now supports client certificates.
This commit is contained in:
parent
b288401646
commit
e93cf8708b
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
etcd "github.com/coreos/etcd/clientv3"
|
etcd "github.com/coreos/etcd/clientv3"
|
||||||
|
@ -15,16 +14,11 @@ type EasyClient struct {
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLocalClient() (*EasyClient, error) {
|
func NewClient(conf EasyConfig) (*EasyClient, error) {
|
||||||
return NewClient([]string{"localhost"}, 2379)
|
config, err := conf.prepare()
|
||||||
}
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
config := etcd.Config{Endpoints: hp, DialTimeout: 5 * time.Second}
|
|
||||||
cli, err := etcd.New(config)
|
cli, err := etcd.New(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
173
queue_test.go
173
queue_test.go
|
@ -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()
|
|
||||||
}
|
|
Loading…
Reference in New Issue