resource_asterisk.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  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. /*! \file
  19. *
  20. * \brief Implementation for ARI stubs.
  21. *
  22. * \author David M. Lee, II <dlee@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  29. #include "asterisk/ast_version.h"
  30. #include "asterisk/buildinfo.h"
  31. #include "asterisk/logger.h"
  32. #include "asterisk/module.h"
  33. #include "asterisk/paths.h"
  34. #include "asterisk/pbx.h"
  35. #include "asterisk/sorcery.h"
  36. #include "resource_asterisk.h"
  37. static void return_sorcery_object(struct ast_sorcery *sorcery, void *sorcery_obj,
  38. struct ast_ari_response *response)
  39. {
  40. RAII_VAR(struct ast_json *, return_set, NULL, ast_json_unref);
  41. struct ast_variable *change_set;
  42. struct ast_variable *it_change_set;
  43. return_set = ast_json_array_create();
  44. if (!return_set) {
  45. ast_ari_response_alloc_failed(response);
  46. return;
  47. }
  48. /* Note that we can't use the sorcery JSON change set directly,
  49. * as it will hand us back an Object (with fields), and we need
  50. * a more generic representation of whatever the API call asked
  51. * for, i.e., a list of tuples.
  52. */
  53. change_set = ast_sorcery_objectset_create(sorcery, sorcery_obj);
  54. if (!change_set) {
  55. ast_ari_response_alloc_failed(response);
  56. return;
  57. }
  58. for (it_change_set = change_set; it_change_set; it_change_set = it_change_set->next) {
  59. struct ast_json *tuple;
  60. tuple = ast_json_pack("{s: s, s: s}",
  61. "attribute", it_change_set->name,
  62. "value", it_change_set->value);
  63. if (!tuple) {
  64. ast_variables_destroy(change_set);
  65. ast_ari_response_alloc_failed(response);
  66. return;
  67. }
  68. if (ast_json_array_append(return_set, tuple)) {
  69. ast_json_unref(tuple);
  70. ast_variables_destroy(change_set);
  71. ast_ari_response_alloc_failed(response);
  72. return;
  73. }
  74. }
  75. ast_variables_destroy(change_set);
  76. ast_ari_response_ok(response, ast_json_ref(return_set));
  77. }
  78. void ast_ari_asterisk_get_object(struct ast_variable *headers,
  79. struct ast_ari_asterisk_get_object_args *args,
  80. struct ast_ari_response *response)
  81. {
  82. RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
  83. RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
  84. RAII_VAR(void *, sorcery_obj, NULL, ao2_cleanup);
  85. sorcery = ast_sorcery_retrieve_by_module_name(args->config_class);
  86. if (!sorcery) {
  87. ast_ari_response_error(
  88. response, 404, "Not Found",
  89. "configClass '%s' not found",
  90. args->config_class);
  91. return;
  92. }
  93. object_type = ast_sorcery_get_object_type(sorcery, args->object_type);
  94. if (!object_type) {
  95. ast_ari_response_error(
  96. response, 404, "Not Found",
  97. "objectType '%s' not found",
  98. args->object_type);
  99. return;
  100. }
  101. sorcery_obj = ast_sorcery_retrieve_by_id(sorcery, args->object_type, args->id);
  102. if (!sorcery_obj) {
  103. ast_ari_response_error(
  104. response, 404, "Not Found",
  105. "Object with id '%s' not found",
  106. args->id);
  107. return;
  108. }
  109. return_sorcery_object(sorcery, sorcery_obj, response);
  110. }
  111. void ast_ari_asterisk_update_object(struct ast_variable *headers, struct ast_ari_asterisk_update_object_args *args, struct ast_ari_response *response)
  112. {
  113. RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
  114. RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
  115. RAII_VAR(void *, sorcery_obj, NULL, ao2_cleanup);
  116. struct ast_json *fields;
  117. struct ast_variable *update_set = NULL;
  118. int created = 0;
  119. sorcery = ast_sorcery_retrieve_by_module_name(args->config_class);
  120. if (!sorcery) {
  121. ast_ari_response_error(
  122. response, 404, "Not Found",
  123. "configClass '%s' not found",
  124. args->config_class);
  125. return;
  126. }
  127. object_type = ast_sorcery_get_object_type(sorcery, args->object_type);
  128. if (!object_type) {
  129. ast_ari_response_error(
  130. response, 404, "Not Found",
  131. "objectType '%s' not found",
  132. args->object_type);
  133. return;
  134. }
  135. sorcery_obj = ast_sorcery_retrieve_by_id(sorcery, args->object_type, args->id);
  136. if (!sorcery_obj) {
  137. ast_debug(5, "Sorcery object '%s' does not exist; creating it\n", args->id);
  138. sorcery_obj = ast_sorcery_alloc(sorcery, args->object_type, args->id);
  139. if (!sorcery_obj) {
  140. ast_ari_response_alloc_failed(response);
  141. return;
  142. }
  143. created = 1;
  144. } else {
  145. void *copy;
  146. copy = ast_sorcery_copy(sorcery, sorcery_obj);
  147. if (!copy) {
  148. ast_ari_response_alloc_failed(response);
  149. return;
  150. }
  151. ao2_ref(sorcery_obj, -1);
  152. sorcery_obj = copy;
  153. }
  154. fields = ast_json_object_get(args->fields, "fields");
  155. if (!fields && !created) {
  156. /* Whoops. We need data. */
  157. ast_ari_response_error(
  158. response, 400, "Bad request",
  159. "Fields must be provided to update object '%s'",
  160. args->id);
  161. return;
  162. } else if (fields) {
  163. size_t i;
  164. for (i = 0; i < ast_json_array_size(fields); i++) {
  165. struct ast_variable *new_var;
  166. struct ast_json *json_value = ast_json_array_get(fields, i);
  167. if (!json_value) {
  168. continue;
  169. }
  170. new_var = ast_variable_new(
  171. ast_json_string_get(ast_json_object_get(json_value, "attribute")),
  172. ast_json_string_get(ast_json_object_get(json_value, "value")),
  173. "");
  174. if (!new_var) {
  175. ast_variables_destroy(update_set);
  176. ast_ari_response_alloc_failed(response);
  177. return;
  178. }
  179. ast_variable_list_append(&update_set, new_var);
  180. }
  181. }
  182. /* APPLY! Note that a NULL update_set is fine (and necessary), as it
  183. * will force validation on a newly created object.
  184. */
  185. if (ast_sorcery_objectset_apply(sorcery, sorcery_obj, update_set)) {
  186. ast_variables_destroy(update_set);
  187. ast_ari_response_error(
  188. response, 400, "Bad request",
  189. "%s of object '%s' failed field value validation",
  190. created ? "Creation" : "Update",
  191. args->id);
  192. return;
  193. }
  194. ast_variables_destroy(update_set);
  195. if (created) {
  196. if (ast_sorcery_create(sorcery, sorcery_obj)) {
  197. ast_ari_response_error(
  198. response, 403, "Forbidden",
  199. "Cannot create sorcery objects of type '%s'",
  200. args->object_type);
  201. return;
  202. }
  203. } else {
  204. if (ast_sorcery_update(sorcery, sorcery_obj)) {
  205. ast_ari_response_error(
  206. response, 403, "Forbidden",
  207. "Cannot update sorcery objects of type '%s'",
  208. args->object_type);
  209. return;
  210. }
  211. }
  212. return_sorcery_object(sorcery, sorcery_obj, response);
  213. }
  214. void ast_ari_asterisk_delete_object(struct ast_variable *headers,
  215. struct ast_ari_asterisk_delete_object_args *args,
  216. struct ast_ari_response *response)
  217. {
  218. RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
  219. RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
  220. RAII_VAR(void *, sorcery_obj, NULL, ao2_cleanup);
  221. sorcery = ast_sorcery_retrieve_by_module_name(args->config_class);
  222. if (!sorcery) {
  223. ast_ari_response_error(
  224. response, 404, "Not Found",
  225. "configClass '%s' not found",
  226. args->config_class);
  227. return;
  228. }
  229. object_type = ast_sorcery_get_object_type(sorcery, args->object_type);
  230. if (!object_type) {
  231. ast_ari_response_error(
  232. response, 404, "Not Found",
  233. "objectType '%s' not found",
  234. args->object_type);
  235. return;
  236. }
  237. sorcery_obj = ast_sorcery_retrieve_by_id(sorcery, args->object_type, args->id);
  238. if (!sorcery_obj) {
  239. ast_ari_response_error(
  240. response, 404, "Not Found",
  241. "Object with id '%s' not found",
  242. args->id);
  243. return;
  244. }
  245. if (ast_sorcery_delete(sorcery, sorcery_obj)) {
  246. ast_ari_response_error(
  247. response, 403, "Forbidden",
  248. "Could not delete object with id '%s'",
  249. args->id);
  250. return;
  251. }
  252. ast_ari_response_no_content(response);
  253. }
  254. void ast_ari_asterisk_get_info(struct ast_variable *headers,
  255. struct ast_ari_asterisk_get_info_args *args,
  256. struct ast_ari_response *response)
  257. {
  258. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  259. int show_all = args->only_count == 0;
  260. int show_build = show_all;
  261. int show_system = show_all;
  262. int show_config = show_all;
  263. int show_status = show_all;
  264. size_t i;
  265. int res = 0;
  266. for (i = 0; i < args->only_count; ++i) {
  267. if (strcasecmp("build", args->only[i]) == 0) {
  268. show_build = 1;
  269. } else if (strcasecmp("system", args->only[i]) == 0) {
  270. show_system = 1;
  271. } else if (strcasecmp("config", args->only[i]) == 0) {
  272. show_config = 1;
  273. } else if (strcasecmp("status", args->only[i]) == 0) {
  274. show_status = 1;
  275. } else {
  276. ast_log(LOG_WARNING, "Unrecognized info section '%s'\n",
  277. args->only[i]);
  278. }
  279. }
  280. json = ast_json_object_create();
  281. if (show_build) {
  282. res |= ast_json_object_set(json, "build",
  283. ast_json_pack(
  284. "{ s: s, s: s, s: s,"
  285. " s: s, s: s, s: s }",
  286. "os", ast_build_os,
  287. "kernel", ast_build_kernel,
  288. "machine", ast_build_machine,
  289. "options", AST_BUILDOPTS,
  290. "date", ast_build_date,
  291. "user", ast_build_user));
  292. }
  293. if (show_system) {
  294. char eid_str[128];
  295. ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
  296. res |= ast_json_object_set(json, "system",
  297. ast_json_pack("{ s: s, s: s }",
  298. "version", ast_get_version(),
  299. "entity_id", eid_str));
  300. }
  301. if (show_config) {
  302. struct ast_json *config = ast_json_pack(
  303. "{ s: s, s: s,"
  304. " s: { s: s, s: s } }",
  305. "name", ast_config_AST_SYSTEM_NAME,
  306. "default_language", ast_defaultlanguage,
  307. "setid",
  308. "user", ast_config_AST_RUN_USER,
  309. "group", ast_config_AST_RUN_GROUP);
  310. res |= ast_json_object_set(json, "config", config);
  311. if (ast_option_maxcalls) {
  312. res |= ast_json_object_set(config, "max_channels",
  313. ast_json_integer_create(ast_option_maxcalls));
  314. }
  315. if (ast_option_maxfiles) {
  316. res |= ast_json_object_set(config, "max_open_files",
  317. ast_json_integer_create(ast_option_maxfiles));
  318. }
  319. if (ast_option_maxload) {
  320. res |= ast_json_object_set(config, "max_load",
  321. ast_json_real_create(ast_option_maxload));
  322. }
  323. }
  324. if (show_status) {
  325. res |= ast_json_object_set(json, "status",
  326. ast_json_pack("{ s: o, s: o }",
  327. "startup_time",
  328. ast_json_timeval(ast_startuptime, NULL),
  329. "last_reload_time",
  330. ast_json_timeval(ast_lastreloadtime, NULL)));
  331. }
  332. if (res != 0) {
  333. ast_ari_response_alloc_failed(response);
  334. return;
  335. }
  336. ast_ari_response_ok(response, ast_json_ref(json));
  337. }
  338. /*!
  339. * \brief Process module information and append to a json array
  340. * \param module Resource name
  341. * \param description Resource description
  342. * \param usecnt Resource use count
  343. * \param status Resource running status
  344. * \param like
  345. * \param support_level Resource support level
  346. * \param module_data_list Resource array
  347. *
  348. * \retval 0 if no resource exists
  349. * \retval 1 if resource exists
  350. */
  351. static int process_module_list(const char *module, const char *description, int usecnt,
  352. const char *status, const char *like,
  353. enum ast_module_support_level support_level, void *module_data_list)
  354. {
  355. struct ast_json *module_info;
  356. module_info = ast_json_pack("{s: s, s: s, s: i, s: s, s: s}",
  357. "name", module,
  358. "description", description,
  359. "use_count", usecnt,
  360. "status", status,
  361. "support_level", ast_module_support_level_to_string(support_level));
  362. if (!module_info) {
  363. return 0;
  364. }
  365. ast_json_array_append(module_data_list, module_info);
  366. return 1;
  367. }
  368. void ast_ari_asterisk_list_modules(struct ast_variable *headers,
  369. struct ast_ari_asterisk_list_modules_args *args,
  370. struct ast_ari_response *response)
  371. {
  372. struct ast_json *json;
  373. json = ast_json_array_create();
  374. if (!json) {
  375. ast_ari_response_alloc_failed(response);
  376. return;
  377. }
  378. ast_update_module_list_data(&process_module_list, NULL, json);
  379. ast_ari_response_ok(response, json);
  380. }
  381. /*!
  382. * \brief Identify module by name and process resource information
  383. * \param module Resource name
  384. * \param description Resource description
  385. * \param usecnt Resource use count
  386. * \param status Resource running status
  387. * \param like
  388. * \param support_level Resource support level
  389. * \param data JSON body for resource
  390. * \param condition Name to match resource to
  391. *
  392. * \retval 0 if no resource exists
  393. * \retval 1 if resource exists
  394. */
  395. static int identify_module(const char *module, const char *description, int usecnt,
  396. const char *status, const char *like,
  397. enum ast_module_support_level support_level, void *data,
  398. const char *condition)
  399. {
  400. int json_obj_set = 0;
  401. if (strcmp(condition, module) != 0) {
  402. return 0;
  403. }
  404. json_obj_set += ast_json_object_set(data, "name", ast_json_string_create(module));
  405. json_obj_set += ast_json_object_set(data, "description", ast_json_string_create(description));
  406. json_obj_set += ast_json_object_set(data, "use_count", ast_json_integer_create(usecnt));
  407. json_obj_set += ast_json_object_set(data, "status", ast_json_string_create(status));
  408. json_obj_set += ast_json_object_set(data, "support_level", ast_json_string_create(
  409. ast_module_support_level_to_string(support_level)));
  410. if (json_obj_set != 0) {
  411. return 0;
  412. }
  413. return 1;
  414. }
  415. void ast_ari_asterisk_get_module(struct ast_variable *headers,
  416. struct ast_ari_asterisk_get_module_args *args,
  417. struct ast_ari_response *response)
  418. {
  419. struct ast_json *json;
  420. int module_retrieved = 0;
  421. ast_assert(response != NULL);
  422. if (!ast_module_check(args->module_name)) {
  423. ast_ari_response_error(
  424. response, 404, "Not Found",
  425. "Module could not be found in running modules");
  426. return;
  427. }
  428. json = ast_json_object_create();
  429. if (!json) {
  430. ast_ari_response_alloc_failed(response);
  431. return;
  432. }
  433. module_retrieved = ast_update_module_list_condition(&identify_module, NULL, json,
  434. args->module_name);
  435. if (!module_retrieved) {
  436. ast_ari_response_error(
  437. response, 409, "Conflict",
  438. "Module information could not be retrieved");
  439. ast_json_unref(json);
  440. return;
  441. }
  442. ast_ari_response_ok(response, json);
  443. }
  444. void ast_ari_asterisk_load_module(struct ast_variable *headers,
  445. struct ast_ari_asterisk_load_module_args *args,
  446. struct ast_ari_response *response)
  447. {
  448. enum ast_module_load_result load_result;
  449. ast_assert(response != NULL);
  450. if (ast_module_check(args->module_name)) {
  451. ast_ari_response_error(
  452. response, 409, "Conflict",
  453. "Module is already loaded");
  454. return;
  455. }
  456. load_result = ast_load_resource(args->module_name);
  457. if (load_result == AST_MODULE_LOAD_DECLINE) {
  458. ast_ari_response_error(
  459. response, 409, "Conflict",
  460. "Module load declined");
  461. return;
  462. } else if (load_result == AST_MODULE_LOAD_SKIP) {
  463. ast_ari_response_error(
  464. response, 409, "Conflict",
  465. "Module was skipped");
  466. return;
  467. } else if (load_result == AST_MODULE_LOAD_FAILURE) {
  468. ast_ari_response_error(
  469. response, 409, "Conflict",
  470. "Module could not be loaded properly");
  471. return;
  472. }
  473. ast_ari_response_no_content(response);
  474. }
  475. void ast_ari_asterisk_unload_module(struct ast_variable *headers,
  476. struct ast_ari_asterisk_unload_module_args *args,
  477. struct ast_ari_response *response)
  478. {
  479. int unload_result;
  480. enum ast_module_unload_mode unload_mode = AST_FORCE_SOFT;
  481. ast_assert(response != NULL);
  482. if (!ast_module_check(args->module_name)) {
  483. ast_ari_response_error(
  484. response, 404, "Not Found",
  485. "Module not found in running modules");
  486. return;
  487. }
  488. unload_result = ast_unload_resource(args->module_name, unload_mode);
  489. if (unload_result != 0) {
  490. ast_ari_response_error(
  491. response, 409, "Conflict",
  492. "Module could not be unloaded");
  493. return;
  494. }
  495. ast_ari_response_no_content(response);
  496. }
  497. void ast_ari_asterisk_reload_module(struct ast_variable *headers,
  498. struct ast_ari_asterisk_reload_module_args *args,
  499. struct ast_ari_response *response)
  500. {
  501. enum ast_module_reload_result reload_result;
  502. ast_assert(response != NULL);
  503. if (!ast_module_check(args->module_name)) {
  504. ast_ari_response_error(
  505. response, 404, "Not Found",
  506. "Module not found in running modules");
  507. return;
  508. }
  509. reload_result = ast_module_reload(args->module_name);
  510. if (reload_result == AST_MODULE_RELOAD_NOT_FOUND) {
  511. ast_ari_response_error(
  512. response, 404, "Not Found",
  513. "Module could not be found");
  514. return;
  515. } else if (reload_result == AST_MODULE_RELOAD_ERROR) {
  516. ast_ari_response_error(
  517. response, 409, "Conflict",
  518. "An unknown error occurred while reloading the module");
  519. return;
  520. } else if (reload_result == AST_MODULE_RELOAD_IN_PROGRESS) {
  521. ast_ari_response_error(
  522. response, 409, "Conflict",
  523. "Another reload is currently in progress");
  524. return;
  525. } else if (reload_result == AST_MODULE_RELOAD_UNINITIALIZED) {
  526. ast_ari_response_error(
  527. response, 409, "Conflict",
  528. "Module has not been initialized");
  529. return;
  530. } else if (reload_result == AST_MODULE_RELOAD_NOT_IMPLEMENTED) {
  531. ast_ari_response_error(
  532. response, 409, "Conflict",
  533. "Module does not support reloading");
  534. return;
  535. } else if (reload_result == AST_MODULE_RELOAD_QUEUED) {
  536. ast_ari_response_accepted(response);
  537. return;
  538. }
  539. ast_ari_response_no_content(response);
  540. }
  541. void ast_ari_asterisk_ping(struct ast_variable *headers,
  542. struct ast_ari_asterisk_ping_args *args,
  543. struct ast_ari_response *response)
  544. {
  545. struct ast_json *json;
  546. char eid[20];
  547. ast_assert(response != NULL);
  548. json = ast_json_pack("{s: s, s: o, s: s}",
  549. "ping", "pong",
  550. "timestamp", ast_json_timeval(ast_tvnow(), NULL),
  551. "asterisk_id", ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)
  552. );
  553. ast_ari_response_ok(response, json);
  554. }
  555. /*!
  556. * \brief Process logger information and append to a json array
  557. * \param channel Resource logger channel name path
  558. * \param type Resource log type
  559. * \param status Resource log status
  560. * \param configuration Resource logger levels
  561. * \param log_data_list Resource array
  562. *
  563. * \retval -1 if no resource exists
  564. * \retval 0 if resource exists
  565. */
  566. static int process_log_list(const char *channel, const char *type,
  567. const char *status, const char *configuration, void *log_data_list)
  568. {
  569. struct ast_json *logger_info;
  570. logger_info = ast_json_pack("{s: s, s: s, s: s, s: s}",
  571. "channel", channel, "type", type, "status", status, "configuration",
  572. configuration);
  573. if (!logger_info) {
  574. return AST_LOGGER_FAILURE;
  575. }
  576. ast_json_array_append(log_data_list, logger_info);
  577. return AST_LOGGER_SUCCESS;
  578. }
  579. void ast_ari_asterisk_list_log_channels(struct ast_variable *headers,
  580. struct ast_ari_asterisk_list_log_channels_args *args,
  581. struct ast_ari_response *response)
  582. {
  583. struct ast_json *json;
  584. int res;
  585. json = ast_json_array_create();
  586. res = ast_logger_get_channels(&process_log_list, json);
  587. if (res == AST_LOGGER_FAILURE) {
  588. ast_ari_response_error(response, 500, "Internal Server Error",
  589. "Response body is not valid");
  590. ast_json_unref(json);
  591. return;
  592. } else if (res == AST_LOGGER_ALLOC_ERROR) {
  593. ast_ari_response_error(response, 500, "Internal Server Error",
  594. "Allocation Failed");
  595. ast_json_unref(json);
  596. return;
  597. }
  598. ast_ari_response_ok(response, json);
  599. }
  600. void ast_ari_asterisk_add_log(struct ast_variable *headers,
  601. struct ast_ari_asterisk_add_log_args *args,
  602. struct ast_ari_response *response)
  603. {
  604. int res;
  605. ast_assert(response != NULL);
  606. res = ast_logger_create_channel(args->log_channel_name, args->configuration);
  607. if (res == AST_LOGGER_DECLINE) {
  608. ast_ari_response_error(response, 400, "Bad Request",
  609. "Configuration levels are required");
  610. return;
  611. } else if (res == AST_LOGGER_FAILURE) {
  612. ast_ari_response_error(response, 409, "Conflict",
  613. "Log channel already exists");
  614. return;
  615. } else if (res == AST_LOGGER_ALLOC_ERROR) {
  616. ast_ari_response_error(response, 500, "Internal Server Error",
  617. "Allocation failed");
  618. return;
  619. }
  620. ast_ari_response_no_content(response);
  621. }
  622. void ast_ari_asterisk_rotate_log(struct ast_variable *headers,
  623. struct ast_ari_asterisk_rotate_log_args *args,
  624. struct ast_ari_response *response)
  625. {
  626. int res;
  627. ast_assert(response != NULL);
  628. res = ast_logger_rotate_channel(args->log_channel_name);
  629. if (res == AST_LOGGER_FAILURE) {
  630. ast_ari_response_error(
  631. response, 404, "Not Found",
  632. "Log channel does not exist");
  633. return;
  634. } else if (res == AST_LOGGER_ALLOC_ERROR) {
  635. ast_ari_response_error(
  636. response, 500, "Internal Server Error",
  637. "Allocation failed");
  638. return;
  639. }
  640. ast_ari_response_no_content(response);
  641. }
  642. void ast_ari_asterisk_delete_log(struct ast_variable *headers,
  643. struct ast_ari_asterisk_delete_log_args *args,
  644. struct ast_ari_response *response)
  645. {
  646. int res;
  647. ast_assert(response != NULL);
  648. res = ast_logger_remove_channel(args->log_channel_name);
  649. if (res == AST_LOGGER_FAILURE) {
  650. ast_ari_response_error(response, 404, "Not Found",
  651. "Log channel does not exist");
  652. return;
  653. } else if (res == AST_LOGGER_ALLOC_ERROR) {
  654. ast_ari_response_error(response, 500, "Internal Server Error",
  655. "Allocation failed");
  656. return;
  657. }
  658. ast_ari_response_no_content(response);
  659. }
  660. void ast_ari_asterisk_get_global_var(struct ast_variable *headers,
  661. struct ast_ari_asterisk_get_global_var_args *args,
  662. struct ast_ari_response *response)
  663. {
  664. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  665. RAII_VAR(struct ast_str *, tmp, NULL, ast_free);
  666. const char *value;
  667. ast_assert(response != NULL);
  668. if (ast_strlen_zero(args->variable)) {
  669. ast_ari_response_error(
  670. response, 400, "Bad Request",
  671. "Variable name is required");
  672. return;
  673. }
  674. tmp = ast_str_create(32);
  675. if (!tmp) {
  676. ast_ari_response_alloc_failed(response);
  677. return;
  678. }
  679. value = ast_str_retrieve_variable(&tmp, 0, NULL, NULL, args->variable);
  680. if (!(json = ast_json_pack("{s: s}", "value", S_OR(value, "")))) {
  681. ast_ari_response_alloc_failed(response);
  682. return;
  683. }
  684. ast_ari_response_ok(response, ast_json_ref(json));
  685. }
  686. void ast_ari_asterisk_set_global_var(struct ast_variable *headers,
  687. struct ast_ari_asterisk_set_global_var_args *args,
  688. struct ast_ari_response *response)
  689. {
  690. ast_assert(response != NULL);
  691. if (ast_strlen_zero(args->variable)) {
  692. ast_ari_response_error(
  693. response, 400, "Bad Request",
  694. "Variable name is required");
  695. return;
  696. }
  697. pbx_builtin_setvar_helper(NULL, args->variable, args->value);
  698. ast_ari_response_no_content(response);
  699. }