You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2022/11/22 06:29:56 UTC
[apisix] branch master updated: feat: add method that parse ip from /etc/hosts in high priority (#8270)
This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 6dbf9761e feat: add method that parse ip from /etc/hosts in high priority (#8270)
6dbf9761e is described below
commit 6dbf9761e5d8851fef8b2fd8262d6d7cf3000f78
Author: MaChao <10...@qq.com>
AuthorDate: Tue Nov 22 14:29:49 2022 +0800
feat: add method that parse ip from /etc/hosts in high priority (#8270)
Co-authored-by: MaChao <ch...@transwarp.io>
Fixes https://github.com/apache/apisix/issues/5233
---
apisix/core/resolver.lua | 39 +++++++++++-
t/core/resolver.t | 151 +++++++++++++++++++++++++++++++++++++++++++++
t/node/upstream-node-dns.t | 52 ++++++++--------
3 files changed, 213 insertions(+), 29 deletions(-)
diff --git a/apisix/core/resolver.lua b/apisix/core/resolver.lua
index 056fbf806..3568a9762 100644
--- a/apisix/core/resolver.lua
+++ b/apisix/core/resolver.lua
@@ -19,15 +19,32 @@
--
-- @module core.resolver
-local json = require("apisix.core.json")
-local log = require("apisix.core.log")
-local utils = require("apisix.core.utils")
+local json = require("apisix.core.json")
+local log = require("apisix.core.log")
+local utils = require("apisix.core.utils")
+local dns_utils = require("resty.dns.utils")
+local config_local = require("apisix.core.config_local")
+
+
+local HOSTS_IP_MATCH_CACHE = {}
local _M = {}
+local function init_hosts_ip()
+ local hosts, err = dns_utils.parseHosts()
+ if not hosts then
+ return hosts, err
+ end
+ HOSTS_IP_MATCH_CACHE = hosts
+end
+
+
function _M.init_resolver(args)
+ -- initialize /etc/hosts
+ init_hosts_ip()
+
local dns_resolver = args and args["dns_resolver"]
utils.set_resolver(dns_resolver)
log.info("dns resolver ", json.delay_encode(dns_resolver, true))
@@ -42,6 +59,22 @@ end
-- @usage
-- local ip, err = core.resolver.parse_domain("apache.org") -- "198.18.10.114"
function _M.parse_domain(host)
+ local rev = HOSTS_IP_MATCH_CACHE[host]
+ local enable_ipv6 = config_local.local_conf().apisix.enable_ipv6
+ if rev then
+ -- use ipv4 in high priority
+ local ip = rev["ipv4"]
+ if enable_ipv6 and not ip then
+ ip = rev["ipv6"]
+ end
+ if ip then
+ -- meet test case
+ log.info("dns resolve ", host, ", result: ", json.delay_encode(ip))
+ log.info("dns resolver domain: ", host, " to ", ip)
+ return ip
+ end
+ end
+
local ip_info, err = utils.dns_parse(host)
if not ip_info then
log.error("failed to parse domain: ", host, ", error: ",err)
diff --git a/t/core/resolver.t b/t/core/resolver.t
new file mode 100644
index 000000000..06d2470b3
--- /dev/null
+++ b/t/core/resolver.t
@@ -0,0 +1,151 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+log_level("info");
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ if (!$block->request) {
+ $block->set_value("request", "GET /t");
+ }
+
+ if (!$block->no_error_log && !$block->error_log) {
+ $block->set_value("no_error_log", "[error]");
+ }
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: resolve host from /etc/hosts
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local resolver = require("apisix.core.resolver")
+ local domain = "localhost"
+ local ip_info, err = resolver.parse_domain(domain)
+ if not ip_info then
+ core.log.error("failed to parse domain: ", domain, ", error: ",err)
+ return
+ end
+ ngx.say("ip_info: ", require("toolkit.json").encode(ip_info))
+ }
+ }
+--- response_body
+ip_info: "127.0.0.1"
+
+
+
+=== TEST 2: resolve host from dns
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local resolver = require("apisix.core.resolver")
+ local domain = "apisix.apache.org"
+ resolver.parse_domain = function(domain) -- mock: resolver parser
+
+ if domain == "apisix.apache.org" then
+ return {address = "127.0.0.2" }
+ end
+ error("unknown domain: " .. domain)
+ end
+ local ip_info, err = resolver.parse_domain(domain)
+ if not ip_info then
+ core.log.error("failed to parse domain: ", domain, ", error: ",err)
+ return
+ end
+ ngx.say("ip_info: ", require("toolkit.json").encode(ip_info))
+ }
+ }
+--- response_body
+ip_info: {"address":"127.0.0.2"}
+
+
+
+=== TEST 3: there is no mapping in /etc/hosts and dns
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local resolver = require("apisix.core.resolver")
+ local domain = "abc1.test"
+ resolver.parse_domain(domain)
+ }
+ }
+--- error_log
+failed to parse domain
+
+
+
+=== TEST 4: test dns config with ipv6 enable
+--- yaml_config
+apisix:
+ enable_ipv6: true
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local resolver = require("apisix.core.resolver")
+ local domain = "localhost6"
+ resolver.parse_domain = function(domain) -- mock: resolver parse_domain
+ if domain == "localhost6" then
+ return {address = "::1" }
+ end
+ error("unknown domain: " .. domain)
+
+ end
+ local ip_info, err = resolver.parse_domain(domain)
+ if not ip_info then
+ core.log.error("failed to parse domain: ", domain, ", error: ",err)
+ return
+ end
+ ngx.say("ip_info: ", require("toolkit.json").encode(ip_info))
+ }
+ }
+--- response_body
+ip_info: {"address":"::1"}
+
+
+
+=== TEST 5: test dns config with ipv6 disable
+--- yaml_config
+apisix:
+ enable_ipv6: false
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local resolver = require("apisix.core.resolver")
+ local domain = "localhost6"
+ local ip_info, err = resolver.parse_domain(domain)
+ if not ip_info then
+ core.log.error("failed to parse domain: ", domain, ", error: ",err)
+ return
+ end
+ ngx.say("ip_info: ", require("toolkit.json").encode(ip_info))
+ }
+ }
+--- error_log
+failed to parse domain
diff --git a/t/node/upstream-node-dns.t b/t/node/upstream-node-dns.t
index f6f8560f1..b8dbb0bce 100644
--- a/t/node/upstream-node-dns.t
+++ b/t/node/upstream-node-dns.t
@@ -35,7 +35,7 @@ __DATA__
[[{
"upstream": {
"nodes": {
- "test.com:1980": 1
+ "test1.com:1980": 1
},
"type": "roundrobin"
},
@@ -65,7 +65,7 @@ passed
local utils = require("apisix.core.utils")
utils.dns_parse = function (domain) -- mock: DNS parser
- if domain == "test.com" then
+ if domain == "test1.com" then
return {address = "127.0.0.2"}
end
@@ -90,7 +90,7 @@ hello world
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
- if domain == "test.com" then
+ if domain == "test1.com" then
return {address = "127.0.0." .. count}
end
@@ -109,10 +109,10 @@ location /t {
--- request
GET /t
--- grep_error_log eval
-qr/dns resolver domain: test.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
+qr/dns resolver domain: test1.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
--- grep_error_log_out
call /hello
-dns resolver domain: test.com to 127.0.0.1
+dns resolver domain: test1.com to 127.0.0.1
proxy request to 127.0.0.1:1980
@@ -127,7 +127,7 @@ proxy request to 127.0.0.1:1980
[[{
"upstream": {
"nodes": {
- "test.com:1980": 1,
+ "test1.com:1980": 1,
"test2.com:1980": 1
},
"type": "roundrobin"
@@ -158,7 +158,7 @@ passed
local utils = require("apisix.core.utils")
utils.dns_parse = function (domain) -- mock: DNS parser
- if domain == "test.com" or domain == "test2.com" then
+ if domain == "test1.com" or domain == "test2.com" then
return {address = "127.0.0.2"}
end
@@ -183,7 +183,7 @@ hello world
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
- if domain == "test.com" or domain == "test2.com" then
+ if domain == "test1.com" or domain == "test2.com" then
return {address = "127.0.0." .. count}
end
@@ -206,10 +206,10 @@ GET /t
qr/dns resolver domain: \w+.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
--- grep_error_log_out eval
qr/call \/hello(
-dns resolver domain: test.com to 127.0.0.1
+dns resolver domain: test1.com to 127.0.0.1
dns resolver domain: test2.com to 127.0.0.2|
dns resolver domain: test2.com to 127.0.0.1
-dns resolver domain: test.com to 127.0.0.2)
+dns resolver domain: test1.com to 127.0.0.2)
proxy request to 127.0.0.[12]:1980
/
@@ -224,7 +224,7 @@ proxy request to 127.0.0.[12]:1980
ngx.HTTP_PUT,
[[{
"nodes": {
- "test.com:1980": 1
+ "test1.com:1980": 1
},
"type": "roundrobin",
"desc": "new upstream"
@@ -282,7 +282,7 @@ passed
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
- if domain == "test.com" then
+ if domain == "test1.com" then
return {address = "127.0.0." .. count}
end
@@ -301,10 +301,10 @@ location /t {
--- request
GET /t
--- grep_error_log eval
-qr/dns resolver domain: test.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
+qr/dns resolver domain: test1.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
--- grep_error_log_out
call /hello
-dns resolver domain: test.com to 127.0.0.1
+dns resolver domain: test1.com to 127.0.0.1
proxy request to 127.0.0.1:1980
@@ -318,7 +318,7 @@ proxy request to 127.0.0.1:1980
ngx.HTTP_PUT,
[[{
"nodes": {
- "test.com:1980": 1,
+ "test1.com:1980": 1,
"test2.com:1980": 1
},
"type": "roundrobin",
@@ -351,7 +351,7 @@ passed
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
- if domain == "test.com" or domain == "test2.com" then
+ if domain == "test1.com" or domain == "test2.com" then
return {address = "127.0.0." .. count}
end
@@ -373,10 +373,10 @@ GET /t
qr/dns resolver domain: \w+.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
--- grep_error_log_out eval
qr/call \/hello(
-dns resolver domain: test.com to 127.0.0.1
+dns resolver domain: test1.com to 127.0.0.1
dns resolver domain: test2.com to 127.0.0.2|
dns resolver domain: test2.com to 127.0.0.1
-dns resolver domain: test.com to 127.0.0.2)
+dns resolver domain: test1.com to 127.0.0.2)
proxy request to 127.0.0.[12]:1980
/
@@ -392,7 +392,7 @@ proxy request to 127.0.0.[12]:1980
local utils = require("apisix.core.utils")
local count = 1
utils.dns_parse = function (domain) -- mock: DNS parser
- if domain == "test.com" or domain == "test2.com" then
+ if domain == "test1.com" or domain == "test2.com" then
return {address = "127.0.0.1"}
end
@@ -414,10 +414,10 @@ GET /t
qr/dns resolver domain: \w+.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
--- grep_error_log_out eval
qr/call \/hello(
-dns resolver domain: test.com to 127.0.0.1
+dns resolver domain: test1.com to 127.0.0.1
dns resolver domain: test2.com to 127.0.0.1|
dns resolver domain: test2.com to 127.0.0.1
-dns resolver domain: test.com to 127.0.0.1)
+dns resolver domain: test1.com to 127.0.0.1)
proxy request to 127.0.0.1:1980
/
@@ -432,7 +432,7 @@ proxy request to 127.0.0.1:1980
ngx.HTTP_PUT,
[[{
"nodes": {
- "test.com:1980": 1,
+ "test1.com:1980": 1,
"127.0.0.5:1981": 1
},
"type": "roundrobin",
@@ -464,7 +464,7 @@ passed
local count = 0
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
- if domain == "test.com" or domain == "test2.com" then
+ if domain == "test1.com" or domain == "test2.com" then
return {address = "127.0.0." .. count}
end
@@ -486,7 +486,7 @@ GET /t
qr/dns resolver domain: \w+.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:198\d/
--- grep_error_log_out eval
qr/call \/hello
-dns resolver domain: test.com to 127.0.0.1
+dns resolver domain: test1.com to 127.0.0.1
proxy request to 127.0.0.(1:1980|5:1981)
/
@@ -502,7 +502,7 @@ proxy request to 127.0.0.(1:1980|5:1981)
[[{
"upstream": {
"nodes": {
- "test.com:1980": 1
+ "test1.com:1980": 1
},
"type": "roundrobin"
},
@@ -534,7 +534,7 @@ passed
local count = 0
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
- if domain == "test.com" then
+ if domain == "test1.com" then
return {address = "127.0.0." .. count}
end