diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst index 55d140a5a9..07ade69152 100644 --- a/doc/lua-api/index.rst +++ b/doc/lua-api/index.rst @@ -592,6 +592,11 @@ Proxy class This class provides a way for manipulating proxy and retrieving information like statistics. +.. js:attribute:: Proxy.servers + + Contain an array with the attached servers. Each server entry is an object of + type :ref:`server_class`. + .. js:function:: Proxy.pause(px) Pause the proxy. See the management socket documentation for more information. @@ -647,6 +652,165 @@ Proxy class proxy. :returns: a key/value array containing stats +.. _server_class: + +Server class +============ + +.. js:function:: Server.is_draining(sv) + + Return true if the server is currently draining stiky connections. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + :returns: a boolean + +.. js:function:: Server.set_weight(sv, weight) + + Dynamically change the weight of the serveur. See the management socket + documentation for more information about the format of the string. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + :param string weight: A string describing the server weight. + +.. js:function:: Server.get_weight(sv) + + This function returns an integer representing the serveur weight. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + :returns: an integer. + +.. js:function:: Server.set_addr(sv, addr) + + Dynamically change the address of the serveur. See the management socket + documentation for more information about the format of the string. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + :param string weight: A string describing the server address. + +.. js:function:: Server.get_addr(sv) + + Returns a string describing the address of the serveur. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + :returns: A string + +.. js:function:: Server.get_stats(sv) + + Returns server statistics. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + :returns: a key/value array containing stats + +.. js:function:: Server.shut_sess(sv) + + Shutdown all the sessions attached to the server. See the management socket + documentation for more information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.set_drain(sv) + + Drain sticky sessions. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.set_maint(sv) + + Set maintenance mode. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.set_ready(sv) + + Set normal mode. See the management socket documentation for more information + about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.check_enable(sv) + + Enable health checks. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.check_disable(sv) + + Disable health checks. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.check_force_up(sv) + + Force health-check up. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.check_force_nolb(sv) + + Force health-check nolb mode. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.check_force_down(sv) + + Force health-check down. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.agent_enable(sv) + + Enable agent check. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.agent_disable(sv) + + Disable agent check. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.agent_force_up(sv) + + Force agent check up. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + +.. js:function:: Server.agent_force_down(sv) + + Force agent check down. See the management socket documentation for more + information about this function. + + :param class_server sv: A :ref:`server_class` which indicates the manipulated + server. + .. _concat_class: Concat class diff --git a/include/types/hlua.h b/include/types/hlua.h index 17cf141b81..afe870a371 100644 --- a/include/types/hlua.h +++ b/include/types/hlua.h @@ -20,6 +20,7 @@ #define CLASS_APPLET_TCP "AppletTCP" #define CLASS_APPLET_HTTP "AppletHTTP" #define CLASS_PROXY "Proxy" +#define CLASS_SERVER "Server" struct stream; diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c index c8b640f228..0e5a33d37e 100644 --- a/src/hlua_fcn.c +++ b/src/hlua_fcn.c @@ -32,6 +32,7 @@ /* Contains the class reference of the concat object. */ static int class_concat_ref; static int class_proxy_ref; +static int class_server_ref; #define STATS_LEN (MAX((int)ST_F_TOTAL_FIELDS, (int)INF_TOTAL_FIELDS)) @@ -434,8 +435,285 @@ static int hlua_concat_init(lua_State *L) return 1; } +int hlua_fcn_new_server(lua_State *L, struct server *srv) +{ + lua_newtable(L); + + /* Pop a class sesison metatable and affect it to the userdata. */ + lua_rawgeti(L, LUA_REGISTRYINDEX, class_server_ref); + lua_setmetatable(L, -2); + + lua_pushlightuserdata(L, srv); + lua_rawseti(L, -2, 0); + return 1; +} + +static struct server *hlua_check_server(lua_State *L, int ud) +{ + return (struct server *)(hlua_checkudata(L, ud, class_server_ref)); +} + +int hlua_server_get_stats(lua_State *L) +{ + struct server *srv; + int i; + + srv = hlua_check_server(L, 1); + + if (!srv->proxy) { + lua_pushnil(L); + return 1; + } + + stats_fill_sv_stats(srv->proxy, srv, ST_SHLGNDS, stats, STATS_LEN); + + lua_newtable(L); + for (i=0; iaddr.ss_family) { + case AF_INET: + inet_ntop(AF_INET, &((struct sockaddr_in *)&srv->addr)->sin_addr, + addr, INET_ADDRSTRLEN); + luaL_addstring(&b, addr); + luaL_addstring(&b, ":"); + snprintf(addr, INET_ADDRSTRLEN, "%d", + ntohs(((struct sockaddr_in *)&srv->addr)->sin_port)); + luaL_addstring(&b, addr); + break; + case AF_INET6: + inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&srv->addr)->sin6_addr, + addr, INET_ADDRSTRLEN); + luaL_addstring(&b, addr); + luaL_addstring(&b, ":"); + snprintf(addr, INET_ADDRSTRLEN, "%d", + ntohs(((struct sockaddr_in6 *)&srv->addr)->sin6_port)); + luaL_addstring(&b, addr); + break; + case AF_UNIX: + luaL_addstring(&b, (char *)((struct sockaddr_un *)&srv->addr)->sun_path); + break; + default: + luaL_addstring(&b, ""); + break; + } + + luaL_pushresult(&b); + return 1; +} + +int hlua_server_is_draining(lua_State *L) +{ + struct server *srv; + + srv = hlua_check_server(L, 1); + lua_pushinteger(L, server_is_draining(srv)); + return 1; +} + +int hlua_server_set_weight(lua_State *L) +{ + struct server *srv; + const char *weight; + const char *err; + + srv = hlua_check_server(L, 1); + weight = luaL_checkstring(L, 2); + + err = server_parse_weight_change_request(srv, weight); + if (!err) + lua_pushnil(L); + else + hlua_pushstrippedstring(L, err); + return 1; +} + +int hlua_server_get_weight(lua_State *L) +{ + struct server *srv; + + srv = hlua_check_server(L, 1); + lua_pushinteger(L, srv->uweight); + return 1; +} + +int hlua_server_set_addr(lua_State *L) +{ + struct server *srv; + const char *addr; + const char *err; + + srv = hlua_check_server(L, 1); + addr = luaL_checkstring(L, 2); + + err = server_parse_addr_change_request(srv, addr, "Lua script"); + if (!err) + lua_pushnil(L); + else + hlua_pushstrippedstring(L, err); + return 1; +} + +int hlua_server_shut_sess(lua_State *L) +{ + struct server *srv; + + srv = hlua_check_server(L, 1); + srv_shutdown_streams(srv, SF_ERR_KILLED); + return 0; +} + +int hlua_server_set_drain(lua_State *L) +{ + struct server *srv; + + srv = hlua_check_server(L, 1); + srv_adm_set_drain(srv); + return 0; +} + +int hlua_server_set_maint(lua_State *L) +{ + struct server *srv; + + srv = hlua_check_server(L, 1); + srv_adm_set_maint(srv); + return 0; +} + +int hlua_server_set_ready(lua_State *L) +{ + struct server *srv; + + srv = hlua_check_server(L, 1); + srv_adm_set_ready(srv); + return 0; +} + +int hlua_server_check_enable(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (sv->check.state & CHK_ST_CONFIGURED) { + sv->check.state &= ~CHK_ST_ENABLED; + } + return 0; +} + +int hlua_server_check_disable(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (sv->check.state & CHK_ST_CONFIGURED) { + sv->check.state |= CHK_ST_ENABLED; + } + return 0; +} + +int hlua_server_check_force_up(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (!(sv->track)) { + sv->check.health = sv->check.rise + sv->check.fall - 1; + srv_set_running(sv, "changed from Lua script"); + } + return 0; +} + +int hlua_server_check_force_nolb(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (!(sv->track)) { + sv->check.health = sv->check.rise + sv->check.fall - 1; + srv_set_stopping(sv, "changed from Lua script"); + } + return 0; +} + +int hlua_server_check_force_down(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (!(sv->track)) { + sv->check.health = 0; + srv_set_stopped(sv, "changed from Lua script"); + } + return 0; +} + +int hlua_server_agent_enable(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (sv->agent.state & CHK_ST_CONFIGURED) { + sv->agent.state |= CHK_ST_ENABLED; + } + return 0; +} + +int hlua_server_agent_disable(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (sv->agent.state & CHK_ST_CONFIGURED) { + sv->agent.state &= ~CHK_ST_ENABLED; + } + return 0; +} + +int hlua_server_agent_force_up(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (sv->agent.state & CHK_ST_ENABLED) { + sv->agent.health = sv->agent.rise + sv->agent.fall - 1; + srv_set_running(sv, "changed from Lua script"); + } + return 0; +} + +int hlua_server_agent_force_down(lua_State *L) +{ + struct server *sv; + + sv = hlua_check_server(L, 1); + if (sv->agent.state & CHK_ST_ENABLED) { + sv->agent.health = 0; + srv_set_stopped(sv, "changed from Lua script"); + } + return 0; +} + int hlua_fcn_new_proxy(lua_State *L, struct proxy *px) { + struct server *srv; + lua_newtable(L); /* Pop a class sesison metatable and affect it to the userdata. */ @@ -444,6 +722,17 @@ int hlua_fcn_new_proxy(lua_State *L, struct proxy *px) lua_pushlightuserdata(L, px); lua_rawseti(L, -2, 0); + + /* Browse and register servers. */ + lua_pushstring(L, "servers"); + lua_newtable(L); + for (srv = px->srv; srv; srv = srv->next) { + lua_pushstring(L, srv->id); + hlua_fcn_new_server(L, srv); + lua_settable(L, -3); + } + lua_settable(L, -3); + return 1; } @@ -567,6 +856,32 @@ int hlua_fcn_reg_core_fcn(lua_State *L) hlua_class_function(L, "concat", hlua_concat_new); hlua_class_function(L, "get_info", hlua_get_info); + /* Create server object. */ + lua_newtable(L); + lua_pushstring(L, "__index"); + lua_newtable(L); + hlua_class_function(L, "is_draining", hlua_server_is_draining); + hlua_class_function(L, "set_weight", hlua_server_set_weight); + hlua_class_function(L, "get_weight", hlua_server_get_weight); + hlua_class_function(L, "set_addr", hlua_server_set_addr); + hlua_class_function(L, "get_addr", hlua_server_get_addr); + hlua_class_function(L, "get_stats", hlua_server_get_stats); + hlua_class_function(L, "shut_sess", hlua_server_shut_sess); + hlua_class_function(L, "set_drain", hlua_server_set_drain); + hlua_class_function(L, "set_maint", hlua_server_set_maint); + hlua_class_function(L, "set_ready", hlua_server_set_ready); + hlua_class_function(L, "check_enable", hlua_server_check_enable); + hlua_class_function(L, "check_disable", hlua_server_check_disable); + hlua_class_function(L, "check_force_up", hlua_server_check_force_up); + hlua_class_function(L, "check_force_nolb", hlua_server_check_force_nolb); + hlua_class_function(L, "check_force_down", hlua_server_check_force_down); + hlua_class_function(L, "agent_enable", hlua_server_agent_enable); + hlua_class_function(L, "agent_disable", hlua_server_agent_disable); + hlua_class_function(L, "agent_force_up", hlua_server_agent_force_up); + hlua_class_function(L, "agent_force_down", hlua_server_agent_force_down); + lua_settable(L, -3); /* -> META["__index"] = TABLE */ + class_server_ref = hlua_register_metatable(L, CLASS_SERVER); + /* Create proxy object. */ lua_newtable(L); lua_pushstring(L, "__index");