Skip to content

Commit

Permalink
feature: suport TLS Authentication for etcd
Browse files Browse the repository at this point in the history
Signed-off-by: DengXiewei <[email protected]>
  • Loading branch information
igotcha committed Oct 16, 2023
1 parent a7ce39f commit ace4a21
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
47 changes: 46 additions & 1 deletion database/kv/etcd/v3/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package gxetcd

import (
"context"
"crypto/tls"
"log"
"strings"
"sync"
Expand Down Expand Up @@ -63,7 +64,7 @@ func NewConfigClientWithErr(opts ...Option) (*Client, error) {
opt(options)
}

newClient, err := NewClient(options.Name, options.Endpoints, options.Timeout, options.Heartbeat)
newClient, err := NewClientWithOptions(context.Background(), options)
if err != nil {
log.Printf("new etcd client (Name{%s}, etcd addresses{%v}, Timeout{%d}) = error{%v}",
options.Name, options.Endpoints, options.Timeout, err)
Expand All @@ -82,6 +83,9 @@ type Client struct {
endpoints []string
timeout time.Duration
heartbeat int
username string
password string
tls *tls.Config

ctx context.Context // if etcd server connection lose, the ctx.Done will be sent msg
cancel context.CancelFunc // cancel the ctx, all watcher will stopped
Expand Down Expand Up @@ -126,6 +130,47 @@ func NewClient(name string, endpoints []string, timeout time.Duration, heartbeat
return c, nil
}

// NewClientWithOptions create a client instance from Options.
func NewClientWithOptions(ctx context.Context, opts *Options) (*Client, error) {
nctx, cancel := context.WithCancel(ctx)

rawClient, err := clientv3.New(clientv3.Config{
Context: nctx,
Endpoints: opts.Endpoints,
DialTimeout: opts.Timeout,
TLS: opts.TLS,
Username: opts.Username,
Password: opts.Password,
DialOptions: []grpc.DialOption{grpc.WithBlock()},
})
if err != nil {
cancel()
return nil, perrors.WithMessage(err, "new raw client block connect to server")
}

c := &Client{
name: opts.Name,
timeout: opts.Timeout,
endpoints: opts.Endpoints,
heartbeat: opts.Heartbeat,
username: opts.Username,
password: opts.Password,
tls: opts.TLS,

ctx: nctx,
cancel: cancel,
rawClient: rawClient,

exit: make(chan struct{}),
}

if err := c.keepSession(); err != nil {
cancel()
return nil, perrors.WithMessage(err, "client keep session")
}
return c, nil
}

// NOTICE: need to get the lock before calling this method
func (c *Client) clean() {
// close raw client
Expand Down
22 changes: 22 additions & 0 deletions database/kv/etcd/v3/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package gxetcd

import (
"crypto/tls"
"time"
)

Expand All @@ -44,6 +45,12 @@ type Options struct {
Timeout time.Duration
// Heartbeat second
Heartbeat int
// Username is a user name for authentication.
Username string
// Password is a password for authentication.
Password string
// TLS holds the client secure credentials, if any.
TLS *tls.Config
}

// Option will define a function of handling Options
Expand Down Expand Up @@ -76,3 +83,18 @@ func WithHeartbeat(heartbeat int) Option {
opt.Heartbeat = heartbeat
}
}

// WithAuthentication sets etcd client authentication
func WithAuthentication(username, password string) Option {
return func(opt *Options) {
opt.Username = username
opt.Password = password
}
}

// WithTLS sets etcd client secure credentials
func WithTLS(tls *tls.Config) Option {
return func(opt *Options) {
opt.TLS = tls
}
}

0 comments on commit ace4a21

Please sign in to comment.