You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by ch...@apache.org on 2020/12/08 13:02:55 UTC
[apisix-dashboard] branch master updated: feat: add etcd basic auth
support (#951)
This is an automated email from the ASF dual-hosted git repository.
chenjunxu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new 0383021 feat: add etcd basic auth support (#951)
0383021 is described below
commit 0383021a07e646a2a8406162fb298c637da000a8
Author: JTrancender <ji...@jie-trancender.org>
AuthorDate: Tue Dec 8 21:02:49 2020 +0800
feat: add etcd basic auth support (#951)
* add etcd basic auth support
---
api/conf/conf.go | 22 +++++++++--
api/conf/conf.yaml | 4 ++
api/go.sum | 1 +
api/internal/core/storage/etcd.go | 7 +++-
api/internal/handler/consumer/consumer_test.go | 4 +-
api/internal/handler/route/route_test.go | 5 ++-
api/internal/handler/service/service_test.go | 3 +-
api/internal/handler/ssl/ssl_test.go | 3 +-
api/internal/handler/upstream/upstream_test.go | 3 +-
api/main.go | 11 +++---
api/test/shell/cli_test.sh | 51 ++++++++++++++++++++++++++
11 files changed, 98 insertions(+), 16 deletions(-)
diff --git a/api/conf/conf.go b/api/conf/conf.go
index 91eb89b..578fcbd 100644
--- a/api/conf/conf.go
+++ b/api/conf/conf.go
@@ -45,7 +45,7 @@ var (
WorkDir = "."
ServerHost = "127.0.0.1"
ServerPort = 80
- ETCDEndpoints = []string{"127.0.0.1:2379"}
+ ETCDConfig *Etcd
ErrorLogLevel = "warn"
ErrorLogPath = "logs/error.log"
UserList = make(map[string]User, 2)
@@ -55,6 +55,8 @@ var (
type Etcd struct {
Endpoints []string
+ Username string
+ Password string
}
type Listen struct {
@@ -128,9 +130,9 @@ func setConf() {
ServerHost = config.Conf.Listen.Host
}
- //etcd
+ // for etcd
if len(config.Conf.Etcd.Endpoints) > 0 {
- ETCDEndpoints = config.Conf.Etcd.Endpoints
+ initEtcdConfig(config.Conf.Etcd)
}
//error log
@@ -180,3 +182,17 @@ func initSchema() {
Schema = gjson.ParseBytes(schemaContent)
}
}
+
+// initialize etcd config
+func initEtcdConfig(conf Etcd) {
+ var endpoints = []string{"127.0.0.1:2379"}
+ if len(conf.Endpoints) > 0 {
+ endpoints = conf.Endpoints
+ }
+
+ ETCDConfig = &Etcd{
+ Endpoints: endpoints,
+ Username: conf.Username,
+ Password: conf.Password,
+ }
+}
diff --git a/api/conf/conf.yaml b/api/conf/conf.yaml
index e971761..7f147cb 100644
--- a/api/conf/conf.yaml
+++ b/api/conf/conf.yaml
@@ -22,6 +22,10 @@ conf:
etcd:
endpoints: # supports defining multiple etcd host addresses for an etcd cluster
- 127.0.0.1:2379
+
+ # etcd basic auth info
+ # username: "root" # ignore etcd username if not enable etcd auth
+ # password: "123456" # ignore etcd password if not enable etcd auth
log:
error_log:
level: warn # supports levels, lower to higher: debug, info, warn, error, panic, fatal
diff --git a/api/go.sum b/api/go.sum
index d245362..80c6f95 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -118,6 +118,7 @@ github.com/shiningrush/droplet v0.2.1 h1:p2utttTbCfgiL+x0Zrb2jFeWspB7/o+v3e+R94G
github.com/shiningrush/droplet v0.2.1/go.mod h1:akW2vIeamvMD6zj6wIBfzYn6StGXBxwlW3gA+hcHu5M=
github.com/shiningrush/droplet v0.2.2 h1:jEqSGoJXlybt1yQdauu+waE+l7KYlguNs8VayMfQ96Q=
github.com/shiningrush/droplet v0.2.2/go.mod h1:akW2vIeamvMD6zj6wIBfzYn6StGXBxwlW3gA+hcHu5M=
+github.com/shiningrush/droplet v0.2.3 h1:bzPDzkE0F54r94XsultGS8uAPeL3pZIRmjqM0zIlpeI=
github.com/shiningrush/droplet v0.2.3/go.mod h1:akW2vIeamvMD6zj6wIBfzYn6StGXBxwlW3gA+hcHu5M=
github.com/shiningrush/droplet/wrapper/gin v0.2.0 h1:LHkU+TbSkpePgXrTg3hJoSZlCMS03GeWMl0t+oLkd44=
github.com/shiningrush/droplet/wrapper/gin v0.2.0/go.mod h1:ZJu+sCRrVXn5Pg618c1KK3Ob2UiXGuPM1ROx5uMM9YQ=
diff --git a/api/internal/core/storage/etcd.go b/api/internal/core/storage/etcd.go
index 5a9c23e..99db3d2 100644
--- a/api/internal/core/storage/etcd.go
+++ b/api/internal/core/storage/etcd.go
@@ -21,6 +21,7 @@ import (
"fmt"
"time"
+ "github.com/apisix/manager-api/conf"
"github.com/apisix/manager-api/internal/utils"
"go.etcd.io/etcd/clientv3"
)
@@ -32,10 +33,12 @@ var (
type EtcdV3Storage struct {
}
-func InitETCDClient(endpoints []string) error {
+func InitETCDClient(etcdConf *conf.Etcd) error {
cli, err := clientv3.New(clientv3.Config{
- Endpoints: endpoints,
+ Endpoints: etcdConf.Endpoints,
DialTimeout: 5 * time.Second,
+ Username: etcdConf.Username,
+ Password: etcdConf.Password,
})
if err != nil {
return fmt.Errorf("init etcd failed: %w", err)
diff --git a/api/internal/handler/consumer/consumer_test.go b/api/internal/handler/consumer/consumer_test.go
index 1f88c52..ba02f28 100644
--- a/api/internal/handler/consumer/consumer_test.go
+++ b/api/internal/handler/consumer/consumer_test.go
@@ -19,12 +19,14 @@ package consumer
import (
"encoding/json"
+
"testing"
"time"
"github.com/shiningrush/droplet"
"github.com/stretchr/testify/assert"
+ "github.com/apisix/manager-api/conf"
"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/storage"
"github.com/apisix/manager-api/internal/core/store"
@@ -32,7 +34,7 @@ import (
func TestConsumer(t *testing.T) {
// init
- err := storage.InitETCDClient([]string{"127.0.0.1:2379"})
+ err := storage.InitETCDClient(conf.ETCDConfig)
assert.Nil(t, err)
err = store.InitStores()
assert.Nil(t, err)
diff --git a/api/internal/handler/route/route_test.go b/api/internal/handler/route/route_test.go
index 00a86a3..bb906f4 100644
--- a/api/internal/handler/route/route_test.go
+++ b/api/internal/handler/route/route_test.go
@@ -27,6 +27,7 @@ import (
"github.com/shiningrush/droplet/data"
"github.com/stretchr/testify/assert"
+ "github.com/apisix/manager-api/conf"
"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/storage"
"github.com/apisix/manager-api/internal/core/store"
@@ -34,7 +35,7 @@ import (
func TestRoute(t *testing.T) {
// init
- err := storage.InitETCDClient([]string{"127.0.0.1:2379"})
+ err := storage.InitETCDClient(conf.ETCDConfig)
assert.Nil(t, err)
err = store.InitStores()
assert.Nil(t, err)
@@ -989,7 +990,7 @@ func TestRoute(t *testing.T) {
func Test_Route_With_Script(t *testing.T) {
// init
- err := storage.InitETCDClient([]string{"127.0.0.1:2379"})
+ err := storage.InitETCDClient(conf.ETCDConfig)
assert.Nil(t, err)
err = store.InitStores()
assert.Nil(t, err)
diff --git a/api/internal/handler/service/service_test.go b/api/internal/handler/service/service_test.go
index 6f801c4..81a56fe 100644
--- a/api/internal/handler/service/service_test.go
+++ b/api/internal/handler/service/service_test.go
@@ -25,6 +25,7 @@ import (
"github.com/shiningrush/droplet"
"github.com/stretchr/testify/assert"
+ "github.com/apisix/manager-api/conf"
"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/storage"
"github.com/apisix/manager-api/internal/core/store"
@@ -32,7 +33,7 @@ import (
func TestService(t *testing.T) {
// init
- err := storage.InitETCDClient([]string{"127.0.0.1:2379"})
+ err := storage.InitETCDClient(conf.ETCDConfig)
assert.Nil(t, err)
err = store.InitStores()
assert.Nil(t, err)
diff --git a/api/internal/handler/ssl/ssl_test.go b/api/internal/handler/ssl/ssl_test.go
index 47ea9c2..4a52032 100644
--- a/api/internal/handler/ssl/ssl_test.go
+++ b/api/internal/handler/ssl/ssl_test.go
@@ -25,6 +25,7 @@ import (
"github.com/shiningrush/droplet"
"github.com/stretchr/testify/assert"
+ "github.com/apisix/manager-api/conf"
"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/storage"
"github.com/apisix/manager-api/internal/core/store"
@@ -32,7 +33,7 @@ import (
func TestSSL(t *testing.T) {
// init
- err := storage.InitETCDClient([]string{"127.0.0.1:2379"})
+ err := storage.InitETCDClient(conf.ETCDConfig)
assert.Nil(t, err)
err = store.InitStores()
assert.Nil(t, err)
diff --git a/api/internal/handler/upstream/upstream_test.go b/api/internal/handler/upstream/upstream_test.go
index c11089c..03f4fe0 100644
--- a/api/internal/handler/upstream/upstream_test.go
+++ b/api/internal/handler/upstream/upstream_test.go
@@ -25,6 +25,7 @@ import (
"github.com/shiningrush/droplet"
"github.com/stretchr/testify/assert"
+ "github.com/apisix/manager-api/conf"
"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/storage"
"github.com/apisix/manager-api/internal/core/store"
@@ -34,7 +35,7 @@ var upstreamHandler *Handler
func TestUpstream(t *testing.T) {
// init
- err := storage.InitETCDClient([]string{"127.0.0.1:2379"})
+ err := storage.InitETCDClient(conf.ETCDConfig)
assert.Nil(t, err)
err = store.InitStores()
assert.Nil(t, err)
diff --git a/api/main.go b/api/main.go
index ce05fdd..38ee8bd 100644
--- a/api/main.go
+++ b/api/main.go
@@ -19,14 +19,15 @@ package main
import (
"context"
"fmt"
- "github.com/apisix/manager-api/internal/handler"
- "github.com/shiningrush/droplet"
"net/http"
"os"
"os/signal"
"syscall"
"time"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/shiningrush/droplet"
+
"github.com/apisix/manager-api/conf"
"github.com/apisix/manager-api/internal"
"github.com/apisix/manager-api/internal/core/storage"
@@ -44,12 +45,12 @@ func main() {
newMws = append(newMws, mws[1:]...)
return newMws
}
- if err := storage.InitETCDClient(conf.ETCDEndpoints); err != nil {
- log.Error("init etcd client fail: %w", err)
+ if err := storage.InitETCDClient(conf.ETCDConfig); err != nil {
+ log.Errorf("init etcd client fail: %w", err)
panic(err)
}
if err := store.InitStores(); err != nil {
- log.Error("init stores fail: %w", err)
+ log.Errorf("init stores fail: %w", err)
panic(err)
}
// routes
diff --git a/api/test/shell/cli_test.sh b/api/test/shell/cli_test.sh
index 8f142b1..af3744b 100755
--- a/api/test/shell/cli_test.sh
+++ b/api/test/shell/cli_test.sh
@@ -93,3 +93,54 @@ if [[ `grep -c "INFO" ./error.log` -eq '0' ]]; then
echo "failed: failed to write log on right level"
exit 1
fi
+
+
+# etcd basic auth
+# add root user
+curl -L http://localhost:2379/v3/auth/user/add -d '{"name": "root", "password": "root"}'
+
+# add root role
+curl -L http://localhost:2379/v3/auth/role/add -d '{"name": "root"}'
+
+# grant root role to root user
+curl -L http://localhost:2379/v3/auth/user/grant -d '{"user": "root", "role": "root"}'
+
+# enable auth
+curl -L http://localhost:2379/v3/auth/enable -d '{}'
+
+./manager-api &
+sleep 3
+
+# make sure it's wrong
+if [[ `grep -c "etcdserver: user name is empty" ./error.log` -eq '0' ]]; then
+ echo "failed: failed to validate etcd basic auth"
+ exit 1
+fi
+
+# modify etcd auth config
+sed -i '1,$s/# username: "root" # ignore etcd username if not enable etcd auth/username: "root"/g' conf/conf.yaml
+sed -i '1,$s/# password: "123456" # ignore etcd password if not enable etcd auth/password: "root"/g' conf/conf.yaml
+
+./manager-api &
+sleep 3
+
+# validate process is right by requesting login api
+resp=$(curl http://127.0.0.1:9000/apisix/admin/user/login -d '{"username":"admin", "password": "admin"}')
+token=$(echo "${resp}" | sed 's/{/\n/g' | sed 's/,/\n/g' | grep "token" | sed 's/:/\n/g' | sed '1d' | sed 's/}//g' | sed 's/"//g')
+if [ -z "${token}" ]; then
+ echo "login failed"
+ exit 1
+fi
+
+# more validation to make sure it's ok to access etcd
+resp=$(curl -ig http://127.0.0.1:9000/apisix/admin/consumers -i -H "Authorization: $token" -d '{"username":"etcd_basic_auth_test"}')
+respCode=$(echo "${resp}" | sed 's/{/\n/g'| sed 's/,/\n/g' | grep "code" | sed 's/:/\n/g' | sed '1d')
+respMessage=$(echo "${resp}" | sed 's/{/\n/g'| sed 's/,/\n/g' | grep "message" | sed 's/:/\n/g' | sed '1d')
+if [ "$respCode" != "0" ] || [ $respMessage != "\"\"" ]; then
+ echo "verify access etcd failed"
+ exit 1
+fi
+
+pkill -f manager-api
+
+check_logfile