From 18744a5082c4286a62503f35f2e1c60656262cc3 Mon Sep 17 00:00:00 2001 From: idbeta Date: Tue, 1 Dec 2020 13:35:46 +0800 Subject: [PATCH 1/7] test: add route with priority (E2E) (#893) test: add route with priority (E2E) (#893) --- api/test/e2e/route_with_priority_test.go | 108 +++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 api/test/e2e/route_with_priority_test.go diff --git a/api/test/e2e/route_with_priority_test.go b/api/test/e2e/route_with_priority_test.go new file mode 100644 index 0000000000..c5ded82093 --- /dev/null +++ b/api/test/e2e/route_with_priority_test.go @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package e2e + +import ( + "net/http" + "testing" +) + +func TestRoute_with_priority(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "add another route with no priority (default 0)", + Object: ManagerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r1", + Body: `{ + "uri": "/server_port", + "methods": ["GET"], + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "172.16.238.20", + "port": 1981, + "weight": 1 + }] + } + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "access the route", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/server_port", + ExpectStatus: http.StatusOK, + ExpectBody: "1981", + Sleep: sleepTime, + }, + { + caseDesc: "add another route with valid priority (1), upstream is different from the others", + Object: ManagerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r2", + Body: `{ + "uri": "/server_port", + "methods": ["GET"], + "priority": 1, + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "172.16.238.20", + "port": 1982, + "weight": 1 + }] + } + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "access the route to determine whether it meets the priority (compair 1 and default)", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/server_port", + ExpectStatus: http.StatusOK, + ExpectBody: "1982", + Sleep: sleepTime, + }, + { + caseDesc: "delete route (r1)", + Object: ManagerApiExpect(t), + Method: http.MethodDelete, + Path: "/apisix/admin/routes/r1", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + Sleep: sleepTime, + }, + { + caseDesc: "delete route (r2)", + Object: ManagerApiExpect(t), + Method: http.MethodDelete, + Path: "/apisix/admin/routes/r2", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + Sleep: sleepTime, + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } +} From 68bdd1dbbb3fb4f7d92488d693ac9aa2eb5749d1 Mon Sep 17 00:00:00 2001 From: idbeta Date: Tue, 1 Dec 2020 15:19:59 +0800 Subject: [PATCH 2/7] test: add route with invalid remote_addr (E2E) (#874) resolve #631 --- api/test/e2e/route_remote_addr_test.go | 121 +++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 api/test/e2e/route_remote_addr_test.go diff --git a/api/test/e2e/route_remote_addr_test.go b/api/test/e2e/route_remote_addr_test.go new file mode 100644 index 0000000000..8cdf6e3225 --- /dev/null +++ b/api/test/e2e/route_remote_addr_test.go @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package e2e + +import ( + "net/http" + "testing" +) + +func TestRoute_add_with_invalid_remote_addr(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "config route with invalid remote_addr", + Object: ManagerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r1", + Body: `{ + "uri": "/hello", + "remote_addr": "127.0.0.", + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "172.16.238.20", + "port": 1980, + "weight": 1 + }] + } + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusBadRequest, + ExpectBody: "\"code\":10000,\"message\":\"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: "verify route", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusNotFound, + Sleep: sleepTime, + }, + { + caseDesc: "config route with invalid remote_addr", + Object: ManagerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r1", + Body: `{ + "uri": "/hello", + "remote_addr": "127.0.0.aa", + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "172.16.238.20", + "port": 1980, + "weight": 1 + }] + } + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusBadRequest, + ExpectBody: "\"code\":10000,\"message\":\"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: "verify route", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusNotFound, + Sleep: sleepTime, + }, + { + caseDesc: "config route with invalid remote_addrs", + Object: ManagerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r1", + Body: `{ + "uri": "/hello", + "remote_addrs": ["127.0.0.1","192.168.0."], + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "172.16.238.20", + "port": 1980, + "weight": 1 + }] + } + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusBadRequest, + ExpectBody: "\"code\":10000,\"message\":\"schema validate failed: remote_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: "verify route", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusNotFound, + Sleep: sleepTime, + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } +} From f464bbd3451f235c3d1492067e6d06a4a20e1ff0 Mon Sep 17 00:00:00 2001 From: nic-chen <33000667+nic-chen@users.noreply.github.com> Date: Tue, 1 Dec 2020 15:22:25 +0800 Subject: [PATCH 3/7] chore: change the default port of manager api from 8080 to 9000 (#931) close #901 --- .github/workflows/backend-unit-test.yml | 2 +- Dockerfile | 2 +- api/conf/conf.yaml | 2 +- api/test/docker-deploy/docker-compose.yaml | 2 +- api/test/docker/Dockerfile | 2 +- api/test/docker/docker-compose.yaml | 2 +- api/test/docker/manager-api-conf.yaml | 2 +- api/test/e2e/base.go | 4 ++-- api/test/shell/docker_deploy_test.sh | 8 ++++---- docs/deploy-with-docker.md | 4 ++-- docs/deploy-with-docker.zh-CN.md | 4 ++-- docs/deploy.md | 2 +- docs/deploy.zh-CN.md | 2 +- 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/backend-unit-test.yml b/.github/workflows/backend-unit-test.yml index bd2154cbc9..8357857a3a 100644 --- a/.github/workflows/backend-unit-test.yml +++ b/.github/workflows/backend-unit-test.yml @@ -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 diff --git a/Dockerfile b/Dockerfile index a1e219f4da..4e340117e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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" ] diff --git a/api/conf/conf.yaml b/api/conf/conf.yaml index 2270e72866..efc996c432 100644 --- a/api/conf/conf.yaml +++ b/api/conf/conf.yaml @@ -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 diff --git a/api/test/docker-deploy/docker-compose.yaml b/api/test/docker-deploy/docker-compose.yaml index a8fba53a46..57df46269b 100644 --- a/api/test/docker-deploy/docker-compose.yaml +++ b/api/test/docker-deploy/docker-compose.yaml @@ -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 diff --git a/api/test/docker/Dockerfile b/api/test/docker/Dockerfile index b4fa2c3000..c7607d60c8 100644 --- a/api/test/docker/Dockerfile +++ b/api/test/docker/Dockerfile @@ -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 diff --git a/api/test/docker/docker-compose.yaml b/api/test/docker/docker-compose.yaml index d72dc3cbf8..ce53e3b039 100644 --- a/api/test/docker/docker-compose.yaml +++ b/api/test/docker/docker-compose.yaml @@ -181,7 +181,7 @@ services: - node2 - node3 ports: - - '8080:8080/tcp' + - '9000:9000/tcp' networks: apisix_dashboard_e2e: ipv4_address: 172.16.238.40 diff --git a/api/test/docker/manager-api-conf.yaml b/api/test/docker/manager-api-conf.yaml index f3b3a05af7..3e9c9f0ffa 100644 --- a/api/test/docker/manager-api-conf.yaml +++ b/api/test/docker/manager-api-conf.yaml @@ -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. diff --git a/api/test/e2e/base.go b/api/test/e2e/base.go index 0eaa30a896..6873767037 100644 --- a/api/test/e2e/base.go +++ b/api/test/e2e/base.go @@ -39,7 +39,7 @@ func init() { "password": "admin" }`) - url := "http://127.0.0.1:8080/apisix/admin/user/login" + url := "http://127.0.0.1:9000/apisix/admin/user/login" req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(requestBody)) if err != nil { panic(err) @@ -84,7 +84,7 @@ func httpGet(url string) ([]byte, int, error) { } func ManagerApiExpect(t *testing.T) *httpexpect.Expect { - return httpexpect.New(t, "http://127.0.0.1:8080") + return httpexpect.New(t, "http://127.0.0.1:9000") } func APISIXExpect(t *testing.T) *httpexpect.Expect { diff --git a/api/test/shell/docker_deploy_test.sh b/api/test/shell/docker_deploy_test.sh index eb39633019..65ddd4f2df 100755 --- a/api/test/shell/docker_deploy_test.sh +++ b/api/test/shell/docker_deploy_test.sh @@ -20,15 +20,15 @@ set -ex # web page -curl http://127.0.0.1:8080 -code=$(curl -k -i -m 20 -o /dev/null -s -w %{http_code} http://127.0.0.1:8080) +curl http://127.0.0.1:9000 +code=$(curl -k -i -m 20 -o /dev/null -s -w %{http_code} http://127.0.0.1:9000) if [ ! $code -eq 200 ]; then echo "failed: failed to custom port" exit 1 fi # login -resp=$(curl http://127.0.0.1:8080/apisix/admin/user/login -X POST -d '{"username":"admin", "password": "admin"}') +resp=$(curl http://127.0.0.1:9000/apisix/admin/user/login -X POST -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" @@ -36,7 +36,7 @@ fi # plugin orchestration echo $token -code=$(curl -k -i -m 20 -o /dev/null -s -w %{http_code} http://127.0.0.1:8080/apisix/admin/routes/1 -X PUT -i -H "Authorization: $token" -d '{"id":"1","uri":"/index.html","upstream":{"type":"roundrobin","nodes":[{"host":"www.test.com","port":80,"weight":1}]},"script":{"rule":{"root":"451106f8-560c-43a4-acf2-2a6ed0ea57b8","451106f8-560c-43a4-acf2-2a6ed0ea57b8":[["code==403","b93d622c-92ef-48b4-b6bb-57e1ce893ee3"],["","988ef5c2-c896-4606-a666-3d4cbe24a731"]]},"conf":{"451106f8-560c-43a4-acf2-2a6ed0ea57b8":{"name":"uri-blocker","conf":{"block_rules":["root.exe","root.m+"],"rejected_code":403}},"988ef5c2-c896-4606-a666-3d4cbe24a731":{"name":"kafka-logger","conf":{"batch_max_size":1000,"broker_list":{},"buffer_duration":60,"inactive_timeout":5,"include_req_body":false,"kafka_topic":"1","key":"2","max_retry_count":0,"name":"kafkalogger","retry_delay":1,"timeout":3}},"b93d622c-92ef-48b4-b6bb-57e1ce893ee3":{"name":"fault-injection","conf":{"abort":{"body":"200","http_status":300},"delay":{"duration":500}}}},"chart":{}}}') +code=$(curl -k -i -m 20 -o /dev/null -s -w %{http_code} http://127.0.0.1:9000/apisix/admin/routes/1 -X PUT -i -H "Authorization: $token" -d '{"id":"1","uri":"/index.html","upstream":{"type":"roundrobin","nodes":[{"host":"www.test.com","port":80,"weight":1}]},"script":{"rule":{"root":"451106f8-560c-43a4-acf2-2a6ed0ea57b8","451106f8-560c-43a4-acf2-2a6ed0ea57b8":[["code==403","b93d622c-92ef-48b4-b6bb-57e1ce893ee3"],["","988ef5c2-c896-4606-a666-3d4cbe24a731"]]},"conf":{"451106f8-560c-43a4-acf2-2a6ed0ea57b8":{"name":"uri-blocker","conf":{"block_rules":["root.exe","root.m+"],"rejected_code":403}},"988ef5c2-c896-4606-a666-3d4cbe24a731":{"name":"kafka-logger","conf":{"batch_max_size":1000,"broker_list":{},"buffer_duration":60,"inactive_timeout":5,"include_req_body":false,"kafka_topic":"1","key":"2","max_retry_count":0,"name":"kafkalogger","retry_delay":1,"timeout":3}},"b93d622c-92ef-48b4-b6bb-57e1ce893ee3":{"name":"fault-injection","conf":{"abort":{"body":"200","http_status":300},"delay":{"duration":500}}}},"chart":{}}}') if [ ! $code -eq 200 ]; then echo "failed to create route" exit 1 diff --git a/docs/deploy-with-docker.md b/docs/deploy-with-docker.md index 4d89f0f1a0..1e747bd84c 100644 --- a/docs/deploy-with-docker.md +++ b/docs/deploy-with-docker.md @@ -55,7 +55,7 @@ Kindly note: ```sh # /path/to/conf.yaml Requires an absolute path pointing to the configuration file mentioned above. -$ docker run -d -p 80:8080 -v /path/to/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml --name apisix-dashboard apisix-dashboard:$tag +$ docker run -d -p 9000:9000 -v /path/to/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml --name apisix-dashboard apisix-dashboard:$tag ``` 3. Check if the container started successfully @@ -64,7 +64,7 @@ $ docker run -d -p 80:8080 -v /path/to/conf.yaml:/usr/local/apisix-dashboard/con $ docker ps -a ``` -If the container `apisix-dashboard` is ok, visit `http://127.0.0.1:8080` to use the dashboard with GUI, where the default username and password are `admin`. +If the container `apisix-dashboard` is ok, visit `http://127.0.0.1:9000` to use the dashboard with GUI, where the default username and password are `admin`. 4. Stop the Dashboard diff --git a/docs/deploy-with-docker.zh-CN.md b/docs/deploy-with-docker.zh-CN.md index f84f56fa81..4eecd0f4d3 100644 --- a/docs/deploy-with-docker.zh-CN.md +++ b/docs/deploy-with-docker.zh-CN.md @@ -55,7 +55,7 @@ $ docker build -t apisix-dashboard:$tag . --build-arg ENABLE_PROXY=true ```sh # /path/to/conf.yaml 需使用 绝对路径 指向上述提到的配置文件 -$ docker run -d -p 80:8080 -v /path/to/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml --name apisix-dashboard apisix-dashboard:$tag +$ docker run -d -p 9000:9000 -v /path/to/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml --name apisix-dashboard apisix-dashboard:$tag ``` 3. 检查容器是否启动成功 @@ -64,7 +64,7 @@ $ docker run -d -p 80:8080 -v /path/to/conf.yaml:/usr/local/apisix-dashboard/con $ docker ps -a ``` -若容器 `apisix-dashboard` 状态正常,访问 `http://127.0.0.1:8080` 以使用有前端界面的控制台,默认用户密码均为 `admin`。 +若容器 `apisix-dashboard` 状态正常,访问 `http://127.0.0.1:9000` 以使用有前端界面的控制台,默认用户密码均为 `admin`。 4. 停止 Dashboard diff --git a/docs/deploy.md b/docs/deploy.md index 32e7f9fad5..408de2cbb0 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -78,7 +78,7 @@ $ ./manager-api $ nohup ./manager-api & ``` -4. Without changing the configuration, visit `http://127.0.0.1:8080` to use the dashboard with GUI, where the default username and password are `admin`. +4. Without changing the configuration, visit `http://127.0.0.1:9000` to use the dashboard with GUI, where the default username and password are `admin`. 5. Stop the Dashboard diff --git a/docs/deploy.zh-CN.md b/docs/deploy.zh-CN.md index 4239e53162..11e9642f33 100644 --- a/docs/deploy.zh-CN.md +++ b/docs/deploy.zh-CN.md @@ -77,7 +77,7 @@ $ ./manager-api $ nohup ./manager-api & ``` -4. 在未修改配置的情况下,访问 `http://127.0.0.1:8080` 以使用有前端界面的控制台,默认用户密码均为 `admin`。 +4. 在未修改配置的情况下,访问 `http://127.0.0.1:9000` 以使用有前端界面的控制台,默认用户密码均为 `admin`。 5. 停止 Dashboard From d42d2e8fdf009a2493115e18e60624899fa6bc60 Mon Sep 17 00:00:00 2001 From: nic-chen <33000667+nic-chen@users.noreply.github.com> Date: Tue, 1 Dec 2020 17:20:48 +0800 Subject: [PATCH 4/7] fix: upstream node can't display when the node's weight is set to 0 (#934) --- api/internal/core/entity/format.go | 3 ++- api/internal/core/entity/format_test.go | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/api/internal/core/entity/format.go b/api/internal/core/entity/format.go index a1384b4fe8..c4bb9f9dc5 100644 --- a/api/internal/core/entity/format.go +++ b/api/internal/core/entity/format.go @@ -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{}) diff --git a/api/internal/core/entity/format_test.go b/api/internal/core/entity/format_test.go index ab6323226e..7ca9d4cb67 100644 --- a/api/internal/core/entity/format_test.go +++ b/api/internal/core/entity/format_test.go @@ -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 := `{ From 7d79386c0c7adcafb5389215c58ac4e8a0f2e8e8 Mon Sep 17 00:00:00 2001 From: nic-chen <33000667+nic-chen@users.noreply.github.com> Date: Tue, 1 Dec 2020 17:32:54 +0800 Subject: [PATCH 5/7] ci: run the E2E test case with APISIX 2.1 (#937) --- api/test/docker/docker-compose.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/test/docker/docker-compose.yaml b/api/test/docker/docker-compose.yaml index ce53e3b039..5bdb4f4888 100644 --- a/api/test/docker/docker-compose.yaml +++ b/api/test/docker/docker-compose.yaml @@ -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 @@ -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 From 47d67d61ef98b5ce8ae482dc0bf135f015e09a4f Mon Sep 17 00:00:00 2001 From: nic-chen <33000667+nic-chen@users.noreply.github.com> Date: Tue, 1 Dec 2020 20:36:27 +0800 Subject: [PATCH 6/7] test: add e2e test cases for route with plugin cors (#906) test: add e2e test cases for route with plugin cors (#906) --- api/test/e2e/base.go | 2 + api/test/e2e/route_with_plugin_cors_test.go | 229 ++++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 api/test/e2e/route_with_plugin_cors_test.go diff --git a/api/test/e2e/base.go b/api/test/e2e/base.go index 6873767037..346361f527 100644 --- a/api/test/e2e/base.go +++ b/api/test/e2e/base.go @@ -149,6 +149,8 @@ func testCaseCheck(tc HttpTestCase) { req = expectObj.DELETE(tc.Path) case http.MethodPatch: req = expectObj.PATCH(tc.Path) + case http.MethodOptions: + req = expectObj.OPTIONS(tc.Path) default: } diff --git a/api/test/e2e/route_with_plugin_cors_test.go b/api/test/e2e/route_with_plugin_cors_test.go new file mode 100644 index 0000000000..d8afb919d1 --- /dev/null +++ b/api/test/e2e/route_with_plugin_cors_test.go @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package e2e + +import ( + "net/http" + "testing" +) + +func TestRoute_With_Plugin_Cors(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "make sure the route is not created", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + ExpectStatus: http.StatusNotFound, + ExpectBody: `{"error_msg":"404 Route Not Found"}`, + }, + { + caseDesc: "create route with cors default setting", + Object: ManagerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r1", + Body: `{ + "uri": "/hello", + "plugins": { + "cors": {} + }, + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "172.16.238.20", + "port": 1981, + "weight": 1 + }] + } + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "verify route with cors default setting", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + ExpectStatus: http.StatusOK, + ExpectHeaders: map[string]string{ + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "*", + }, + ExpectBody: "hello world", + Sleep: sleepTime, + }, + { + caseDesc: "update route with specified setting", + Object: ManagerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r1", + Body: `{ + "uri": "/hello", + "plugins": { + "cors": { + "allow_origins": "http://sub.domain.com,http://sub2.domain.com", + "allow_methods": "GET,POST", + "allow_headers": "headr1,headr2", + "expose_headers": "ex-headr1,ex-headr2", + "max_age": 50, + "allow_credential": true + } + }, + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "172.16.238.20", + "port": 1981, + "weight": 1 + }] + } + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "verify route with cors specified setting", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + Headers: map[string]string{ + "Origin": "http://sub2.domain.com", + "resp-vary": "Via", + }, + ExpectStatus: http.StatusOK, + ExpectHeaders: map[string]string{ + "Access-Control-Allow-Origin": "http://sub2.domain.com", + "Access-Control-Allow-Methods": "GET,POST", + "Access-Control-Allow-Headers": "headr1,headr2", + "Access-Control-Expose-Headers": "ex-headr1,ex-headr2", + "Access-Control-Max-Age": "50", + }, + ExpectBody: "hello world", + Sleep: sleepTime, + }, + { + caseDesc: "verify route with cors specified no match origin", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + Headers: map[string]string{ + "Origin": "http://sub3.domain.com", + }, + ExpectStatus: http.StatusOK, + ExpectHeaders: map[string]string{ + "Access-Control-Allow-Origin": "", + "Access-Control-Allow-Methods": "", + "Access-Control-Allow-Headers": "", + "Access-Control-Expose-Headers": "", + "Access-Control-Max-Age": "", + }, + ExpectBody: "hello world", + Sleep: sleepTime, + }, + { + caseDesc: "verify route with options method", + Object: APISIXExpect(t), + Method: http.MethodOptions, + Headers: map[string]string{ + "Origin": "http://sub2.domain.com", + }, + Path: "/hello", + ExpectStatus: http.StatusOK, + ExpectHeaders: map[string]string{ + "Access-Control-Allow-Origin": "http://sub2.domain.com", + "Access-Control-Allow-Methods": "GET,POST", + "Access-Control-Allow-Headers": "headr1,headr2", + "Access-Control-Expose-Headers": "ex-headr1,ex-headr2", + "Access-Control-Max-Age": "50", + }, + ExpectBody: "", + }, + { + caseDesc: "update route with cors setting force wildcard", + Object: ManagerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r1", + Body: `{ + "uri": "/hello", + "plugins": { + "cors": { + "allow_origins": "**", + "allow_methods": "**", + "allow_headers": "**", + "expose_headers": "*" + } + }, + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "172.16.238.20", + "port": 1981, + "weight": 1 + }] + } + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "verify route with cors setting force wildcard", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + Headers: map[string]string{ + "Origin": "https://sub.domain.com", + "ExternalHeader1": "val", + "ExternalHeader2": "val", + "ExternalHeader3": "val", + "Access-Control-Request-Headers": "req-header1,req-header2", + }, + ExpectStatus: http.StatusOK, + ExpectHeaders: map[string]string{ + "Access-Control-Allow-Origin": "https://sub.domain.com", + "Vary": "Origin", + "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,CONNECT,TRACE", + "Access-Control-Allow-Headers": "req-header1,req-header2", + "Access-Control-Expose-Headers": "*", + "Access-Control-Allow-Credentials": "", + }, + ExpectBody: "hello world", + Sleep: sleepTime, + }, + { + caseDesc: "delete route", + Object: ManagerApiExpect(t), + Method: http.MethodDelete, + Path: "/apisix/admin/routes/r1", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "make sure the route deleted", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello", + ExpectStatus: http.StatusNotFound, + ExpectBody: `{"error_msg":"404 Route Not Found"}`, + Sleep: sleepTime, + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } + +} From 95f26122fee30d2fcbd18d98433b106c09e9bdca Mon Sep 17 00:00:00 2001 From: nic-chen <33000667+nic-chen@users.noreply.github.com> Date: Wed, 2 Dec 2020 09:40:42 +0800 Subject: [PATCH 7/7] CD: auto deploy codes on the master branch to the online demo (#929) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: should deploy code in master branch to the online demo * ci: take a test, should remove pr trigger later * ci: remove pr trigger * doc: fix description about build docker image in doc * fix typo Co-authored-by: 琚致远 --- .github/workflows/deploy-with-docker.yml | 2 +- docs/deploy-with-docker.md | 4 ++++ docs/deploy-with-docker.zh-CN.md | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-with-docker.yml b/.github/workflows/deploy-with-docker.yml index 8cd08af216..5fa7e9d741 100644 --- a/.github/workflows/deploy-with-docker.yml +++ b/.github/workflows/deploy-with-docker.yml @@ -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: | diff --git a/docs/deploy-with-docker.md b/docs/deploy-with-docker.md index 1e747bd84c..185fbefefd 100644 --- a/docs/deploy-with-docker.md +++ b/docs/deploy-with-docker.md @@ -38,6 +38,10 @@ $ docker build -t apisix-dashboard:$tag . # For users in mainland China, the `ENABLE_PROXY` parameter can be provided to speed up module downloads. $ docker build -t apisix-dashboard:$tag . --build-arg ENABLE_PROXY=true + +# If you want to use the latest codes to build, you can specify the `APISIX_DASHBOARD_VERSION` parameter to `master`. +# This parameter can also be specified as branch name of a specific version, such as `v2.0`. +$ docker build -t apisix-dashboard:$tag . --build-arg APISIX_DASHBOARD_VERSION=master ``` ## Launch diff --git a/docs/deploy-with-docker.zh-CN.md b/docs/deploy-with-docker.zh-CN.md index 4eecd0f4d3..fb7c3622a6 100644 --- a/docs/deploy-with-docker.zh-CN.md +++ b/docs/deploy-with-docker.zh-CN.md @@ -38,6 +38,9 @@ $ docker build -t apisix-dashboard:$tag . # 对于中国大陆的用户,可启用 `ENABLE_PROXY` 参数加快模块下载速度。 $ docker build -t apisix-dashboard:$tag . --build-arg ENABLE_PROXY=true + +# 如果需要使用最新代码构建,可启用 `APISIX_DASHBOARD_VERSION` 参数指定为 `master` ,此参数也可以指定为其他版本的分支名,如 `v2.0` 。 +$ docker build -t apisix-dashboard:$tag . --build-arg APISIX_DASHBOARD_VERSION=master ``` ## 启动