Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
cc57776
A little bit of README Driven Development
wfarr Jul 14, 2016
508c71e
Spike out upstream.add_server_to_upstream()
wfarr Jul 14, 2016
63b8d44
minor fixes
wfarr Jul 14, 2016
c2f2863
test things
wfarr Jul 14, 2016
30047af
get_servers is a function in upstream module
wfarr Jul 15, 2016
1874f9f
typo
wfarr Jul 15, 2016
c8011bc
test update
wfarr Jul 15, 2016
4b503ce
typo
wfarr Jul 15, 2016
c17fb18
extra newline
wfarr Jul 15, 2016
e75bf46
correct retval
wfarr Jul 15, 2016
75e87a6
rename add_server_to_upstream to add_peer
wfarr Jul 15, 2016
095f50a
Rename add_peer to add_upstream_peer
wfarr Jul 15, 2016
8007566
suspecting race conditions
wfarr Jul 15, 2016
c201d4f
accurate debug logs
wfarr Jul 15, 2016
6f5c7a7
try %d for bools
wfarr Jul 15, 2016
7eef0bb
ok is probably for chumps
wfarr Jul 15, 2016
4253c5d
ngx_http_lua_upstream_find_server should take ngx_url_t pointer
wfarr Jul 18, 2016
621e9cd
Provide default values for upstream.add_upstream_peer()
wfarr Jul 18, 2016
8713b97
method header fixup
wfarr Jul 18, 2016
47b1c0d
misc
wfarr Jul 18, 2016
7bb736d
update test to check primary peers over servers
wfarr Jul 18, 2016
7b77d6b
misc
wfarr Jul 18, 2016
140bb43
attempt to 0 out u correctly
wfarr Jul 18, 2016
49078fa
Add peers, not servers
wfarr Jul 18, 2016
ac2e4d2
fixup
wfarr Jul 18, 2016
da070e0
should be a ptr
wfarr Jul 18, 2016
66326cf
p is gone
wfarr Jul 18, 2016
3a8db01
remove unused var
wfarr Jul 18, 2016
5d03293
say error in test
wfarr Jul 18, 2016
0d162b8
better wording
wfarr Jul 18, 2016
d825697
lolidunno
wfarr Jul 18, 2016
389ad8c
remove find_server
wfarr Jul 18, 2016
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
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Table of Contents
* [Functions](#functions)
* [get_upstreams](#get_upstreams)
* [get_servers](#get_servers)
* [add_upstream_peer](#add_upstream_peer)
* [remove_server_from_upstream](#remove_server_from_upstream)
* [get_primary_peers](#get_primary_peers)
* [get_backup_peers](#get_backup_peers)
* [set_peer_down](#set_peer_down)
Expand Down Expand Up @@ -126,6 +128,24 @@ The return value is an array-like Lua table. Each table entry is a hash-like Lua

[Back to TOC](#table-of-contents)

add_upstream_peer
-----------
`syntax: ok, err = upstream.add_upstream_peer(upstream_name, ip:port, optional weight = 1, optional max_fails = 1, optional fail_timeout = 10, optional backup = false)`

The return values are a boolean denoting the success of the operation and an associated error if one occurs.

[Back to TOC](#table-of-contents)

remove_server_from_upstream
-----------
`syntax: err = upstream.remove_server_from_upstream(upstream_name, server_name)`

Removes a server from an upstream given the upstream and server names. The server name is expected to match the `name` field on the server in the upstream.

The return value is an error string or nil.

[Back to TOC](#table-of-contents)

get_primary_peers
---------
`syntax: peers = upstream.get_primary_peers(upstream_name)`
Expand Down Expand Up @@ -329,4 +349,3 @@ See Also
* the [lua-resty-upstream-healthcheck](https://github.com/openresty/lua-resty-upstream-healthcheck) library which makes use of the Lua API provided by this module.

[Back to TOC](#table-of-contents)

127 changes: 126 additions & 1 deletion src/ngx_http_lua_upstream_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ static ngx_int_t ngx_http_lua_upstream_init(ngx_conf_t *cf);
static int ngx_http_lua_upstream_create_module(lua_State * L);
static int ngx_http_lua_upstream_get_upstreams(lua_State * L);
static int ngx_http_lua_upstream_get_servers(lua_State * L);
static int ngx_http_lua_upstream_add_upstream_peer(lua_State * L);
static ngx_http_upstream_main_conf_t *
ngx_http_lua_upstream_get_upstream_main_conf(lua_State *L);
static int ngx_http_lua_upstream_get_primary_peers(lua_State * L);
Expand All @@ -37,6 +38,7 @@ static int ngx_http_lua_upstream_set_peer_down(lua_State * L);
static int ngx_http_lua_upstream_current_upstream_name(lua_State *L);



static ngx_http_module_t ngx_http_lua_upstream_ctx = {
NULL, /* preconfiguration */
ngx_http_lua_upstream_init, /* postconfiguration */
Expand Down Expand Up @@ -90,6 +92,9 @@ ngx_http_lua_upstream_create_module(lua_State * L)
lua_pushcfunction(L, ngx_http_lua_upstream_get_servers);
lua_setfield(L, -2, "get_servers");

lua_pushcfunction(L, ngx_http_lua_upstream_add_upstream_peer);
lua_setfield(L, -2, "add_upstream_peer");

lua_pushcfunction(L, ngx_http_lua_upstream_get_primary_peers);
lua_setfield(L, -2, "get_primary_peers");

Expand Down Expand Up @@ -141,6 +146,127 @@ ngx_http_lua_upstream_get_upstreams(lua_State * L)
return 1;
}

static int
ngx_http_lua_upstream_add_upstream_peer(lua_State * L)
{
ngx_http_request_t *r;

ngx_http_upstream_srv_conf_t *us;

ngx_http_upstream_rr_peers_t *peers;
ngx_http_upstream_rr_peer_t *peer, *last;

u_char *url;

ngx_url_t upstream;
ngx_str_t host;
ngx_int_t weight = 1;
ngx_int_t max_fails = 1;
time_t fail_timeout = 10;
ngx_uint_t backup = 0;

if ((lua_gettop(L) < 2) || (lua_gettop(L) > 6)) {
/*
* "upstream name", "host:port", "weight", "max_fails", "fail_timeout", "backup"
*/
return luaL_error(L, "at least 2 arguments are required and as many as 6 are allowed");
}

r = ngx_http_lua_get_request(L);
if (r == NULL) {
lua_pushnil(L);
lua_pushliteral(L, "could not retrieve request\n");
return 2;
}

host.data = (u_char *) luaL_checklstring(L, 1, &host.len);

ngx_memzero(&upstream, sizeof(ngx_url_t));

url = (u_char *) luaL_checklstring(L, 2, &upstream.url.len);
upstream.default_port = 80;

if (lua_gettop(L) >= 3) {
weight = (ngx_int_t) luaL_checkint(L, 3);
}

if (lua_gettop(L) >= 4) {
max_fails = (ngx_int_t) luaL_checkint(L, 4);
}

if (lua_gettop(L) >= 5) {
fail_timeout = (time_t) luaL_checklong(L, 5);
}

if (lua_gettop(L) >= 6) {
backup = lua_toboolean(L, 6);
}

#if (NGX_DEBUG)
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "%s %s params: %s,%s,%d,%d,%d,%d\n", __FILE__, __FUNCTION__, host.data, url, weight, max_fails, fail_timeout, backup);
#endif

us = ngx_http_lua_upstream_find_upstream(L, &host);
if (us == NULL) {
lua_pushnil(L);
lua_pushliteral(L, "upstream not found\n");
return 2;
}

peers = us->peer.data;

for (peer = peers->peer, last = peer; peer; peer = peer->next){
if (len(url) == peer->name.len && ngx_strncmp(url, peer->name.data, peer->name.len) == 0) {
lua_pushnil(L);
lua_pushliteral(L, "server already exists\n");
return 2;
}
last = peer;
}

upstream.url.data = ngx_pcalloc(r->pool, upstream.url.len + 1);
ngx_memcpy(upstream.url.data, url, upstream.url.len);

// validate URL
if (ngx_parse_url(r->pool, &upstream) != NGX_OK) {
if (upstream.err) {
lua_pushnil(L);
lua_pushliteral(L, "url parser error\n");
return 2;
}
}

last->next = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_rr_peer_t));

if (last->next == NULL) {
lua_pushnil(L);
lua_pushliteral(L, "failed to allocate memory\n");
return 2;
}

last->next->name = upstream.url;
last->next->server = upstream.url;
last->next->sockaddr = upstream.addrs[0].sockaddr;
last->next->socklen = upstream.addrs[0].socklen;

last->next->weight = weight;
last->next->effective_weight = weight;
last->next->current_weight = weight;

last->next->max_fails = max_fails;

last->next->fail_timeout = fail_timeout;

last->next->backup = backup;

peers->number++;
peers->total_weight += last->next->weight;
peers->single = (peers->number == 1);
peers->weighted = (peers->total_weight != peers->number);

lua_pushboolean(L, 1);
return 1;
}

static int
ngx_http_lua_upstream_get_servers(lua_State * L)
Expand Down Expand Up @@ -551,7 +677,6 @@ ngx_http_lua_upstream_find_upstream(lua_State *L, ngx_str_t *host)
return NULL;
}


static int
ngx_http_lua_upstream_current_upstream_name(lua_State *L)
{
Expand Down
32 changes: 32 additions & 0 deletions t/sanity.t
Original file line number Diff line number Diff line change
Expand Up @@ -648,3 +648,35 @@ nil
--- no_error_log
[error]



=== TEST 19: add server to pre-defined upstream
--- http_config
upstream foo {
server 127.0.0.2;
}

--- config
location /t {
content_by_lua '
local ljson = require "ljson"
local upstream = require "ngx.upstream"
local ok, err = upstream.add_upstream_peer("foo", "127.0.0.10")
if err then
ngx.say(err)
else
local peers, err = upstream.get_primary_peers("foo")
if not peers then
ngx.say("failed to get primary peers from upstream foo: " .. err)
else
ngx.say(json.encode(peers))
end
end
';
}
--- request
GET /t
--- response_body
[{"addr": "127.0.0.2:80", "weight": 1, "fail_timeout": 10, "name": "127.0.0.2", "max_fails": 1}, {"addr": "127.0.0.10:80", "weight": 1, "fail_timeout": 1, "name": "127.0.0.10", "max_fails": 1}]
--- no_error_log
[error]