dyn_conf.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #ifndef DYN_CONF_H
  3. #define DYN_CONF_H
  4. #include "../libnetdata.h"
  5. #define FUNCTION_NAME_GET_PLUGIN_CONFIG "get_plugin_config"
  6. #define FUNCTION_NAME_GET_PLUGIN_CONFIG_SCHEMA "get_plugin_config_schema"
  7. #define FUNCTION_NAME_GET_MODULE_CONFIG "get_module_config"
  8. #define FUNCTION_NAME_GET_MODULE_CONFIG_SCHEMA "get_module_config_schema"
  9. #define FUNCTION_NAME_GET_JOB_CONFIG "get_job_config"
  10. #define FUNCTION_NAME_GET_JOB_CONFIG_SCHEMA "get_job_config_schema"
  11. #define FUNCTION_NAME_SET_PLUGIN_CONFIG "set_plugin_config"
  12. #define FUNCTION_NAME_SET_MODULE_CONFIG "set_module_config"
  13. #define FUNCTION_NAME_SET_JOB_CONFIG "set_job_config"
  14. #define FUNCTION_NAME_DELETE_JOB "delete_job"
  15. #define DYNCFG_MAX_WORDS 5
  16. #define DYNCFG_VFNC_RET_CFG_ACCEPTED (1)
  17. enum module_type {
  18. MOD_TYPE_UNKNOWN = 0,
  19. MOD_TYPE_ARRAY,
  20. MOD_TYPE_SINGLE
  21. };
  22. static inline enum module_type str2_module_type(const char *type_name)
  23. {
  24. if (strcmp(type_name, "job_array") == 0)
  25. return MOD_TYPE_ARRAY;
  26. else if (strcmp(type_name, "single") == 0)
  27. return MOD_TYPE_SINGLE;
  28. return MOD_TYPE_UNKNOWN;
  29. }
  30. static inline const char *module_type2str(enum module_type type)
  31. {
  32. switch (type) {
  33. case MOD_TYPE_ARRAY:
  34. return "job_array";
  35. case MOD_TYPE_SINGLE:
  36. return "single";
  37. default:
  38. return "unknown";
  39. }
  40. }
  41. struct dyncfg_config {
  42. void *data;
  43. size_t data_size;
  44. };
  45. typedef struct dyncfg_config dyncfg_config_t;
  46. struct configurable_plugin;
  47. struct module;
  48. enum job_status {
  49. JOB_STATUS_UNKNOWN = 0, // State used until plugin reports first status
  50. JOB_STATUS_STOPPED,
  51. JOB_STATUS_RUNNING,
  52. JOB_STATUS_ERROR
  53. };
  54. static inline enum job_status str2job_state(const char *state_name) {
  55. if (strcmp(state_name, "stopped") == 0)
  56. return JOB_STATUS_STOPPED;
  57. else if (strcmp(state_name, "running") == 0)
  58. return JOB_STATUS_RUNNING;
  59. else if (strcmp(state_name, "error") == 0)
  60. return JOB_STATUS_ERROR;
  61. return JOB_STATUS_UNKNOWN;
  62. }
  63. const char *job_status2str(enum job_status status);
  64. enum set_config_result {
  65. SET_CONFIG_ACCEPTED = 0,
  66. SET_CONFIG_REJECTED,
  67. SET_CONFIG_DEFFER
  68. };
  69. typedef uint32_t dyncfg_job_flg_t;
  70. enum job_flags {
  71. JOB_FLG_PS_LOADED = 1 << 0, // PS abbr. Persistent Storage
  72. JOB_FLG_PLUGIN_PUSHED = 1 << 1, // got it from plugin (e.g. autodiscovered job)
  73. JOB_FLG_STREAMING_PUSHED = 1 << 2, // got it through streaming
  74. JOB_FLG_USER_CREATED = 1 << 3, // user created this job during agent runtime
  75. };
  76. enum job_type {
  77. JOB_TYPE_UNKNOWN = 0,
  78. JOB_TYPE_STOCK = 1,
  79. JOB_TYPE_USER = 2,
  80. JOB_TYPE_AUTODISCOVERED = 3,
  81. };
  82. static inline const char* job_type2str(enum job_type type)
  83. {
  84. switch (type) {
  85. case JOB_TYPE_STOCK:
  86. return "stock";
  87. case JOB_TYPE_USER:
  88. return "user";
  89. case JOB_TYPE_AUTODISCOVERED:
  90. return "autodiscovered";
  91. case JOB_TYPE_UNKNOWN:
  92. default:
  93. return "unknown";
  94. }
  95. }
  96. static inline enum job_type dyncfg_str2job_type(const char *type_name)
  97. {
  98. if (strcmp(type_name, "stock") == 0)
  99. return JOB_TYPE_STOCK;
  100. else if (strcmp(type_name, "user") == 0)
  101. return JOB_TYPE_USER;
  102. else if (strcmp(type_name, "autodiscovered") == 0)
  103. return JOB_TYPE_AUTODISCOVERED;
  104. error_report("Unknown job type: %s", type_name);
  105. return JOB_TYPE_UNKNOWN;
  106. }
  107. struct job
  108. {
  109. const char *name;
  110. enum job_type type;
  111. struct module *module;
  112. pthread_mutex_t lock;
  113. // lock protexts only fields below (which are modified during job existence)
  114. // others are static during lifetime of job
  115. int dirty; // this relates to rrdpush, true if parent has different data than us
  116. // state reported by plugin
  117. usec_t last_state_update;
  118. enum job_status status; // reported by plugin, enum as this has to be interpreted by UI
  119. int state; // code reported by plugin which can mean anything plugin wants
  120. char *reason; // reported by plugin, can be NULL (optional)
  121. dyncfg_job_flg_t flags;
  122. };
  123. struct module
  124. {
  125. pthread_mutex_t lock;
  126. char *name;
  127. enum module_type type;
  128. struct configurable_plugin *plugin;
  129. // module config
  130. enum set_config_result (*set_config_cb)(void *usr_ctx, const char *plugin_name, const char *module_name, dyncfg_config_t *cfg);
  131. dyncfg_config_t (*get_config_cb)(void *usr_ctx, const char *plugin_name, const char *module_name);
  132. dyncfg_config_t (*get_config_schema_cb)(void *usr_ctx, const char *plugin_name, const char *module_name);
  133. void *config_cb_usr_ctx;
  134. DICTIONARY *jobs;
  135. // jobs config
  136. dyncfg_config_t (*get_job_config_cb)(void *usr_ctx, const char *plugin_name, const char *module_name, const char *job_name);
  137. dyncfg_config_t (*get_job_config_schema_cb)(void *usr_ctx, const char *plugin_name, const char *module_name);
  138. enum set_config_result (*set_job_config_cb)(void *usr_ctx, const char *plugin_name, const char *module_name, const char *job_name, dyncfg_config_t *cfg);
  139. enum set_config_result (*delete_job_cb)(void *usr_ctx, const char *plugin_name, const char *module_name, const char *job_name);
  140. void *job_config_cb_usr_ctx;
  141. };
  142. struct configurable_plugin {
  143. pthread_mutex_t lock;
  144. char *name;
  145. DICTIONARY *modules;
  146. const char *schema;
  147. dyncfg_config_t (*get_config_cb)(void *usr_ctx, const char *plugin_name);
  148. dyncfg_config_t (*get_config_schema_cb)(void *usr_ctx, const char *plugin_name);
  149. enum set_config_result (*set_config_cb)(void *usr_ctx, const char *plugin_name, dyncfg_config_t *cfg);
  150. void *cb_usr_ctx; // context for all callbacks (split if needed in future)
  151. };
  152. // API to be used by plugins
  153. const DICTIONARY_ITEM *register_plugin(DICTIONARY *plugins_dict, struct configurable_plugin *plugin, bool localhost);
  154. void unregister_plugin(DICTIONARY *plugins_dict, const DICTIONARY_ITEM *plugin);
  155. int register_module(DICTIONARY *plugins_dict, struct configurable_plugin *plugin, struct module *module, bool localhost);
  156. int register_job(DICTIONARY *plugins_dict, const char *plugin_name, const char *module_name, const char *job_name, enum job_type job_type, dyncfg_job_flg_t flags, int ignore_existing);
  157. const DICTIONARY_ITEM *report_job_status_acq_lock(DICTIONARY *plugins_dict, const DICTIONARY_ITEM **plugin_acq_item, DICTIONARY **job_dict, const char *plugin_name, const char *module_name, const char *job_name, enum job_status status, int status_code, char *reason);
  158. void dyn_conf_store_config(const char *function, const char *payload, struct configurable_plugin *plugin);
  159. void unlink_job(const char *plugin_name, const char *module_name, const char *job_name);
  160. void delete_job(struct configurable_plugin *plugin, const char *module_name, const char *job_name);
  161. void delete_job_pname(DICTIONARY *plugins_dict, const char *plugin_name, const char *module_name, const char *job_name);
  162. // API to be used by the web server(s)
  163. json_object *get_list_of_plugins_json(DICTIONARY *plugins_dict);
  164. struct configurable_plugin *get_plugin_by_name(DICTIONARY *plugins_dict, const char *name);
  165. json_object *get_list_of_modules_json(struct configurable_plugin *plugin);
  166. struct module *get_module_by_name(struct configurable_plugin *plugin, const char *module_name);
  167. json_object *job2json(struct job *job);
  168. // helper struct to make interface between internal webserver and h2o same
  169. struct uni_http_response {
  170. int status;
  171. char *content;
  172. size_t content_length;
  173. HTTP_CONTENT_TYPE content_type;
  174. void (*content_free)(void *);
  175. };
  176. struct uni_http_response dyn_conf_process_http_request(DICTIONARY *plugins_dict, int method, const char *plugin, const char *module, const char *job_id, void *payload, size_t payload_size);
  177. // API to be used by main netdata process, initialization and destruction etc.
  178. int dyn_conf_init(void);
  179. void freez_dyncfg(void *ptr);
  180. #define dyncfg_dictionary_create() dictionary_create(DICT_OPTION_VALUE_LINK_DONT_CLONE)
  181. void plugin_del_cb(const DICTIONARY_ITEM *item, void *value, void *data);
  182. void *dyncfg_main(void *in);
  183. #define DYNCFG_FUNCTION_TYPE_REGULAR (1 << 0)
  184. #define DYNCFG_FUNCTION_TYPE_PAYLOAD (1 << 1)
  185. #define DYNCFG_FUNCTION_TYPE_GET (1 << 2)
  186. #define DYNCFG_FUNCTION_TYPE_SET (1 << 3)
  187. #define DYNCFG_FUNCTION_TYPE_DELETE (1 << 4)
  188. #define DYNCFG_FUNCTION_TYPE_ALL \
  189. (DYNCFG_FUNCTION_TYPE_REGULAR | DYNCFG_FUNCTION_TYPE_PAYLOAD | DYNCFG_FUNCTION_TYPE_GET | DYNCFG_FUNCTION_TYPE_SET | DYNCFG_FUNCTION_TYPE_DELETE)
  190. bool is_dyncfg_function(const char *function_name, uint8_t type);
  191. #endif //DYN_CONF_H