Skip to content

Commit 3adf407

Browse files
fancy-rabbitspinlock
authored andcommitted
support authentication for zookeeper/etcd (#1330)
* add authentication for zookeeper * add authentication for etcd (NOT TESTED) * fix docopt arg parse * fmt
1 parent fe6ff94 commit 3adf407

File tree

13 files changed

+90
-27
lines changed

13 files changed

+90
-27
lines changed

cmd/admin/admin.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,23 @@ func (t *cmdAdmin) newTopomClient(d map[string]interface{}) models.Client {
4040
var coordinator struct {
4141
name string
4242
addr string
43+
auth string
4344
}
4445

4546
switch {
4647
case d["--zookeeper"] != nil:
4748
coordinator.name = "zookeeper"
4849
coordinator.addr = utils.ArgumentMust(d, "--zookeeper")
50+
if d["--zookeeper-auth"] != nil {
51+
coordinator.auth = utils.ArgumentMust(d, "--zookeeper-auth")
52+
}
4953

5054
case d["--etcd"] != nil:
5155
coordinator.name = "etcd"
5256
coordinator.addr = utils.ArgumentMust(d, "--etcd")
57+
if d["--etcd-auth"] != nil {
58+
coordinator.auth = utils.ArgumentMust(d, "--etcd-auth")
59+
}
5360

5461
case d["--filesystem"] != nil:
5562
coordinator.name = "filesystem"
@@ -59,7 +66,7 @@ func (t *cmdAdmin) newTopomClient(d map[string]interface{}) models.Client {
5966
log.Panicf("invalid coordinator")
6067
}
6168

62-
c, err := models.NewClient(coordinator.name, coordinator.addr, time.Minute)
69+
c, err := models.NewClient(coordinator.name, coordinator.addr, coordinator.auth, time.Minute)
6370
if err != nil {
6471
log.PanicErrorf(err, "create '%s' client to '%s' failed", coordinator.name, coordinator.addr)
6572
}

cmd/admin/main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ Usage:
5252
codis-admin [-v] --dashboard=ADDR --sentinel-add --addr=ADDR
5353
codis-admin [-v] --dashboard=ADDR --sentinel-del --addr=ADDR [--force]
5454
codis-admin [-v] --dashboard=ADDR --sentinel-resync
55-
codis-admin [-v] --remove-lock --product=NAME (--zookeeper=ADDR|--etcd=ADDR|--filesystem=ROOT)
56-
codis-admin [-v] --config-dump --product=NAME (--zookeeper=ADDR|--etcd=ADDR|--filesystem=ROOT) [-1]
55+
codis-admin [-v] --remove-lock --product=NAME (--zookeeper=ADDR [--zookeeper-auth=USR:PWD]|--etcd=ADDR [--etcd-auth=USR:PWD]|--filesystem=ROOT)
56+
codis-admin [-v] --config-dump --product=NAME (--zookeeper=ADDR [--zookeeper-auth=USR:PWD]|--etcd=ADDR [--etcd-auth=USR:PWD]|--filesystem=ROOT) [-1]
5757
codis-admin [-v] --config-convert=FILE
58-
codis-admin [-v] --config-restore=FILE --product=NAME (--zookeeper=ADDR|--etcd=ADDR|--filesystem=ROOT) [--confirm]
59-
codis-admin [-v] --dashboard-list (--zookeeper=ADDR|--etcd=ADDR|--filesystem=ROOT)
58+
codis-admin [-v] --config-restore=FILE --product=NAME (--zookeeper=ADDR [--zookeeper-auth=USR:PWD]|--etcd=ADDR [--etcd-auth=USR:PWD]|--filesystem=ROOT) [--confirm]
59+
codis-admin [-v] --dashboard-list (--zookeeper=ADDR [--zookeeper-auth=USR:PWD]|--etcd=ADDR [--etcd-auth=USR:PWD]|--filesystem=ROOT)
6060
6161
Options:
6262
-a AUTH, --auth=AUTH

cmd/dashboard/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ Options:
115115
log.Warnf("option --product_auth = %s", s)
116116
}
117117

118-
client, err := models.NewClient(config.CoordinatorName, config.CoordinatorAddr, time.Minute)
118+
client, err := models.NewClient(config.CoordinatorName, config.CoordinatorAddr, config.CoordinatorAuth, time.Minute)
119119
if err != nil {
120120
log.PanicErrorf(err, "create '%s' client to '%s' failed", config.CoordinatorName, config.CoordinatorAddr)
121121
}

cmd/fe/main.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func init() {
5656
func main() {
5757
const usage = `
5858
Usage:
59-
codis-fe [--ncpu=N] [--log=FILE] [--log-level=LEVEL] [--assets-dir=PATH] [--pidfile=FILE] (--dashboard-list=FILE|--zookeeper=ADDR|--etcd=ADDR|--filesystem=ROOT) --listen=ADDR
59+
codis-fe [--ncpu=N] [--log=FILE] [--log-level=LEVEL] [--assets-dir=PATH] [--pidfile=FILE] (--dashboard-list=FILE|--zookeeper=ADDR [--zookeeper-auth=USR:PWD]|--etcd=ADDR [--etcd-auth=USR:PWD]|--filesystem=ROOT) --listen=ADDR
6060
codis-fe --version
6161
6262
Options:
@@ -133,16 +133,23 @@ Options:
133133
var coordinator struct {
134134
name string
135135
addr string
136+
auth string
136137
}
137138

138139
switch {
139140
case d["--zookeeper"] != nil:
140141
coordinator.name = "zookeeper"
141142
coordinator.addr = utils.ArgumentMust(d, "--zookeeper")
143+
if d["--zookeeper-auth"] != nil {
144+
coordinator.auth = utils.ArgumentMust(d, "--zookeeper-auth")
145+
}
142146

143147
case d["--etcd"] != nil:
144148
coordinator.name = "etcd"
145149
coordinator.addr = utils.ArgumentMust(d, "--etcd")
150+
if d["--etcd-auth"] != nil {
151+
coordinator.auth = utils.ArgumentMust(d, "--etcd-auth")
152+
}
146153

147154
case d["--filesystem"] != nil:
148155
coordinator.name = "filesystem"
@@ -154,7 +161,7 @@ Options:
154161

155162
log.Warnf("set --%s = %s", coordinator.name, coordinator.addr)
156163

157-
c, err := models.NewClient(coordinator.name, coordinator.addr, time.Minute)
164+
c, err := models.NewClient(coordinator.name, coordinator.addr, coordinator.auth, time.Minute)
158165
if err != nil {
159166
log.PanicErrorf(err, "create '%s' client to '%s' failed", coordinator.name, coordinator.addr)
160167
}

cmd/proxy/main.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131
func main() {
3232
const usage = `
3333
Usage:
34-
codis-proxy [--ncpu=N [--max-ncpu=MAX]] [--config=CONF] [--log=FILE] [--log-level=LEVEL] [--host-admin=ADDR] [--host-proxy=ADDR] [--dashboard=ADDR|--zookeeper=ADDR|--etcd=ADDR|--filesystem=ROOT|--fillslots=FILE] [--ulimit=NLIMIT] [--pidfile=FILE] [--product_name=NAME] [--product_auth=AUTH] [--session_auth=AUTH]
34+
codis-proxy [--ncpu=N [--max-ncpu=MAX]] [--config=CONF] [--log=FILE] [--log-level=LEVEL] [--host-admin=ADDR] [--host-proxy=ADDR] [--dashboard=ADDR|--zookeeper=ADDR [--zookeeper-auth=USR:PWD]|--etcd=ADDR [--etcd-auth=USR:PWD]|--filesystem=ROOT|--fillslots=FILE] [--ulimit=NLIMIT] [--pidfile=FILE] [--product_name=NAME] [--product_auth=AUTH] [--session_auth=AUTH]
3535
codis-proxy --default-config
3636
codis-proxy --version
3737
@@ -131,17 +131,24 @@ Options:
131131
var coordinator struct {
132132
name string
133133
addr string
134+
auth string
134135
}
135136

136137
switch {
137138

138139
case d["--zookeeper"] != nil:
139140
coordinator.name = "zookeeper"
140141
coordinator.addr = utils.ArgumentMust(d, "--zookeeper")
142+
if d["--zookeeper-auth"] != nil {
143+
coordinator.auth = utils.ArgumentMust(d, "--zookeeper-auth")
144+
}
141145

142146
case d["--etcd"] != nil:
143147
coordinator.name = "etcd"
144148
coordinator.addr = utils.ArgumentMust(d, "--etcd")
149+
if d["--etcd-auth"] != nil {
150+
coordinator.auth = utils.ArgumentMust(d, "--etcd-auth")
151+
}
145152

146153
case d["--filesystem"] != nil:
147154
coordinator.name = "filesystem"
@@ -213,7 +220,7 @@ Options:
213220
case dashboard != "":
214221
go AutoOnlineWithDashboard(s, dashboard)
215222
case coordinator.name != "":
216-
go AutoOnlineWithCoordinator(s, coordinator.name, coordinator.addr)
223+
go AutoOnlineWithCoordinator(s, coordinator.name, coordinator.addr, coordinator.auth)
217224
case slots != nil:
218225
go AutoOnlineWithFillSlots(s, slots)
219226
}
@@ -287,8 +294,8 @@ func AutoOnlineWithDashboard(p *proxy.Proxy, dashboard string) {
287294
log.Panicf("online proxy failed")
288295
}
289296

290-
func AutoOnlineWithCoordinator(p *proxy.Proxy, name, addr string) {
291-
client, err := models.NewClient(name, addr, time.Minute)
297+
func AutoOnlineWithCoordinator(p *proxy.Proxy, name, addr string, auth string) {
298+
client, err := models.NewClient(name, addr, auth, time.Minute)
292299
if err != nil {
293300
log.PanicErrorf(err, "create '%s' client to '%s' failed", name, addr)
294301
}

config/dashboard.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
##################################################
77

88
# Set Coordinator, only accept "zookeeper" & "etcd" & "filesystem".
9+
# for zookeeper/etcd, coorinator_auth accept "user:password"
910
# Quick Start
1011
coordinator_name = "filesystem"
1112
coordinator_addr = "/tmp/codis"
1213
#coordinator_name = "zookeeper"
1314
#coordinator_addr = "127.0.0.1:2181"
15+
#coordinator_auth = ""
1416

1517
# Set Codis Product Name/Auth.
1618
product_name = "codis-demo"

config/proxy.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ proxy_addr = "0.0.0.0:19000"
2626
# Set jodis address & session timeout
2727
# 1. jodis_name is short for jodis_coordinator_name, only accept "zookeeper" & "etcd".
2828
# 2. jodis_addr is short for jodis_coordinator_addr
29-
# 3. proxy will be registered as node:
29+
# 3. jodis_auth is short for jodis_coordinator_auth, for zookeeper/etcd, "user:password" is accepted.
30+
# 4. proxy will be registered as node:
3031
# if jodis_compatible = true (not suggested):
3132
# /zk/codis/db_{PRODUCT_NAME}/proxy-{HASHID} (compatible with Codis2.0)
3233
# or else
3334
# /jodis/{PRODUCT_NAME}/proxy-{HASHID}
3435
jodis_name = ""
3536
jodis_addr = ""
37+
jodis_auth = ""
3638
jodis_timeout = "20s"
3739
jodis_compatible = false
3840

pkg/models/client.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ type Client interface {
2828
CreateEphemeralInOrder(path string, data []byte) (<-chan struct{}, string, error)
2929
}
3030

31-
func NewClient(coordinator string, addrlist string, timeout time.Duration) (Client, error) {
31+
func NewClient(coordinator string, addrlist string, auth string, timeout time.Duration) (Client, error) {
3232
switch coordinator {
3333
case "zk", "zookeeper":
34-
return zkclient.New(addrlist, timeout)
34+
return zkclient.New(addrlist, auth, timeout)
3535
case "etcd":
36-
return etcdclient.New(addrlist, timeout)
36+
return etcdclient.New(addrlist, auth, timeout)
3737
case "fs", "filesystem":
3838
return fsclient.New(addrlist)
3939
}

pkg/models/etcd/etcdclient.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type Client struct {
3434
context context.Context
3535
}
3636

37-
func New(addrlist string, timeout time.Duration) (*Client, error) {
37+
func New(addrlist string, auth string, timeout time.Duration) (*Client, error) {
3838
endpoints := strings.Split(addrlist, ",")
3939
for i, s := range endpoints {
4040
if s != "" && !strings.HasPrefix(s, "http://") {
@@ -45,10 +45,18 @@ func New(addrlist string, timeout time.Duration) (*Client, error) {
4545
timeout = time.Second * 5
4646
}
4747

48-
c, err := client.New(client.Config{
48+
config := client.Config{
4949
Endpoints: endpoints, Transport: client.DefaultTransport,
5050
HeaderTimeoutPerRequest: time.Second * 5,
51-
})
51+
}
52+
53+
if auth != "" {
54+
a := strings.Split(auth, ":")
55+
config.Username = a[0]
56+
config.Password = a[1]
57+
}
58+
59+
c, err := client.New(config)
5260
if err != nil {
5361
return nil, errors.Trace(err)
5462
}

pkg/models/zk/zkclient.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Client struct {
2828
conn *zk.Conn
2929

3030
addrlist string
31+
auth string
3132
timeout time.Duration
3233

3334
logger *zkLogger
@@ -45,16 +46,16 @@ func (l *zkLogger) Printf(format string, v ...interface{}) {
4546
}
4647
}
4748

48-
func New(addrlist string, timeout time.Duration) (*Client, error) {
49-
return NewWithLogfunc(addrlist, timeout, DefaultLogfunc)
49+
func New(addrlist string, auth string, timeout time.Duration) (*Client, error) {
50+
return NewWithLogfunc(addrlist, auth, timeout, DefaultLogfunc)
5051
}
5152

52-
func NewWithLogfunc(addrlist string, timeout time.Duration, logfunc func(foramt string, v ...interface{})) (*Client, error) {
53+
func NewWithLogfunc(addrlist string, auth string, timeout time.Duration, logfunc func(foramt string, v ...interface{})) (*Client, error) {
5354
if timeout <= 0 {
5455
timeout = time.Second * 5
5556
}
5657
c := &Client{
57-
addrlist: addrlist, timeout: timeout,
58+
addrlist: addrlist, auth: auth, timeout: timeout,
5859
logger: &zkLogger{logfunc},
5960
}
6061
if err := c.reset(); err != nil {
@@ -77,6 +78,12 @@ func (c *Client) reset() error {
7778

7879
c.logger.Printf("zkclient setup new connection to %s", c.addrlist)
7980

81+
if c.auth != "" {
82+
if err := c.conn.AddAuth("digest", []byte(c.auth)); err != nil {
83+
return errors.Trace(err)
84+
}
85+
}
86+
8087
go func() {
8188
for e := range events {
8289
log.Debugf("zookeeper event: %+v", e)
@@ -155,7 +162,15 @@ func (c *Client) mkdir(conn *zk.Conn, path string) error {
155162
if err := c.mkdir(conn, filepath.Dir(path)); err != nil {
156163
return err
157164
}
158-
_, err := conn.Create(path, []byte{}, 0, zk.WorldACL(zk.PermAll))
165+
var acl []zk.ACL
166+
167+
if c.auth != "" {
168+
auth := strings.Split(c.auth, ":")
169+
acl = zk.DigestACL(zk.PermAll, auth[0], auth[1])
170+
} else {
171+
acl = zk.WorldACL(zk.PermAll)
172+
}
173+
_, err := conn.Create(path, []byte{}, 0, acl)
159174
if err != nil && errors.NotEqual(err, zk.ErrNodeExists) {
160175
return errors.Trace(err)
161176
}
@@ -213,7 +228,16 @@ func (c *Client) create(conn *zk.Conn, path string, data []byte, flag int32) (st
213228
if err := c.mkdir(conn, filepath.Dir(path)); err != nil {
214229
return "", err
215230
}
216-
p, err := conn.Create(path, data, flag, zk.WorldACL(zk.PermAdmin|zk.PermRead|zk.PermWrite))
231+
232+
var acl []zk.ACL
233+
234+
if c.auth != "" {
235+
auth := strings.Split(c.auth, ":")
236+
acl = zk.DigestACL(zk.PermAdmin|zk.PermRead|zk.PermWrite, auth[0], auth[1])
237+
} else {
238+
acl = zk.WorldACL(zk.PermAdmin|zk.PermRead|zk.PermWrite)
239+
}
240+
p, err := conn.Create(path, data, flag, acl)
217241
if err != nil {
218242
return "", errors.Trace(err)
219243
}

0 commit comments

Comments
 (0)