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

Add hostname resolution to ip #17

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .pongo/redis-cluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ networks:
services:
redis-cluster:
image: redis:latest
hostname: pongo-test-network
command: redis-cli -p 7101 --cluster create 172.18.55.1:7101 172.18.55.2:7102 172.18.55.3:7103 --cluster-yes
depends_on:
- redis-1
Expand Down
2 changes: 1 addition & 1 deletion kong-scalable-rate-limiter-1.1.0-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ description = {
}

dependencies = {

"lua-resty-ipmatcher == 0.6.1",
}

build = {
Expand Down
8 changes: 8 additions & 0 deletions kong/plugins/scalable-rate-limiter/policies/connection.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ local redis_cluster = require "resty.rediscluster"
local resty_lock = require "resty.lock"
local worker = ngx.worker
local inspect = require "inspect"
local dns_client = require "kong.resty.dns.client"
local ipmatcher = require "resty.ipmatcher"
local _M = {}

local data = {
conn_pool = nil
}

local function get_redis_config(source_config)
-- If not ipv4 and not ipv6 adress then we need to resolve hostname to ip
if not ipmatcher.parse_ipv4(source_config.redis_host) and not ipmatcher.parse_ipv6(source_config.redis_host) then
dns_client = require("kong.tools.dns")(kong.configuration) -- configure DNS client
source_config.redis_host = dns_client.toip(source_config.redis_host)
end

return {
name = "d11-redis-cluster",
serv_list = {
Expand Down
131 changes: 131 additions & 0 deletions spec/scalable-rate-limiter/01-access_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local cjson = require "cjson"

-- REDIS_HOST and REDIS_PORT taken from .pongo/redis-cluster.yml
local REDIS_HOST = "172.18.55.1"
local REDIS_HOSTNAME = "pongo-test-network"
local REDIS_PORT = 7101
local REDIS_PASSWORD = ""
local REDIS_DATABASE = 1
Expand Down Expand Up @@ -75,6 +76,15 @@ for _, strategy in helpers.each_strategy() do
limit_by = "service",
batch_size = 2,
}

local limit_by_service_config_hostname = {
policy = policy,
minute = per_minute_limit,
redis_host = REDIS_HOSTNAME,
redis_port = REDIS_PORT,
limit_by = "service",
batch_size = 2,
}

local limit_by_header_config = {
policy = policy,
Expand Down Expand Up @@ -206,6 +216,127 @@ for _, strategy in helpers.each_strategy() do
end
end)
end)

describe("global level plugin limit by service using redis hostname", function()
lazy_setup(function()
helpers.kill_all()

bp, db = helpers.get_db_utils(strategy, nil, {"scalable-rate-limiter"})

-- Add request termination plugin at global level to return 200 response for all api calls
bp.plugins:insert {
name = "request-termination",
config = {
status_code = 200,
},
}

-- Global level Rate limiting plugin limit by service
bp.plugins:insert {
name = "scalable-rate-limiter",
config = limit_by_service_config_hostname,
}

local service_1 = bp.services:insert {
protocol = "http",
host = mock_host,
port = mock_port,
name = "service_1",
}

bp.routes:insert {
methods = {"GET"},
protocols = {"http"},
paths = {"/service_1_route_1"},
strip_path = false,
preserve_host = true,
service = service_1,
}

local service_2 = bp.services:insert {
protocol = "http",
host = mock_host,
port = mock_port,
name = "service_2",
}

bp.routes:insert {
methods = {"GET"},
protocols = {"http"},
paths = {"/service_2_route_1"},
strip_path = false,
preserve_host = true,
service = service_2,
}

local service_3 = bp.services:insert {
protocol = "http",
host = mock_host,
port = mock_port,
name = "service_3",
}

bp.routes:insert {
methods = {"GET"},
protocols = {"http"},
paths = {"/service_3_route_1"},
strip_path = false,
preserve_host = true,
service = service_3,
}

bp.routes:insert {
methods = {"GET"},
protocols = {"http"},
paths = {"/service_3_route_2"},
strip_path = false,
preserve_host = true,
service = service_3,
}

assert(helpers.start_kong({
database = strategy,
nginx_conf = "spec/fixtures/custom_nginx.template",
plugins = "bundled,scalable-rate-limiter",
}))
end)

lazy_teardown(function()
helpers.stop_kong()
assert(db:truncate())
end)

it_with_retry("blocks requests over limit on same service", function()
for i = 1, per_minute_limit do
local res = GET("/service_1_route_1", nil, 200)
end

local res = GET("/service_1_route_1", nil, 429)
end)

it_with_retry("blocks requests over limit on same service with multiple routes", function()
for i = 1, per_minute_limit/2 do
local res = GET("/service_3_route_1", nil, 200)
end

for i = 1, per_minute_limit/2 do
local res = GET("/service_3_route_2", nil, 200)
end

local res = GET("/service_3_route_1", nil, 429)
local res = GET("/service_3_route_2", nil, 429)
end)

it_with_retry("allows requests upto limit on each different service", function()
for i = 1, per_minute_limit do
local res = GET("/service_1_route_1", nil, 200)
end

for i = 1, per_minute_limit do
local res = GET("/service_2_route_1", nil, 200)
end
end)
end)

describe("global level plugin limit by header", function()
lazy_setup(function()
Expand Down