MINOR: hlua: expose SERVER_ADMIN event

Exposing SERVER_ADMIN event in lua and updating the documentation.
diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst
index 333c351..8a82a16 100644
--- a/doc/lua-api/index.rst
+++ b/doc/lua-api/index.rst
@@ -947,6 +947,7 @@
     * **SERVER_DOWN**: when a server state goes from UP to DOWN
     * **SERVER_UP**: when a server state goes from DOWN to UP
     * **SERVER_STATE**: when a server state changes
+    * **SERVER_ADMIN**: when a server administrative state changes
 
    .. Note::
      Use **SERVER** in **event_types** to subscribe to all server events types
@@ -1533,6 +1534,13 @@
   .. Note::
      Only available for SERVER_STATE event
 
+.. js:attribute:: ServerEvent.admin
+
+  A :ref:`server_event_admin_class`
+
+  .. Note::
+     Only available for SERVER_ADMIN event
+
 .. _server_event_checkres_class:
 
 ServerEventCheckRes class
@@ -1631,6 +1639,45 @@
   backend that may be redispatched to the server according to the load
   balancing algorithm that is in use.
 
+.. _server_event_admin_class:
+
+ServerEventAdmin class
+======================
+
+.. js:class:: ServerEventAdmin
+
+This class contains additional info related to **SERVER_ADMIN** event.
+
+.. js:attribute:: ServerEventAdmin.cause
+
+  Printable admin state change cause. Might be empty.
+
+.. js:attribute:: ServerEventAdmin.new_admin
+
+  New server admin state due to the admin change.
+
+  It is an array of string containing a composition of following values:
+    - "**MAINT**": server is in maintenance mode
+    - "FMAINT": server is in forced maintenance mode (MAINT is also set)
+    - "IMAINT": server is in inherited maintenance mode (MAINT is also set)
+    - "RMAINT": server is in resolve maintenance mode (MAINT is also set)
+    - "CMAINT": server is in config maintenance mode (MAINT is also set)
+    - "**DRAIN**": server is in drain mode
+    - "FDRAIN": server is in forced drain mode (DRAIN is also set)
+    - "IDRAIN": server is in inherited drain mode (DRAIN is also set)
+
+.. js:attribute:: ServerEventAdmin.old_admin
+
+  Previous server admin state prior to the admin change.
+
+  Values are presented as in **new_admin**, but they should differ.
+  (Comparing old and new helps to find out the change(s))
+
+.. js:attribute:: ServerEventAdmin.requeued
+
+  Same as :js:attr:`ServerEventState.requeued` but when the requeue is due to
+  the server administrative state change.
+
 .. _concat_class:
 
 Concat class
diff --git a/src/hlua.c b/src/hlua.c
index 34ad3c8..e3d6efd 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -9200,6 +9200,65 @@
 
 			lua_settable(hlua->T, -3); /* state table */
 		}
+		else if (event_hdl_sub_type_equal(EVENT_HDL_SUB_SERVER_ADMIN, event)) {
+			struct event_hdl_cb_data_server_admin *admin = data;
+			int it;
+
+			if (!lua_checkstack(hlua->T, 20))
+				WILL_LJMP(luaL_error(hlua->T, "Lua out of memory error."));
+
+			/* admin subclass */
+			lua_pushstring(hlua->T, "admin");
+			lua_newtable(hlua->T);
+
+			lua_pushstring(hlua->T, "cause");
+			lua_pushstring(hlua->T, srv_adm_st_chg_cause(admin->safe.cause));
+			lua_settable(hlua->T, -3);
+
+			/* old_admin, new_admin */
+			for (it = 0; it < 2; it++) {
+				enum srv_admin srv_admin = (!it) ? admin->safe.old_admin : admin->safe.new_admin;
+
+				lua_pushstring(hlua->T, (!it) ? "old_admin" : "new_admin");
+
+				/* admin state matrix */
+				lua_newtable(hlua->T);
+
+				lua_pushstring(hlua->T, "MAINT");
+				lua_pushboolean(hlua->T, srv_admin & SRV_ADMF_MAINT);
+				lua_settable(hlua->T, -3);
+				lua_pushstring(hlua->T, "FMAINT");
+				lua_pushboolean(hlua->T, srv_admin & SRV_ADMF_FMAINT);
+				lua_settable(hlua->T, -3);
+				lua_pushstring(hlua->T, "IMAINT");
+				lua_pushboolean(hlua->T, srv_admin & SRV_ADMF_IMAINT);
+				lua_settable(hlua->T, -3);
+				lua_pushstring(hlua->T, "RMAINT");
+				lua_pushboolean(hlua->T, srv_admin & SRV_ADMF_RMAINT);
+				lua_settable(hlua->T, -3);
+				lua_pushstring(hlua->T, "CMAINT");
+				lua_pushboolean(hlua->T, srv_admin & SRV_ADMF_CMAINT);
+				lua_settable(hlua->T, -3);
+
+				lua_pushstring(hlua->T, "DRAIN");
+				lua_pushboolean(hlua->T, srv_admin & SRV_ADMF_DRAIN);
+				lua_settable(hlua->T, -3);
+				lua_pushstring(hlua->T, "FDRAIN");
+				lua_pushboolean(hlua->T, srv_admin & SRV_ADMF_FDRAIN);
+				lua_settable(hlua->T, -3);
+				lua_pushstring(hlua->T, "IDRAIN");
+				lua_pushboolean(hlua->T, srv_admin & SRV_ADMF_IDRAIN);
+				lua_settable(hlua->T, -3);
+
+				lua_settable(hlua->T, -3); /* matrix table */
+			}
+			/* requeued */
+			lua_pushstring(hlua->T, "requeued");
+			lua_pushinteger(hlua->T, admin->safe.requeued);
+			lua_settable(hlua->T, -3);
+
+			lua_settable(hlua->T, -3); /* admin table */
+		}
 
 		/* attempt to provide reference server object
 		 * (if it wasn't removed yet, SERVER_DEL will never succeed here)