source: nscp/modules/LUAScript/script_wrapper.hpp @ a8c6e93

0.4.00.4.10.4.2
Last change on this file since a8c6e93 was a8c6e93, checked in by Michael Medin <michael@…>, 16 months ago

Now "everything" (ish) works including channels, exec and query (via moderna API)
Still no protocol buffer support but not sure how to play that yet so will not be avalible in 0.4.0.

  • Property mode set to 100644
File size: 15.0 KB
Line 
1#pragma once
2
3#include <boost/enable_shared_from_this.hpp>
4#include <boost/shared_ptr.hpp>
5#include <map>
6
7#include "lua_wrappers.hpp"
8
9#include <scripts/functions.hpp>
10
11namespace script_wrapper {
12
13        typedef lua_wrappers::lua_wrapper lua_wrapper;
14        typedef lua_wrappers::lua_script_instance script_instance;
15        typedef lua_wrappers::lua_instance_manager instance_manager;
16
17
18        class base_script_object : boost::noncopyable {
19        private:
20                instance_manager::script_instance_type instance;
21
22        public:
23                base_script_object(lua_State *L) {
24                        instance = instance_manager::get_script(L);
25                }
26                instance_manager::script_instance_type get_instance() {
27                        if (!instance)
28                                throw lua_wrappers::LUAException("Invalid instance");
29                        return instance;
30                }
31        };
32
33        class core_wrapper : public base_script_object {
34        public:
35                core_wrapper(lua_State *L) : base_script_object(L) {
36                        NSC_DEBUG_MSG(_T("get: "));
37                }
38
39                static const char className[];
40                static const Luna<core_wrapper>::RegType methods[];
41
42                int simple_query(lua_State *L) {
43                        lua_wrappers::lua_wrapper lua(L);
44                        try {
45                                int nargs = lua.size();
46                                if (nargs == 0)
47                                        return lua.error("nscp.execute requires at least 1 argument!");
48                                const unsigned int argLen = nargs-1;
49                                std::list<std::wstring> arguments;
50                                for (unsigned int i=argLen; i>0; i--) {
51                                        if (lua.is_table()) {
52                                                std::list<std::wstring> table = lua.pop_array();
53                                                arguments.insert(arguments.begin(), table.begin(), table.end());
54                                        } else {
55                                                arguments.push_front(lua.pop_string());
56                                        }
57                                }
58                                std::wstring command = lua.pop_string();
59                                std::wstring message;
60                                std::wstring perf;
61                                NSCAPI::nagiosReturn ret = get_instance()->get_core()->simple_query(command, arguments, message, perf);
62                                lua.push_code(ret);
63                                lua.push_string(message);
64                                lua.push_string(perf);
65                                return lua.size();
66                        } catch (...) {
67                                return lua.error("Unknown exception in: simple_query");
68                        }
69                }
70                int query(lua_State *L) {
71                        lua_wrappers::lua_wrapper lua(L);
72                        NSC_LOG_ERROR_STD(_T("Unsupported API called: query"));
73                        return lua.error("Unsupported API called: query");
74                }
75                int simple_exec(lua_State *L) {
76                        lua_wrappers::lua_wrapper lua(L);
77                        try {
78                                int nargs = lua.size();
79                                std::wstring target = lua.wstring(1);
80                                std::wstring command = lua.wstring(2);
81                                std::list<std::wstring> arguments = lua.checkarray(3);
82                                std::list<std::wstring> result;
83                                NSCAPI::nagiosReturn ret = get_instance()->get_core()->exec_simple_command(target, command, arguments, result);
84                                lua.push_code(ret);
85                                lua.push_array(result);
86                                return 2;
87                        } catch (...) {
88                                return lua.error("Unknown exception in: simple_query");
89                        }
90                }
91                int exec(lua_State *L) {
92                        lua_wrappers::lua_wrapper lua(L);
93                        NSC_LOG_ERROR_STD(_T("Unsupported API called: exec"));
94                        return lua.error("Unsupported API called: exec");
95                }
96                int simple_submit(lua_State *L) {
97                        lua_wrappers::lua_wrapper lua(L);
98                        try {
99                                int nargs = lua.size();
100                                std::wstring channel = lua.wstring(1);
101                                std::wstring command = lua.wstring(2);
102                                NSCAPI::nagiosReturn code = lua.get_code(3);
103                                std::wstring message = lua.wstring(4);
104                                std::wstring perf = lua.wstring(5);
105                                std::wstring result;
106                                NSCAPI::nagiosReturn ret = get_instance()->get_core()->submit_simple_message(channel, command, code, message, perf, result);
107                                lua.push_code(ret);
108                                lua.push_string(result);
109                                return 2;
110                        } catch (...) {
111                                return lua.error("Unknown exception in: simple_query");
112                        }
113                }
114                int submit(lua_State *L) {
115                        lua_wrappers::lua_wrapper lua(L);
116                        NSC_LOG_ERROR_STD(_T("Unsupported API called: submit"));
117                        return lua.error("Unsupported API called: submit");
118                }
119                int reload(lua_State *L) {
120                        lua_wrappers::lua_wrapper lua(L);
121                        if (lua.size() > 1)
122                                return lua.error("Incorrect syntax: reload([<module>]);");
123                        std::wstring module = _T("module");
124                        if (lua.size() == 1)
125                                module = lua.pop_string();
126                        get_instance()->get_core()->reload(module);
127                        return 0;
128                }
129        };
130
131        const char core_wrapper::className[] = "Core";
132        const Luna<core_wrapper>::RegType core_wrapper::methods[] = {
133                { "simple_query", &core_wrapper::simple_query },
134                { "query", &core_wrapper::query },
135                { "simple_exec", &core_wrapper::simple_exec },
136                { "exec", &core_wrapper::exec },
137                { "simple_submit", &core_wrapper::simple_submit },
138                { "submit", &core_wrapper::submit },
139                { "reload", &core_wrapper::reload },
140                { 0 }
141        };
142
143        class registry_wrapper : public base_script_object {
144        private:
145
146        public:
147
148                registry_wrapper(lua_State *L) : base_script_object(L) {}
149
150                static const char className[];
151                static const Luna<registry_wrapper>::RegType methods[];
152
153                int register_function(lua_State *L) {
154                        lua_wrappers::lua_wrapper lua(L);
155                        NSC_LOG_ERROR_STD(_T("Unsupported API called: exec"));
156                        return lua.error("Unsupported API called: exec");
157                }
158                int register_simple_function(lua_State *L) {
159                        lua_wrapper lua(L);
160                        std::wstring description;
161                        if (lua.size() > 2)
162                                description = lua.pop_string();
163                        std::wstring name;
164                        if (lua.is_string()) {
165                                name = lua.pop_string();
166                                lua_getglobal(L, utf8::cvt<std::string>(name).c_str());
167                        }
168                        if (!lua.is_function())
169                                return lua.error("Invalid argument not a function: " + utf8::cvt<std::string>(name));
170
171                        int func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
172
173                        if (func_ref == 0)
174                                return lua.error("Invalid function: " + utf8::cvt<std::string>(name));
175                        std::wstring script = lua.pop_string();
176                        if (description.empty())
177                                description = _T("Lua script: ") + script;
178                        get_instance()->get_core()->registerCommand(get_instance()->get_plugin_id(), script, description);
179                        get_instance()->get_registry()->register_query(script, get_instance(), func_ref);
180                        return 0;
181                }
182                int register_cmdline(lua_State *L) {
183                        lua_wrappers::lua_wrapper lua(L);
184                        NSC_LOG_ERROR_STD(_T("Unsupported API called: exec"));
185                        return lua.error("Unsupported API called: exec");
186                }
187                int register_simple_cmdline(lua_State *L) {
188                        lua_wrapper lua(L);
189                        std::wstring name;
190                        if (lua.is_string()) {
191                                name = lua.pop_string();
192                                lua_getglobal(L, utf8::cvt<std::string>(name).c_str());
193                        }
194                        if (!lua.is_function())
195                                return lua.error("Invalid argument not a function: " + utf8::cvt<std::string>(name));
196
197                        int func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
198
199                        if (func_ref == 0)
200                                return lua.error("Invalid function: " + utf8::cvt<std::string>(name));
201                        std::wstring script = lua.pop_string();
202                        get_instance()->get_registry()->register_exec(script, get_instance(), func_ref);
203                        return 0;
204                }
205                int subscription(lua_State *L) {
206                        lua_wrappers::lua_wrapper lua(L);
207                        NSC_LOG_ERROR_STD(_T("Unsupported API called: exec"));
208                        return lua.error("Unsupported API called: exec");
209                }
210                int simple_subscription(lua_State *L) {
211                        lua_wrapper lua(L);
212                        std::wstring name;
213                        if (lua.is_string()) {
214                                name = lua.pop_string();
215                                lua_getglobal(L, utf8::cvt<std::string>(name).c_str());
216                        }
217                        if (!lua.is_function())
218                                return lua.error("Invalid argument not a function: " + utf8::cvt<std::string>(name));
219
220                        int func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
221
222                        if (func_ref == 0)
223                                return lua.error("Invalid function: " + utf8::cvt<std::string>(name));
224                        std::wstring channel = lua.pop_string();
225                        get_instance()->get_core()->registerSubmissionListener(get_instance()->get_plugin_id(), channel);
226                        get_instance()->get_registry()->register_subscription(channel, get_instance(), func_ref);
227                        return 0;
228                }
229        };
230
231        const char registry_wrapper::className[] = "Registry";
232        const Luna<registry_wrapper>::RegType registry_wrapper::methods[] = {
233                { "function", &registry_wrapper::register_function },
234                { "simple_function", &registry_wrapper::register_simple_function },
235                { "cmdline", &registry_wrapper::register_cmdline },
236                { "simple_cmdline", &registry_wrapper::register_simple_cmdline },
237                { "subscription", &registry_wrapper::subscription },
238                { "simple_subscription", &registry_wrapper::simple_subscription },
239                { 0 }
240        };
241
242
243
244        class settings_wrapper : public base_script_object {
245        public:
246
247                settings_wrapper(lua_State *L) : base_script_object(L) {
248                        NSC_DEBUG_MSG(_T("create"));
249                }
250
251                static const char className[];
252                static const Luna<settings_wrapper>::RegType methods[];
253
254                int get_section(lua_State *L) {
255                        lua_wrapper lua(L);
256                        std::wstring v = lua.op_wstring(1);
257                        try {
258                                lua.push_array(get_instance()->get_core()->getSettingsSection(v));
259                        } catch (...) {
260                                return lua.error("Unknown exception getting section");
261                        }
262                        return 1;
263                }
264                int get_string(lua_State *L) {
265                        lua_wrapper lua(L);
266                        std::wstring s = lua.wstring(1);
267                        std::wstring k = lua.wstring(2);
268                        std::wstring v = lua.op_wstring(3);
269                        lua.push_string(get_instance()->get_core()->getSettingsString(s, k, v));
270                        return 1;
271                }
272                int set_string(lua_State *L) {
273                        lua_wrapper lua(L);
274                        std::wstring s = lua.wstring(1);
275                        std::wstring k = lua.wstring(2);
276                        std::wstring v = lua.wstring(3);
277                        get_instance()->get_core()->SetSettingsString(s, k, v);
278                        return 0;
279                }
280                int get_bool(lua_State *L) {
281                        lua_wrapper lua(L);
282                        std::wstring s = lua.wstring(1);
283                        std::wstring k = lua.wstring(2);
284                        bool v = lua.checkbool(3);
285                        lua.push_boolean(get_instance()->get_core()->getSettingsInt(s, k, v?1:0)==1);
286                        return 1;
287                }
288                int set_bool(lua_State *L) {
289                        lua_wrapper lua(L);
290                        std::wstring s = lua.wstring(1);
291                        std::wstring k = lua.wstring(2);
292                        bool v = lua.checkbool(3);
293                        get_instance()->get_core()->SetSettingsInt(s, k, v?1:0);
294                        return 0;
295                }
296                int get_int(lua_State *L) {
297                        lua_wrapper lua(L);
298                        std::wstring s = lua.wstring(1);
299                        std::wstring k = lua.wstring(2);
300                        int v = lua.checkint(3);
301                        lua.push_int(get_instance()->get_core()->getSettingsInt(s, k, v));
302                        return 1;
303                }
304                int set_int(lua_State *L) {
305                        lua_wrapper lua(L);
306                        std::wstring s = lua.wstring(1);
307                        std::wstring k = lua.wstring(2);
308                        int v = lua.checkint(3);
309                        get_instance()->get_core()->SetSettingsInt(s, k, v);
310                        return 0;
311                }
312                int save(lua_State *L) {
313                        get_instance()->get_core()->settings_save();
314                        return 0;
315                }
316                int register_path(lua_State *L) {
317                        lua_wrapper lua(L);
318                        std::wstring path = lua.wstring(1);
319                        std::wstring title = lua.wstring(1);
320                        std::wstring description = lua.wstring(1);
321                        get_instance()->get_core()->settings_register_path(path, title, description, false);
322                        return 0;
323                }
324                NSCAPI::settings_type script_wrapper::settings_wrapper::get_type(std::string stype) {
325                        if (stype == "string" || stype == "str" || stype == "s")
326                                return NSCAPI::key_string;
327                        if (stype == "integer" || stype == "int" || stype == "i")
328                                return NSCAPI::key_integer;
329                        if (stype == "bool" || stype == "b")
330                                return NSCAPI::key_bool;
331                        NSC_LOG_ERROR_STD(_T("Invalid settings type"));
332                        return NSCAPI::key_string;
333                }
334
335                int register_key(lua_State *L) {
336                        lua_wrapper lua(L);
337                        std::wstring path = lua.wstring(1);
338                        std::wstring key = lua.wstring(1);
339                        std::string stype = lua.string(1);
340                        NSCAPI::settings_type type = get_type(stype);
341                        std::wstring title = lua.wstring(1);
342                        std::wstring description = lua.wstring(1);
343                        std::wstring defaultValue = lua.wstring(1);
344                        get_instance()->get_core()->settings_register_key(path, key, type, title, description, defaultValue, false);
345                        return 0;
346                }
347               
348        };
349
350        const char settings_wrapper::className[] = "Settings";
351        const Luna<settings_wrapper>::RegType settings_wrapper::methods[] = {
352                { "get_section", &settings_wrapper::get_section },
353                { "get_string", &settings_wrapper::get_string },
354                { "set_string", &settings_wrapper::set_string },
355                { "get_bool", &settings_wrapper::get_bool },
356                { "set_bool", &settings_wrapper::set_bool },
357                { "get_int", &settings_wrapper::get_int },
358                { "set_int", &settings_wrapper::set_int },
359                { "save", &settings_wrapper::save },
360                { "register_path", &settings_wrapper::register_path },
361                { "register_key", &settings_wrapper::register_key },
362                { 0 }
363        };
364
365        class nsclient_wrapper {
366        public:
367
368                static int execute (lua_State *L) {
369                        core_wrapper core(L);
370                        return core.simple_query(L);
371                }
372
373                static int register_command(lua_State *L) {
374                        registry_wrapper registry(L);
375                        return registry.register_simple_function(L);
376                }
377
378                static int getSetting (lua_State *L) {
379                        settings_wrapper sw(L);
380                        return sw.get_string(L);
381                }
382                static int getSection (lua_State *L) {
383                        settings_wrapper sw(L);
384                        return sw.get_section(L);
385                }
386                static int info (lua_State *L) {
387                        return log_any(L, NSCAPI::log_level::info);
388                }
389                static int error (lua_State *L) {
390                        return log_any(L, NSCAPI::log_level::error);
391                }
392                static int log_any(lua_State *L, int mode) {
393                        lua_wrapper lua(L);
394                        lua_wrapper::stack_trace trace = lua.get_stack_trace();
395                        int nargs = lua.size();
396                        std::wstring str;
397                        for (int i=0;i<nargs;i++) {
398                                str += lua.pop_string();
399                        }
400                        GET_CORE()->log(mode, utf8::cvt<std::string>(trace.first), trace.second, str);
401                        return 0;
402                }
403
404                static const luaL_Reg my_funcs[];
405
406                static void luaopen(lua_State *L) {
407                        luaL_register(L, "nscp", my_funcs);
408                        lua_pop(L, 1);
409                        Luna<core_wrapper>::Register(L);
410                        Luna<registry_wrapper>::Register(L);
411                        Luna<settings_wrapper>::Register(L);
412                }
413
414        };
415        const luaL_Reg nsclient_wrapper::my_funcs[] = {
416                {"execute", execute},
417                {"info", info},
418                {"print", info},
419                {"error", error},
420                {"register", register_command},
421                {"getSetting", getSetting},
422                {"getSection", getSection},
423                {NULL, NULL}
424        };
425
426        class lua_script : public script_instance, public boost::enable_shared_from_this<lua_script>  {
427                lua_script(nscapi::core_wrapper* core, const int plugin_id, boost::shared_ptr<lua_wrappers::lua_registry> registry, const std::string alias, const std::string script)
428                        : script_instance(core, plugin_id, registry, alias, script) {}
429        public:
430
431                static boost::shared_ptr<lua_script> create_instance(nscapi::core_wrapper* core, const int plugin_id, boost::shared_ptr<lua_wrappers::lua_registry> registry, const std::wstring alias, const std::wstring script) {
432                        boost::shared_ptr<lua_script> instance(new lua_script(core, plugin_id, registry, utf8::cvt<std::string>(alias), utf8::cvt<std::string>(script)));
433                        if (instance) {
434                                instance->init();
435                                instance->load();
436                        }
437                        return instance;
438                }
439                void init() {
440                        lua_wrappers::lua_instance_manager::set_script(get_lua_state(), shared_from_this());
441                }
442
443                void load() {
444                        lua_wrappers::lua_wrapper lua(get_lua_state());
445                        lua.openlibs();
446                        nsclient_wrapper::luaopen(get_lua_state());
447                        if (lua.loadfile(get_script()) != 0)
448                                throw lua_wrappers::LUAException(_T("Failed to load script: ") + get_wscript() + _T(": ") + lua.pop_string());
449                        if (lua.pcall(0, 0, 0) != 0)
450                                throw lua_wrappers::LUAException(_T("Failed to execute script: ") + get_wscript() + _T(": ") + lua.pop_string());
451                }
452                std::wstring get_wscript() const {
453                        return utf8::cvt<std::wstring>(get_script());
454                }
455                void unload() {}
456                void reload() {
457                        unload();
458                        load();
459                }
460        };
461}
Note: See TracBrowser for help on using the repository browser.