ARI: Added new functionality to get all module information.
[asterisk/asterisk.git] / res / ari / resource_asterisk.c
1 /* -*- C -*-
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012 - 2013, Digium, Inc.
5  *
6  * David M. Lee, II <dlee@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Implementation for ARI stubs.
22  *
23  * \author David M. Lee, II <dlee@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 ASTERISK_REGISTER_FILE()
33
34 #include "asterisk/ast_version.h"
35 #include "asterisk/buildinfo.h"
36 #include "asterisk/module.h"
37 #include "asterisk/paths.h"
38 #include "asterisk/pbx.h"
39 #include "resource_asterisk.h"
40
41 void ast_ari_asterisk_get_info(struct ast_variable *headers,
42         struct ast_ari_asterisk_get_info_args *args,
43         struct ast_ari_response *response)
44 {
45         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
46         int show_all = args->only_count == 0;
47         int show_build = show_all;
48         int show_system = show_all;
49         int show_config = show_all;
50         int show_status = show_all;
51         size_t i;
52         int res = 0;
53
54         for (i = 0; i < args->only_count; ++i) {
55                 if (strcasecmp("build", args->only[i]) == 0) {
56                         show_build = 1;
57                 } else if (strcasecmp("system", args->only[i]) == 0) {
58                         show_system = 1;
59                 } else if (strcasecmp("config", args->only[i]) == 0) {
60                         show_config = 1;
61                 } else if (strcasecmp("status", args->only[i]) == 0) {
62                         show_status = 1;
63                 } else {
64                         ast_log(LOG_WARNING, "Unrecognized info section '%s'\n",
65                                 args->only[i]);
66                 }
67         }
68
69         json = ast_json_object_create();
70
71         if (show_build) {
72                 res |= ast_json_object_set(json, "build",
73                         ast_json_pack(
74                                 "{ s: s, s: s, s: s,"
75                                 "  s: s, s: s, s: s }",
76
77                                 "os", ast_build_os,
78                                 "kernel", ast_build_kernel,
79                                 "machine", ast_build_machine,
80
81                                 "options", AST_BUILDOPTS,
82                                 "date", ast_build_date,
83                                 "user", ast_build_user));
84         }
85
86         if (show_system) {
87                 char eid_str[128];
88
89                 ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
90
91                 res |= ast_json_object_set(json, "system",
92                         ast_json_pack("{ s: s, s: s }",
93                                 "version", ast_get_version(),
94                                 "entity_id", eid_str));
95         }
96
97         if (show_config) {
98                 struct ast_json *config = ast_json_pack(
99                         "{ s: s, s: s,"
100                         " s: { s: s, s: s } }",
101
102                         "name", ast_config_AST_SYSTEM_NAME,
103                         "default_language", ast_defaultlanguage,
104
105                         "setid",
106                         "user", ast_config_AST_RUN_USER,
107                         "group", ast_config_AST_RUN_GROUP);
108
109                 res |= ast_json_object_set(json, "config", config);
110
111                 if (ast_option_maxcalls) {
112                         res |= ast_json_object_set(config, "max_channels",
113                                 ast_json_integer_create(ast_option_maxcalls));
114                 }
115
116                 if (ast_option_maxfiles) {
117                         res |= ast_json_object_set(config, "max_open_files",
118                                 ast_json_integer_create(ast_option_maxfiles));
119                 }
120
121                 if (ast_option_maxload) {
122                         res |= ast_json_object_set(config, "max_load",
123                                 ast_json_real_create(ast_option_maxload));
124                 }
125         }
126
127         if (show_status) {
128                 res |= ast_json_object_set(json, "status",
129                         ast_json_pack("{ s: o, s: o }",
130                                 "startup_time",
131                                 ast_json_timeval(ast_startuptime, NULL),
132                                 "last_reload_time",
133                                 ast_json_timeval(ast_lastreloadtime, NULL)));
134         }
135
136         if (res != 0) {
137                 ast_ari_response_alloc_failed(response);
138                 return;
139         }
140
141         ast_ari_response_ok(response, ast_json_ref(json));
142 }
143
144 /*!
145  * \brief Process module information and append to a json array
146  * \param module Resource name
147  * \param description Resource description
148  * \param usecnt Resource use count
149  * \param status Resource running status
150  * \param like
151  * \param support_level Resource support level
152  * \param module_data_list Resource array
153  *
154  * \retval 0 if no resource exists
155  * \retval 1 if resource exists
156  */
157 static int process_module_list(const char *module, const char *description, int usecnt,
158                                const char *status, const char *like,
159                                enum ast_module_support_level support_level, void *module_data_list)
160 {
161         struct ast_json *module_info;
162
163         module_info = ast_json_pack("{s: s, s: s, s: i, s: s, s: s}",
164                               "name", module,
165                               "description", description,
166                               "use_count", usecnt,
167                               "status", status,
168                               "support_level", ast_module_support_level_to_string(support_level));
169         if (!module_info) {
170                 return 0;
171         }
172         ast_json_array_append(module_data_list, module_info);
173         return 1;
174 }
175
176 void ast_ari_asterisk_list_modules(struct ast_variable *headers,
177         struct ast_ari_asterisk_list_modules_args *args,
178         struct ast_ari_response *response)
179 {
180         struct ast_json *json;
181
182         json = ast_json_array_create();
183         ast_update_module_list_data(&process_module_list, NULL, json);
184
185         ast_ari_response_ok(response, json);
186 }
187
188 void ast_ari_asterisk_get_global_var(struct ast_variable *headers,
189         struct ast_ari_asterisk_get_global_var_args *args,
190         struct ast_ari_response *response)
191 {
192         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
193         RAII_VAR(struct ast_str *, tmp, NULL, ast_free);
194
195         const char *value;
196
197         ast_assert(response != NULL);
198
199         if (ast_strlen_zero(args->variable)) {
200                 ast_ari_response_error(
201                         response, 400, "Bad Request",
202                         "Variable name is required");
203                 return;
204         }
205
206         tmp = ast_str_create(32);
207         if (!tmp) {
208                 ast_ari_response_alloc_failed(response);
209                 return;
210         }
211
212         value = ast_str_retrieve_variable(&tmp, 0, NULL, NULL, args->variable);
213
214         if (!(json = ast_json_pack("{s: s}", "value", S_OR(value, "")))) {
215                 ast_ari_response_alloc_failed(response);
216                 return;
217         }
218
219         ast_ari_response_ok(response, ast_json_ref(json));
220 }
221
222 void ast_ari_asterisk_set_global_var(struct ast_variable *headers,
223         struct ast_ari_asterisk_set_global_var_args *args,
224         struct ast_ari_response *response)
225 {
226         ast_assert(response != NULL);
227
228         if (ast_strlen_zero(args->variable)) {
229                 ast_ari_response_error(
230                         response, 400, "Bad Request",
231                         "Variable name is required");
232                 return;
233         }
234
235         pbx_builtin_setvar_helper(NULL, args->variable, args->value);
236
237         ast_ari_response_no_content(response);
238 }