diff --git a/CHANGELOG.md b/CHANGELOG.md index ce0b32ea9..7f17da7a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Support for loading configration from custom URL [PR #323](https://github.com/3scale/apicast/pull/323) +### Changed + +- Use `RESOLVER` before falling back to `resolv.conf` [PR #324](https://github.com/3scale/apicast/pull/324) + ## [3.0.0-beta3] - 2017-03-20 ### Changed diff --git a/apicast/src/resty/resolver.lua b/apicast/src/resty/resolver.lua index f84b61f2b..a83bc6c92 100644 --- a/apicast/src/resty/resolver.lua +++ b/apicast/src/resty/resolver.lua @@ -49,6 +49,18 @@ local function read_resolv_conf(path) return output or "", err end +local nameserver = { + mt = { + __tostring = function(t) + return concat(t, ':') + end + } +} + +function nameserver.new(host, port) + return setmetatable({ host, port or default_resolver_port }, nameserver.mt) +end + function _M.parse_nameservers(path) local resolv_conf, err = read_resolv_conf(path) @@ -71,26 +83,27 @@ function _M.parse_nameservers(path) if resolver then local m = re.split(resolver, ':', 'oj') - insert(nameservers, { m[1] , m[2] or default_resolver_port }) - return nameservers + insert(nameservers, nameserver.new(m[1], m[2])) + -- we are going to use all resolvers, because we can't trust dnsmasq + -- see https://github.com/3scale/apicast/issues/321 for more details end - for nameserver in gmatch(resolv_conf, 'nameserver%s+([^%s]+)') do + for server in gmatch(resolv_conf, 'nameserver%s+([^%s]+)') do -- TODO: implement port matching based on https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=549190 - if nameserver ~= resolver then - insert(nameservers, { nameserver, default_resolver_port } ) + if server ~= resolver then + insert(nameservers, nameserver.new(server)) end end return nameservers end -function _M.init_nameservers() - local nameservers = _M.parse_nameservers() or {} +function _M.init_nameservers(path) + local nameservers = _M.parse_nameservers(path) or {} local search = nameservers.search or {} for i=1, #nameservers do - ngx.log(ngx.INFO, 'adding ', nameservers[i][1],':', nameservers[i][2], ' as default nameserver') + ngx.log(ngx.INFO, 'adding ', nameservers[i], ' as default nameserver') insert(_M._nameservers, nameservers[i]) end @@ -114,8 +127,8 @@ function _M.nameservers() return _M._nameservers end -function _M.init() - _M.init_nameservers() +function _M.init(path) + _M.init_nameservers(path) end function _M.new(dns, opts) diff --git a/t/014-resolver.t b/t/014-resolver.t new file mode 100644 index 000000000..2c5094783 --- /dev/null +++ b/t/014-resolver.t @@ -0,0 +1,45 @@ +use Test::Nginx::Socket 'no_plan'; +use Cwd qw(cwd); + +my $pwd = cwd(); +my $apicast = $ENV{TEST_NGINX_APICAST_PATH} || "$pwd/apicast"; + +$ENV{TEST_NGINX_LUA_PATH} = "$apicast/src/?.lua;;"; +$ENV{TEST_NGINX_HTTP_CONFIG} = "$apicast/http.d/*.conf"; +$ENV{TEST_NGINX_APICAST_PATH} = $apicast; +$ENV{RESOLVER} = '127.0.1.1:5353'; + + +env_to_nginx( + 'RESOLVER' +); +master_on(); +log_level('warn'); +repeat_each(2); +no_root_location(); +run_tests(); + +__DATA__ + +=== TEST 1: uses all resolvers +both RESOLVER env variable and resolvers in resolv.conf should be used +--- http_config + lua_package_path "$TEST_NGINX_LUA_PATH"; + init_by_lua_block { + require('resty.resolver').init(ngx.config.prefix() .. 'html/resolv.conf') + } +--- config + location = /t { + content_by_lua_block { + local nameservers = require('resty.resolver').nameservers() + ngx.say('nameservers: ', #nameservers, ' ', nameservers[1], ' ', nameservers[2], ' ', nameservers[3]) + } + } +--- request +GET /t +--- response_body +nameservers: 3 127.0.1.15353 1.2.3.453 4.5.6.753 +--- user_files +>>> resolv.conf +nameserver 1.2.3.4 +nameserver 4.5.6.7