Skip to content

Commit

Permalink
Merge branch 'master' into juzhiyuan/feat-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
juzhiyuan authored Dec 3, 2020
2 parents e60cacd + c574813 commit 8b92a1d
Show file tree
Hide file tree
Showing 45 changed files with 2,044 additions and 190 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/backend-unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
run: |
export GO111MOUDULE=on
export APISIX_CONF_PATH=$PWD/conf
sed -i 's/8080/8088/' conf/conf.yaml
sed -i 's/9000/8088/' conf/conf.yaml
go build -o ./manager-api
./manager-api > ./api.log 2>&1 &
sleep 2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-with-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

- name: Build Docker Image
run: |
docker build -t dashboard:ci .
docker build -t dashboard:ci . --build-arg APISIX_DASHBOARD_VERSION=master
- name: Modify ETCD IP
run: |
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ COPY --from=fe-builder /usr/local/apisix-dashboard/output/ ./

RUN mkdir logs

EXPOSE 8080
EXPOSE 9000

CMD [ "/usr/local/apisix-dashboard/manager-api" ]
2 changes: 1 addition & 1 deletion api/conf/conf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
conf:
listen:
host: 127.0.0.1 # `manager api` listening ip or host name
port: 8080 # `manager api` listening port
port: 9000 # `manager api` listening port
etcd:
endpoints: # supports defining multiple etcd host addresses for an etcd cluster
- 127.0.0.1:2379
Expand Down
1 change: 1 addition & 0 deletions api/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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/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=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
Expand Down
3 changes: 2 additions & 1 deletion api/internal/core/entity/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ func NodesFormat(obj interface{}) interface{} {
return nodes
case []*Node:
log.Infof("nodes type: %v", objType)
return nodes
return obj
case []interface{}:
log.Infof("nodes type []interface{}: %v", objType)
list := obj.([]interface{})
for _, v := range list {
val := v.(map[string]interface{})
Expand Down
21 changes: 21 additions & 0 deletions api/internal/core/entity/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ func TestNodesFormat(t *testing.T) {
assert.Contains(t, jsonStr, `"host":"127.0.0.1"`)
}

func TestNodesFormat_struct(t *testing.T) {
// route data saved in ETCD
var route Route
route.Uris = []string{"/*"}
route.Upstream = &UpstreamDef{}
route.Upstream.Type = "roundrobin"
var nodes = []*Node{{Host: "127.0.0.1", Port: 80, Weight: 0}}
route.Upstream.Nodes = nodes

// nodes format
formattedNodes := NodesFormat(route.Upstream.Nodes)

// json encode for client
res, err := json.Marshal(formattedNodes)
assert.Nil(t, err)
jsonStr := string(res)
assert.Contains(t, jsonStr, `"weight":0`)
assert.Contains(t, jsonStr, `"port":80`)
assert.Contains(t, jsonStr, `"host":"127.0.0.1"`)
}

func TestNodesFormat_Map(t *testing.T) {
// route data saved in ETCD
routeStr := `{
Expand Down
13 changes: 13 additions & 0 deletions api/internal/core/store/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ func checkUpstream(upstream *entity.UpstreamDef) error {
return nil
}

func checkRemoteAddr(remoteAddrs []string) error {
for _, remoteAddr := range remoteAddrs {
if remoteAddr == "" {
return fmt.Errorf("schema validate failed: invalid field remote_addrs")
}
}
return nil
}

func checkConf(reqBody interface{}) error {
switch bodyType := reqBody.(type) {
case *entity.Route:
Expand All @@ -201,6 +210,10 @@ func checkConf(reqBody interface{}) error {
if err := checkUpstream(route.Upstream); err != nil {
return err
}
// todo: this is a temporary method, we'll drop it later
if err := checkRemoteAddr(route.RemoteAddrs); err != nil {
return err
}
case *entity.Service:
service := reqBody.(*entity.Service)
if err := checkUpstream(service.Upstream); err != nil {
Expand Down
129 changes: 129 additions & 0 deletions api/internal/core/store/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,5 +247,134 @@ func TestAPISIXJsonSchemaValidator_checkUpstream(t *testing.T) {
err = validator.Validate(route5)
assert.NotNil(t, err)
assert.EqualError(t, err, "schema validate failed: (root): Does not match pattern '^((uri|server_name|server_addr|request_uri|remote_port|remote_addr|query_string|host|hostname)|arg_[0-9a-zA-z_-]+)$'")
}

func TestAPISIXJsonSchemaValidator_Route_checkRemoteAddr(t *testing.T) {
tests := []struct {
caseDesc string
giveContent string
wantNewErr error
wantValidateErr error
}{
{
caseDesc: "correct remote_addr",
giveContent: `{
"id": "1",
"uri": "/*",
"upstream": {
"nodes": [{
"host": "127.0.0.1",
"port": 8080,
"weight": 1
}],
"type": "roundrobin"
},
"remote_addr": "127.0.0.1"
}`,
},
{
caseDesc: "correct remote_addr (CIDR)",
giveContent: `{
"id": "1",
"uri": "/*",
"upstream": {
"nodes": [{
"host": "127.0.0.1",
"port": 8080,
"weight": 1
}],
"type": "roundrobin"
},
"remote_addr": "192.168.1.0/24"
}`,
},
{
caseDesc: "invalid remote_addr",
giveContent: `{
"id": "1",
"uri": "/*",
"upstream": {
"nodes": [{
"host": "127.0.0.1",
"port": 8080,
"weight": 1
}],
"type": "roundrobin"
},
"remote_addr": "127.0.0."
}`,
wantValidateErr: fmt.Errorf("schema validate failed: remote_addr: Must validate at least one schema (anyOf)\nremote_addr: Does not match pattern '^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$'"),
},
{
caseDesc: "correct remote_addrs",
giveContent: `{
"id": "1",
"uri": "/*",
"upstream": {
"nodes": [{
"host": "127.0.0.1",
"port": 8080,
"weight": 1
}],
"type": "roundrobin"
},
"remote_addrs": ["127.0.0.1", "192.0.0.0/8", "::1", "fe80::1/64"]
}`,
},
{
caseDesc: "invalid remote_addrs",
giveContent: `{
"id": "1",
"uri": "/*",
"upstream": {
"nodes": [{
"host": "127.0.0.1",
"port": 8080,
"weight": 1
}],
"type": "roundrobin"
},
"remote_addrs": ["127.0.0.", "192.0.0.0/128", "::1"]
}`,
wantValidateErr: fmt.Errorf("schema validate failed: remote_addrs.0: Must validate at least one schema (anyOf)\nremote_addrs.0: Does not match pattern '^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$'\nremote_addrs.1: Must validate at least one schema (anyOf)\nremote_addrs.1: Does not match pattern '^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$'"),
},
{
caseDesc: "invalid remote_addrs (an empty string item)",
giveContent: `{
"id": "1",
"uri": "/*",
"upstream": {
"nodes": [{
"host": "127.0.0.1",
"port": 8080,
"weight": 1
}],
"type": "roundrobin"
},
"remote_addrs": [""]
}`,
wantValidateErr: fmt.Errorf("schema validate failed: invalid field remote_addrs"),
},
}

// todo: add a test case for "remote_addr": ""

for _, tc := range tests {
validator, err := NewAPISIXJsonSchemaValidator("main.route")
if err != nil {
assert.Equal(t, tc.wantNewErr, err, tc.caseDesc)
continue
}
route := &entity.Route{}
err = json.Unmarshal([]byte(tc.giveContent), route)
assert.Nil(t, err, tc.caseDesc)

err = validator.Validate(route)
if tc.wantValidateErr == nil {
assert.Equal(t, nil, err, tc.caseDesc)
continue
}

assert.Equal(t, tc.wantValidateErr, err, tc.caseDesc)
}
}
33 changes: 20 additions & 13 deletions api/internal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,35 +37,42 @@ func init() {
}
salt = uint16(i)
}

ips, err := getLocalIPs()
if err != nil {
panic(err)
}
_sf = sonyflake.NewSonyflake(sonyflake.Settings{
MachineID: func() (u uint16, e error) {
return sumIP(GetOutboundIP()) + salt, nil
return sumIPs(ips) + salt, nil
},
})
if _sf == nil {
panic("sonyflake init failed")
}
}

func sumIP(ip net.IP) uint16 {
func sumIPs(ips []net.IP) uint16 {
total := 0
for i := range ip {
total += int(ip[i])
for _, ip := range ips {
for i := range ip {
total += int(ip[i])
}
}
return uint16(total)
}

// Get preferred outbound ip of this machine
func GetOutboundIP() net.IP {
conn, err := net.Dial("udp", "8.8.8.8:80")
func getLocalIPs() ([]net.IP, error) {
var ips []net.IP
addrs, err := net.InterfaceAddrs()
if err != nil {
panic(err)
return ips, err
}
defer conn.Close()

localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP
for _, a := range addrs {
if ipNet, ok := a.(*net.IPNet); ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil {
ips = append(ips, ipNet.IP)
}
}
return ips, nil
}

func GetFlakeUid() uint64 {
Expand Down
14 changes: 13 additions & 1 deletion api/internal/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
package utils

import (
"github.com/stretchr/testify/assert"
"testing"

"github.com/stretchr/testify/assert"
)

func TestGetFlakeUid(t *testing.T) {
Expand All @@ -29,4 +30,15 @@ func TestGetFlakeUid(t *testing.T) {
func TestGetFlakeUidStr(t *testing.T) {
id := GetFlakeUidStr()
assert.NotEqual(t, "", id)
assert.Equal(t, 18, len(id))
}

func TestGetLocalIPs(t *testing.T) {
_, err := getLocalIPs()
assert.Equal(t, nil, err)
}

func TestSumIPs_with_nil(t *testing.T) {
total := sumIPs(nil)
assert.Equal(t, uint16(0), total)
}
2 changes: 1 addition & 1 deletion api/test/docker-deploy/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ services:
depends_on:
- etcd
ports:
- '8080:8080/tcp'
- '9000:9000/tcp'
networks:
apisix_dashboard_e2e:
ipv4_address: 172.16.238.40
Expand Down
2 changes: 1 addition & 1 deletion api/test/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ COPY --from=build-env /usr/share/zoneinfo/Hongkong /etc/localtime

RUN mkdir logs

EXPOSE 8080
EXPOSE 9000

RUN chmod +x ./entry.sh

Expand Down
6 changes: 3 additions & 3 deletions api/test/docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ services:
context: ../../
dockerfile: test/docker/Dockerfile-apisix
args:
- APISIX_VERSION=master
- APISIX_VERSION=2.1
restart: always
volumes:
- ./apisix_config.yaml:/usr/local/apisix/conf/config.yaml:ro
Expand All @@ -153,7 +153,7 @@ services:
context: ../../
dockerfile: test/docker/Dockerfile-apisix
args:
- APISIX_VERSION=master
- APISIX_VERSION=2.1
restart: always
volumes:
- ./apisix_config.yaml:/usr/local/apisix/conf/config.yaml:ro
Expand Down Expand Up @@ -181,7 +181,7 @@ services:
- node2
- node3
ports:
- '8080:8080/tcp'
- '9000:9000/tcp'
networks:
apisix_dashboard_e2e:
ipv4_address: 172.16.238.40
Expand Down
2 changes: 1 addition & 1 deletion api/test/docker/manager-api-conf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
conf:
listen:
host: 0.0.0.0 # `manager api` listening ip or host name. It's for e2e test, so it is set to 0.0.0.0
port: 8080 # `manager api` listening port
port: 9000 # `manager api` listening port
etcd:
endpoints: # supports defining multiple etcd host addresses for an etcd cluster
- 172.16.238.10:2379 # ips here are defined in docker compose.
Expand Down
Loading

0 comments on commit 8b92a1d

Please sign in to comment.