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 16 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, weight, max_fails, fail_timeout)`

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)

119 changes: 119 additions & 0 deletions 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 @@ -31,12 +32,15 @@ static int ngx_http_lua_get_peer(lua_State *L,
ngx_http_upstream_rr_peer_t *peer, ngx_uint_t id);
static ngx_http_upstream_srv_conf_t *
ngx_http_lua_upstream_find_upstream(lua_State *L, ngx_str_t *host);
static ngx_http_upstream_server_t*
ngx_http_lua_upstream_find_server(ngx_http_upstream_srv_conf_t * us, ngx_url_t u);
static ngx_http_upstream_rr_peer_t *
ngx_http_lua_upstream_lookup_peer(lua_State *L);
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 +94,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 +148,92 @@ ngx_http_lua_upstream_get_upstreams(lua_State * L)
return 1;
}

static int
ngx_http_lua_upstream_add_upstream_peer(lua_State * L)
{
ngx_str_t host;
ngx_http_upstream_server_t *us;
ngx_http_upstream_srv_conf_t *uscf;
ngx_url_t u;
ngx_http_request_t *r;
ngx_int_t weight, max_fails;
ngx_uint_t backup;
time_t fail_timeout;
u_char *p;

if (lua_gettop(L) != 6) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be some sane defaults here.

/*
* "upstream name", "host:port", "weight", "max_fails", "fail_timeout", "backup"
*/
return luaL_error(L, "exactly 6 arguments expected");
}

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

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

ngx_memzero(&u, sizeof(ngx_url_t));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can declare u like so: ngx_url_t u = { 0 }; to automatically zero it.

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

weight = (ngx_int_t) luaL_checkint(L, 3);
max_fails = (ngx_int_t) luaL_checkint(L, 4);
fail_timeout = (time_t) luaL_checklong(L, 5);
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, p, weight, max_fails, fail_timeout, backup);
#endif

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

u.url.data = ngx_pcalloc(uscf->servers->pool, u.url.len+1);
ngx_memcpy(u.url.data, p, u.url.len);

if (ngx_http_lua_upstream_find_server(uscf, u) != NULL) {
lua_pushnil(L);
lua_pushliteral(L, "server already exists\n");
return 2;
} else {
// validate URL
if (ngx_parse_url(uscf->servers->pool, &u) != NGX_OK) {
if (u.err) {
lua_pushnil(L);
lua_pushliteral(L, "url parser error\n");
return 2;
}
}

us = ngx_array_push(uscf->servers);
if (us == NULL) {
lua_pushnil(L);
lua_pushliteral(L, "could not append server to upstream\n");
return 2;
}

ngx_memzero(us, sizeof(ngx_http_upstream_server_t));

us->name = u.url;
us->addrs = u.addrs;
us->naddrs = u.naddrs;
us->weight = weight;
us->max_fails = max_fails;
us->fail_timeout = fail_timeout;
us->backup = backup;
}

lua_pushboolean(L, 1);
return 1;
}

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

static ngx_http_upstream_server_t*
ngx_http_lua_upstream_find_server(ngx_http_upstream_srv_conf_t * us, ngx_url_t u)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The u parameters should be a pointer.

{
ngx_uint_t i, j;
size_t len;
ngx_http_upstream_server_t *server = NULL;

if (us->servers == NULL || us->servers->nelts == 0) {
return NULL;
}

server = us->servers->elts;

for (i = 0; i < us->servers->nelts; ++i) {
for (j = 0; j < server[i].naddrs; ++j) {
len = server[i].addrs[j].name.len;

if (len == u.url.len
&& ngx_memcmp(u.url.data, server[i].addrs[j].name.data, u.url.len) == 0) {
return &server[i];
}
}
}

return NULL;
}

static int
ngx_http_lua_upstream_current_upstream_name(lua_State *L)
Expand Down
52 changes: 52 additions & 0 deletions t/sanity.t
Original file line number Diff line number Diff line change
Expand Up @@ -648,3 +648,55 @@ 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 upstream = require "ngx.upstream"
local ok, err = upstream.add_upstream_peer("foo", "127.0.0.10", 1, 1, 1, false)
if err then
ngx.say(err)
else
local srvs, err = upstream.get_servers("foo")
if not srvs then
ngx.say("failed to get servers in upstream foo")
else
ngx.say("upstream foo:")
for _, srv in ipairs(srvs) do
local first = true
for k, v in pairs(srv) do
if first then
first = false
ngx.print(" ")
else
ngx.print(", ")
end
if type(v) == "table" then
ngx.print(k, " = {", concat(v, ", "), "}")
else
ngx.print(k, " = ", v)
end
end
ngx.print("\\n")
end
end
ngx.say("done")
end
';
}
--- request
GET /t
--- response_body
upstream foo:
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
done
--- no_error_log
[error]