This is an automated email from the ASF dual-hosted git repository. membphis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-apisix.git
The following commit(s) were added to refs/heads/master by this push: new 7baa0ab feature: if the `dns_resolver` is not set in the file `conf/config.yaml`, use the resolver in local DNS. (#1217) 7baa0ab is described below commit 7baa0abd44380d957f4d27cffc9d57f65a488420 Author: qiujiayu <153163...@qq.com> AuthorDate: Thu Mar 26 09:48:18 2020 +0800 feature: if the `dns_resolver` is not set in the file `conf/config.yaml`, use the resolver in local DNS. (#1217) Fix #1164 --- .travis/apisix_cli_test.sh | 20 ++++++++ bin/apisix | 64 ++++++++++++++++++------- conf/config.yaml | 4 +- lua/apisix.lua | 20 ++++---- t/APISIX.pm | 39 ++++++++++++++- t/node/route-domain-with-local-dns.t | 93 ++++++++++++++++++++++++++++++++++++ 6 files changed, 209 insertions(+), 31 deletions(-) diff --git a/.travis/apisix_cli_test.sh b/.travis/apisix_cli_test.sh index 7ef2089..d67c7f8 100755 --- a/.travis/apisix_cli_test.sh +++ b/.travis/apisix_cli_test.sh @@ -52,3 +52,23 @@ if [ ! $? -eq 0 ]; then fi echo "passed: change default ssl port" + +# check nameserver imported + +sed -i '/dns_resolver:/,+4s/^/#/' conf/config.yaml + +make init + +i=`grep -E '^nameserver[[:space:]]+(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4]0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])[[:space:]]?$' /etc/resolv.conf | awk '{print $2}'` +for ip in $i +do + echo $ip + grep $ip conf/nginx.conf > /dev/null + if [ ! $? -eq 0 ]; then + echo "failed: system DNS "$ip" unimported" + exit 1 + fi +done + +sed -i '/dns_resolver:/,+4s/^#//' conf/config.yaml +echo "passed: system nameserver imported" diff --git a/bin/apisix b/bin/apisix index 2f27970..f72c89a 100755 --- a/bin/apisix +++ b/bin/apisix @@ -22,7 +22,10 @@ local function trim(s) end local function excute_cmd(cmd) - local t = io.popen(cmd) + local t, err = io.popen(cmd) + if not t then + return nil, "failed to execute command: " .. cmd .. ", error info:" .. err + end local data = t:read("*all") t:close() return data @@ -119,6 +122,9 @@ stream { .. [=[{*lua_cpath*};"; lua_socket_log_errors off; + resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} valid={*dns_resolver_valid*}; + resolver_timeout {*resolver_timeout*}; + upstream apisix_backend { server 127.0.0.1:80; balancer_by_lua_block { @@ -207,8 +213,8 @@ http { lua_socket_log_errors off; - resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} valid={*dns_resolver_valid*} ipv6=off; - resolver_timeout 5; + resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} valid={*dns_resolver_valid*}; + resolver_timeout {*resolver_timeout*}; lua_http10_buffering off; @@ -260,7 +266,12 @@ http { init_by_lua_block { require "resty.core" apisix = require("apisix") - apisix.http_init() + + local dns_resolver = { {% for _, dns_addr in ipairs(dns_resolver or {}) do %} "{*dns_addr*}", {% end %} } + local args = { + dns_resolver = dns_resolver, + } + apisix.http_init(args) } init_worker_by_lua_block { @@ -497,9 +508,9 @@ http { ]=] local function write_file(file_path, data) - local file = io.open(file_path, "w+") + local file, err = io.open(file_path, "w+") if not file then - return false, "failed to open file: " .. file_path + return false, "failed to open file: " .. file_path .. ", error info:" .. err end file:write(data) @@ -508,9 +519,9 @@ local function write_file(file_path, data) end local function read_file(file_path) - local file = io.open(file_path, "rb") + local file, err = io.open(file_path, "rb") if not file then - return false, "failed to open file: " .. file_path + return false, "failed to open file: " .. file_path .. ", error info:" .. err end local data = file:read("*all") @@ -518,12 +529,6 @@ local function read_file(file_path) return data end -local function exec(command) - local t= io.popen(command) - local res = t:read("*all") - t:close() - return trim(res) -end local function read_yaml_conf() local profile = require("apisix.core.profile") @@ -593,6 +598,24 @@ local function check_or_version(cur_ver_s, need_ver_s) return true end + +local function local_dns_resolver(file_path) + local file, err = io.open(file_path, "rb") + if not file then + return false, "failed to open file: " .. file_path .. ", error info:" .. err + end + local dns_addrs = {} + for line in file:lines() do + local addr, n = line:gsub("^nameserver%s+(%d+%.%d+%.%d+%.%d+)%s*$", "%1") + if n == 1 then + table.insert(dns_addrs, addr) + end + end + file:close() + return dns_addrs +end + + local _M = {version = 0.1} function _M.help() @@ -636,7 +659,7 @@ local function init() local sys_conf = { lua_path = pkg_path_org, lua_cpath = pkg_cpath_org, - os_name = exec("uname"), + os_name = excute_cmd("uname"), apisix_lua_home = apisix_home, with_module_status = with_module_status, error_log = {level = "warn"}, @@ -676,6 +699,15 @@ local function init() sys_conf["worker_processes"] = "auto" end + local dns_resolver = sys_conf["dns_resolver"] + if not dns_resolver or #dns_resolver == 0 then + local dns_addrs, err = local_dns_resolver("/etc/resolv.conf") + if not dns_addrs then + error("failed to import local DNS: " .. err) + end + sys_conf["dns_resolver"] = dns_addrs + end + local conf_render = template.compile(ngx_tpl) local ngxconf = conf_render(sys_conf) @@ -742,7 +774,7 @@ local function init_etcd(show_output) .. "--connect-timeout " .. timeout .. " --max-time " .. timeout * 2 .. " --retry 1 2>&1" - local res = exec(cmd) + local res = excute_cmd(cmd) if not res:find("index", 1, true) and not res:find("createdIndex", 1, true) then is_success = false diff --git a/conf/config.yaml b/conf/config.yaml index f02134b..e76a3aa 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -80,13 +80,13 @@ apisix: # udp: # UDP proxy port list # - 9200 # - 9211 - dns_resolver: # default DNS resolver, with disable IPv6 and enable local DNS + dns_resolver: # If not set, read from `/etc/resolv.conf` - 114.114.114.114 - 223.5.5.5 - 1.1.1.1 - 8.8.8.8 dns_resolver_valid: 30 # valid time for dns result 30 seconds - + resolver_timeout: 5 # resolver timeout ssl: enable: true enable_http2: true diff --git a/lua/apisix.lua b/lua/apisix.lua index 2bd2184..3a08157 100644 --- a/lua/apisix.lua +++ b/lua/apisix.lua @@ -32,14 +32,20 @@ local pairs = pairs local tostring = tostring local load_balancer - +local dns_resolver local parsed_domain +local function parse_args(args) + dns_resolver = args and args["dns_resolver"] + core.log.info("dns resolver", core.json.delay_encode(dns_resolver, true)) +end + + local _M = {version = 0.3} -function _M.http_init() +function _M.http_init(args) require("resty.core") if require("ffi").os == "Linux" then @@ -57,7 +63,7 @@ function _M.http_init() seed = ngx.now() * 1000 + ngx.worker.pid() end math.randomseed(seed) - + parse_args(args) core.id.init() end @@ -171,11 +177,7 @@ end local function parse_domain_in_up(up, ver) - local local_conf = core.config.local_conf() - local dns_resolver = local_conf and local_conf.apisix and - local_conf.apisix.dns_resolver local new_nodes = core.table.new(0, 8) - for addr, weight in pairs(up.value.nodes) do local host, port = core.utils.parse_addr(addr) if not ipmatcher.parse_ipv4(host) and @@ -209,11 +211,7 @@ end local function parse_domain_in_route(route, ver) - local local_conf = core.config.local_conf() - local dns_resolver = local_conf and local_conf.apisix and - local_conf.apisix.dns_resolver local new_nodes = core.table.new(0, 8) - for addr, weight in pairs(route.value.upstream.nodes) do local host, port = core.utils.parse_addr(addr) if not ipmatcher.parse_ipv4(host) and diff --git a/t/APISIX.pm b/t/APISIX.pm index af7f2b0..3347766 100644 --- a/t/APISIX.pm +++ b/t/APISIX.pm @@ -37,6 +37,38 @@ sub read_file($) { $data; } +sub local_dns_resolver() { + open my $in, "/etc/resolv.conf" or die "cannot open /etc/resolv.conf"; + my @lines = <$in>; + my @dns_addrs = (); + foreach my $line (@lines){ + $line =~ m/^nameserver\s+(\d+[.]\d+[.]\d+[.]\d+)\s*$/; + if ($1) { + push(@dns_addrs, $1); + } + } + close($in); + return @dns_addrs +} + + +my $dns_addrs_str = ""; +my $dns_addrs_tbl_str = ""; +my $enable_local_dns = $ENV{"ENABLE_LOCAL_DNS"}; +if ($enable_local_dns) { + my @dns_addrs = local_dns_resolver(); + $dns_addrs_tbl_str = "{"; + foreach my $addr (@dns_addrs){ + $dns_addrs_str = "$dns_addrs_str $addr"; + $dns_addrs_tbl_str = "$dns_addrs_tbl_str\"$addr\", "; + } + $dns_addrs_tbl_str = "$dns_addrs_tbl_str}"; +} else { + $dns_addrs_str = "8.8.8.8 114.114.114.114"; + $dns_addrs_tbl_str = "{\"8.8.8.8\", \"114.114.114.114\"}"; +} + + my $yaml_config = read_file("conf/config.yaml"); my $ssl_crt = read_file("conf/cert/apisix.crt"); my $ssl_key = read_file("conf/cert/apisix.key"); @@ -146,7 +178,10 @@ _EOC_ require "resty.core" apisix = require("apisix") - apisix.http_init() + local args = { + dns_resolver = $dns_addrs_tbl_str, + } + apisix.http_init(args) _EOC_ my $http_config = $block->http_config // ''; @@ -161,7 +196,7 @@ _EOC_ lua_shared_dict upstream-healthcheck 32m; lua_shared_dict worker-events 10m; - resolver 8.8.8.8 114.114.114.114 ipv6=off; + resolver $dns_addrs_str; resolver_timeout 5; underscores_in_headers on; diff --git a/t/node/route-domain-with-local-dns.t b/t/node/route-domain-with-local-dns.t new file mode 100644 index 0000000..d68acd9 --- /dev/null +++ b/t/node/route-domain-with-local-dns.t @@ -0,0 +1,93 @@ +# +# 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. +# + +BEGIN { + # for test + $ENV{ENABLE_LOCAL_DNS} = "true"; +} + +use t::APISIX 'no_plan'; + +repeat_each(1); +log_level('info'); +worker_connections(256); +no_root_location(); +no_shuffle(); + +run_tests(); + +__DATA__ + +=== TEST 1: set route(id: 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "upstream": { + "nodes": { + "127.0.0.1:1980": 1, + "baidu.com:80": 0 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- error_log eval +/.*parse_args(): dns resolver\[.+\]/ +--- no_error_log +[error] + + + + +=== TEST 2: /not_found +--- request +GET /not_found +--- error_code: 404 +--- response_body +{"error_msg":"failed to match any routes"} +--- error_log eval +/.*parse_args(): dns resolver\[.+\]/ +--- no_error_log +[error] + + + +=== TEST 3: hit route +--- request +GET /hello +--- response_body +hello world +--- no_error_log +[error] +--- error_log eval +qr/dns resolver domain: baidu.com to \d+.\d+.\d+.\d+/