Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add token support for consul discovery (#9532) #10278

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions apisix/discovery/consul/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -197,21 +197,20 @@ local function get_opts(consul_server, is_catalog)
port = consul_server.port,
connect_timeout = consul_server.connect_timeout,
read_timeout = consul_server.read_timeout,
default_args = {
token = consul_server.token,
}
}
if not consul_server.keepalive then
return opts
end

opts.default_args.wait = consul_server.wait_timeout --blocked wait!=0; unblocked by wait=0

if is_catalog then
sevensolutions marked this conversation as resolved.
Show resolved Hide resolved
opts.default_args = {
wait = consul_server.wait_timeout, --blocked wait!=0; unblocked by wait=0
index = consul_server.catalog_index,
}
opts.default_args.index = consul_server.catalog_index
else
opts.default_args = {
wait = consul_server.wait_timeout, --blocked wait!=0; unblocked by wait=0
index = consul_server.health_index,
}
opts.default_args.index = consul_server.health_index
end

return opts
Expand Down Expand Up @@ -396,6 +395,9 @@ function _M.connect(premature, consul_server, retry_delay)
port = consul_server.port,
connect_timeout = consul_server.connect_timeout,
read_timeout = consul_server.read_timeout,
default_args = {
token = consul_server.token
}
})
local catalog_success, catalog_res, catalog_err = pcall(function()
return consul_client:get(consul_server.consul_watch_catalog_url)
Expand Down Expand Up @@ -545,6 +547,7 @@ local function format_consul_params(consul_conf)
core.table.insert(consul_server_list, {
host = host,
port = port,
token = consul_conf.token,
connect_timeout = consul_conf.timeout.connect,
read_timeout = consul_conf.timeout.read,
wait_timeout = consul_conf.timeout.wait,
Expand Down
1 change: 1 addition & 0 deletions apisix/discovery/consul/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ return {
type = "string",
}
},
token = {type = "string", default = ""},
fetch_interval = {type = "integer", minimum = 1, default = 3},
keepalive = {
type = "boolean",
Expand Down
18 changes: 7 additions & 11 deletions apisix/discovery/consul_kv/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -320,18 +320,14 @@ end

local function format_consul_params(consul_conf)
local consul_server_list = core.table.new(0, #consul_conf.servers)
local args
local args = {
token = consul_conf.token,
recurse = true
}

if consul_conf.keepalive == false then
args = {
recurse = true,
}
elseif consul_conf.keepalive then
args = {
recurse = true,
wait = consul_conf.timeout.wait, --blocked wait!=0; unblocked by wait=0
index = 0,
}
if consul_conf.keepalive then
args.wait = consul_conf.timeout.wait --blocked wait!=0; unblocked by wait=0
args.index = 0
end

for _, v in pairs(consul_conf.servers) do
Expand Down
1 change: 1 addition & 0 deletions apisix/discovery/consul_kv/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ return {
type = "string",
}
},
token = {type = "string", default = ""},
fetch_interval = {type = "integer", minimum = 1, default = 3},
keepalive = {
type = "boolean",
Expand Down
9 changes: 9 additions & 0 deletions ci/pod/docker-compose.first.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ services:
networks:
consul_net:

consul_3:
image: hashicorp/consul:1.16.2
sevensolutions marked this conversation as resolved.
Show resolved Hide resolved
restart: unless-stopped
ports:
- "8502:8500"
command: [ "consul", "agent", "-server", "-bootstrap-expect=1", "-client", "0.0.0.0", "-log-level", "info", "-data-dir=/consul/data", "-enable-script-checks", "-ui", "-hcl", "acl = {\nenabled = true\ndefault_policy = \"deny\"\nenable_token_persistence = true\ntokens = {\nagent = \"2b778dd9-f5f1-6f29-b4b4-9a5fa948757a\"\n}}" ]
networks:
consul_net:

## Nacos cluster
nacos_auth:
hostname: nacos1
Expand Down
1 change: 1 addition & 0 deletions docs/en/latest/discovery/consul.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ discovery:
servers: # make sure service name is unique in these consul servers
- "http://127.0.0.1:8500" # `http://127.0.0.1:8500` and `http://127.0.0.1:8600` are different clusters
- "http://127.0.0.1:8600" # `consul` service is default skip service
token: "..." # if your consul cluster has enabled acl access control, you need to specify the token
skip_services: # if you need to skip special services
- "service_a"
timeout:
Expand Down
1 change: 1 addition & 0 deletions docs/en/latest/discovery/consul_kv.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ discovery:
servers:
- "http://127.0.0.1:8500"
- "http://127.0.0.1:8600"
token: "..." # if your consul cluster has enabled acl access control, you need to specify the token
prefix: "upstreams"
skip_keys: # if you need to skip special keys
- "upstreams/unused_api/"
Expand Down
2 changes: 1 addition & 1 deletion t/control/discovery.t
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ GET /t
--- error_code: 200
--- response_body
{}
{"fetch_interval":3,"keepalive":true,"prefix":"upstreams","servers":["http://127.0.0.1:8500","http://127.0.0.1:8600"],"timeout":{"connect":2000,"read":2000,"wait":60},"weight":1}
{"fetch_interval":3,"keepalive":true,"prefix":"upstreams","servers":["http://127.0.0.1:8500","http://127.0.0.1:8600"],"timeout":{"connect":2000,"read":2000,"wait":60},"token":"","weight":1}
--- error_log
connect consul
Expand Down
124 changes: 124 additions & 0 deletions t/discovery/consul.t
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,40 @@ discovery:
max_fails: 1
_EOC_

our $yaml_config_with_acl = <<_EOC_;
apisix:
node_listen: 1984
enable_control: true
control:
ip: 127.0.0.1
port: 9090
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
consul:
servers:
- "http://127.0.0.1:8502"
token: "2b778dd9-f5f1-6f29-b4b4-9a5fa948757a"
skip_services:
- "service_c"
timeout:
connect: 1000
read: 1000
wait: 60
weight: 1
fetch_interval: 1
keepalive: true
default_service:
host: "127.0.0.1"
port: 20999
metadata:
fail_timeout: 1
weight: 1
max_fails: 1
_EOC_


run_tests();

Expand Down Expand Up @@ -657,3 +691,93 @@ location /sleep {
qr/server 1\n/,
]
--- ignore_error_log
=== TEST 14: bootstrap acl
--- config
location /v1/acl {
proxy_pass http://127.0.0.1:8502;
}
--- request eval
"PUT /v1/acl/bootstrap\n" . "{\"BootstrapSecret\": \"2b778dd9-f5f1-6f29-b4b4-9a5fa948757a\"}"
--- error_code_like: ^(?:200|403)$
=== TEST 15: test register and unregister nodes with acl
--- yaml_config eval: $::yaml_config_with_acl
--- apisix_yaml
routes:
-
uri: /*
upstream:
service_name: service-a
discovery_type: consul
type: roundrobin
#END
--- config
location /v1/agent {
proxy_pass http://127.0.0.1:8502;
proxy_set_header X-Consul-Token "2b778dd9-f5f1-6f29-b4b4-9a5fa948757a";
}
location /sleep {
content_by_lua_block {
local args = ngx.req.get_uri_args()
local sec = args.sec or "2"
ngx.sleep(tonumber(sec))
ngx.say("ok")
}
}
--- timeout: 6
--- pipelined_requests eval
[
"PUT /v1/agent/service/register\n" . "{\"ID\":\"service-a1\",\"Name\":\"service-a\",\"Tags\":[\"primary\",\"v1\"],\"Address\":\"127.0.0.1\",\"Port\":30513,\"Meta\":{\"service_b_version\":\"4.1\"},\"EnableTagOverride\":false,\"Weights\":{\"Passing\":10,\"Warning\":1}}",
"PUT /v1/agent/service/register\n" . "{\"ID\":\"service-a2\",\"Name\":\"service-a\",\"Tags\":[\"primary\",\"v1\"],\"Address\":\"127.0.0.1\",\"Port\":30514,\"Meta\":{\"service_b_version\":\"4.1\"},\"EnableTagOverride\":false,\"Weights\":{\"Passing\":10,\"Warning\":1}}",
"GET /sleep",
"GET /hello?random1",
"GET /hello?random2",
"GET /hello?random3",
"GET /hello?random4",
"PUT /v1/agent/service/deregister/service-a1",
"PUT /v1/agent/service/deregister/service-a2",
"PUT /v1/agent/service/register\n" . "{\"ID\":\"service-a1\",\"Name\":\"service-a\",\"Tags\":[\"primary\",\"v1\"],\"Address\":\"127.0.0.1\",\"Port\":30511,\"Meta\":{\"service_b_version\":\"4.1\"},\"EnableTagOverride\":false,\"Weights\":{\"Passing\":10,\"Warning\":1}}",
"PUT /v1/agent/service/register\n" . "{\"ID\":\"service-a2\",\"Name\":\"service-a\",\"Tags\":[\"primary\",\"v1\"],\"Address\":\"127.0.0.1\",\"Port\":30512,\"Meta\":{\"service_b_version\":\"4.1\"},\"EnableTagOverride\":false,\"Weights\":{\"Passing\":10,\"Warning\":1}}",
"GET /sleep?sec=5",
"GET /hello?random1",
"GET /hello?random2",
"GET /hello?random3",
"GET /hello?random4",
"PUT /v1/agent/service/deregister/service-a1",
"PUT /v1/agent/service/deregister/service-a2",
]
--- response_body_like eval
[
qr//,
qr//,
qr/ok\n/,
qr/server [3-4]\n/,
qr/server [3-4]\n/,
qr/server [3-4]\n/,
qr/server [3-4]\n/,
qr//,
qr//,
qr//,
qr//,
qr/ok\n/,
qr/server [1-2]\n/,
qr/server [1-2]\n/,
qr/server [1-2]\n/,
qr/server [1-2]\n/,
qr//,
qr//
]
--- ignore_error_log
120 changes: 120 additions & 0 deletions t/discovery/consul_kv.t
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,37 @@ discovery:
max_fails: 1
_EOC_

our $yaml_config_with_acl = <<_EOC_;
apisix:
node_listen: 1984
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
discovery:
consul_kv:
servers:
- "http://127.0.0.1:8502"
token: "2b778dd9-f5f1-6f29-b4b4-9a5fa948757a"
prefix: "upstreams"
skip_keys:
- "upstreams/unused_api/"
timeout:
connect: 1000
read: 1000
wait: 60
weight: 1
fetch_interval: 1
keepalive: true
default_service:
host: "127.0.0.1"
port: 20999
metadata:
fail_timeout: 1
weight: 1
max_fails: 1
_EOC_


run_tests();

Expand Down Expand Up @@ -576,3 +607,92 @@ qr/retry connecting consul after \d seconds/
--- grep_error_log_out
retry connecting consul after 1 seconds
retry connecting consul after 4 seconds
=== TEST 13: bootstrap acl
--- config
location /v1/acl {
proxy_pass http://127.0.0.1:8502;
}
--- request eval
"PUT /v1/acl/bootstrap\n" . "{\"BootstrapSecret\": \"2b778dd9-f5f1-6f29-b4b4-9a5fa948757a\"}"
--- error_code_like: ^(?:200|403)$
=== TEST 14: test register and unregister nodes
--- yaml_config eval: $::yaml_config_with_acl
--- apisix_yaml
routes:
-
uri: /*
upstream:
service_name: http://127.0.0.1:8502/v1/kv/upstreams/webpages/
discovery_type: consul_kv
type: roundrobin
#END
--- config
location /v1/kv {
proxy_pass http://127.0.0.1:8502;
proxy_set_header X-Consul-Token "2b778dd9-f5f1-6f29-b4b4-9a5fa948757a";
}
location /sleep {
content_by_lua_block {
local args = ngx.req.get_uri_args()
local sec = args.sec or "2"
ngx.sleep(tonumber(sec))
ngx.say("ok")
}
}
--- timeout: 6
--- request eval
[
"DELETE /v1/kv/upstreams/webpages/127.0.0.1:30511",
"DELETE /v1/kv/upstreams/webpages/127.0.0.1:30512",
"PUT /v1/kv/upstreams/webpages/127.0.0.1:30513\n" . "{\"weight\": 1, \"max_fails\": 2, \"fail_timeout\": 1}",
"PUT /v1/kv/upstreams/webpages/127.0.0.1:30514\n" . "{\"weight\": 1, \"max_fails\": 2, \"fail_timeout\": 1}",
"GET /sleep",
"GET /hello?random1",
"GET /hello?random2",
"GET /hello?random3",
"GET /hello?random4",
"DELETE /v1/kv/upstreams/webpages/127.0.0.1:30513",
"DELETE /v1/kv/upstreams/webpages/127.0.0.1:30514",
"PUT /v1/kv/upstreams/webpages/127.0.0.1:30511\n" . "{\"weight\": 1, \"max_fails\": 2, \"fail_timeout\": 1}",
"PUT /v1/kv/upstreams/webpages/127.0.0.1:30512\n" . "{\"weight\": 1, \"max_fails\": 2, \"fail_timeout\": 1}",
"GET /sleep?sec=5",
"GET /hello?random1",
"GET /hello?random2",
"GET /hello?random3",
"GET /hello?random4",
]
--- response_body_like eval
[
qr/true/,
qr/true/,
qr/true/,
qr/true/,
qr/ok\n/,
qr/server [3-4]\n/,
qr/server [3-4]\n/,
qr/server [3-4]\n/,
qr/server [3-4]\n/,
qr/true/,
qr/true/,
qr/true/,
qr/true/,
qr/ok\n/,
qr/server [1-2]\n/,
qr/server [1-2]\n/,
qr/server [1-2]\n/,
qr/server [1-2]\n/
]
--- ignore_error_log
Loading