- static void c_grpc_destroy_write_callback (void *ptr) {
- delete (CollectdClient *) ptr;
- }
-
- static int c_grpc_write(__attribute__((unused)) data_set_t const *ds,
- value_list_t const *vl,
- user_data_t *ud) {
- CollectdClient *c = (CollectdClient *) ud->data;
- return c->DispatchValues(vl);
- }
-
- static int c_grpc_config_listen(oconfig_item_t *ci)
- {
- if ((ci->values_num != 2)
- || (ci->values[0].type != OCONFIG_TYPE_STRING)
- || (ci->values[1].type != OCONFIG_TYPE_STRING)) {
- ERROR("grpc: The `%s` config option needs exactly "
- "two string argument (address and port).", ci->key);
- return -1;
- }
-
- auto listener = Listener();
- listener.addr = grpc::string(ci->values[0].value.string);
- listener.port = grpc::string(ci->values[1].value.string);
- listener.ssl = nullptr;
-
- auto ssl_opts = new(grpc::SslServerCredentialsOptions);
- grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp = {};
- bool use_ssl = false;
-
- for (int i = 0; i < ci->children_num; i++) {
- oconfig_item_t *child = ci->children + i;
-
- if (!strcasecmp("EnableSSL", child->key)) {
- if (cf_util_get_boolean(child, &use_ssl)) {
- ERROR("grpc: Option `%s` expects a boolean value",
- child->key);
- return -1;
- }
- }
- else if (!strcasecmp("SSLCACertificateFile", child->key)) {
- char *certs = NULL;
- if (cf_util_get_string(child, &certs)) {
- ERROR("grpc: Option `%s` expects a string value",
- child->key);
- return -1;
- }
- ssl_opts->pem_root_certs = read_file(certs);
- }
- else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
- char *key = NULL;
- if (cf_util_get_string(child, &key)) {
- ERROR("grpc: Option `%s` expects a string value",
- child->key);
- return -1;
- }
- pkcp.private_key = read_file(key);
- }
- else if (!strcasecmp("SSLCertificateFile", child->key)) {
- char *cert = NULL;
- if (cf_util_get_string(child, &cert)) {
- ERROR("grpc: Option `%s` expects a string value",
- child->key);
- return -1;
- }
- pkcp.cert_chain = read_file(cert);
- }
- else {
- WARNING("grpc: Option `%s` not allowed in <%s> block.",
- child->key, ci->key);
- }
- }
-
- ssl_opts->pem_key_cert_pairs.push_back(pkcp);
- if (use_ssl)
- listener.ssl = ssl_opts;
- else
- delete(ssl_opts);
-
- listeners.push_back(listener);
- return 0;
- } /* c_grpc_config_listen() */
-
- static int c_grpc_config_server(oconfig_item_t *ci)
- {
- if ((ci->values_num != 2)
- || (ci->values[0].type != OCONFIG_TYPE_STRING)
- || (ci->values[1].type != OCONFIG_TYPE_STRING)) {
- ERROR("grpc: The `%s` config option needs exactly "
- "two string argument (address and port).", ci->key);
- return -1;
- }
-
- grpc::SslCredentialsOptions ssl_opts;
- bool use_ssl = false;
-
- for (int i = 0; i < ci->children_num; i++) {
- oconfig_item_t *child = ci->children + i;
-
- if (!strcasecmp("EnableSSL", child->key)) {
- if (cf_util_get_boolean(child, &use_ssl)) {
- return -1;
- }
- }
- else if (!strcasecmp("SSLCACertificateFile", child->key)) {
- char *certs = NULL;
- if (cf_util_get_string(child, &certs)) {
- return -1;
- }
- ssl_opts.pem_root_certs = read_file(certs);
- }
- else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
- char *key = NULL;
- if (cf_util_get_string(child, &key)) {
- return -1;
- }
- ssl_opts.pem_private_key = read_file(key);
- }
- else if (!strcasecmp("SSLCertificateFile", child->key)) {
- char *cert = NULL;
- if (cf_util_get_string(child, &cert)) {
- return -1;
- }
- ssl_opts.pem_cert_chain = read_file(cert);
- }
- else {
- WARNING("grpc: Option `%s` not allowed in <%s> block.",
- child->key, ci->key);
- }
- }
-
- auto node = grpc::string(ci->values[0].value.string);
- auto service = grpc::string(ci->values[1].value.string);
- auto addr = node + ":" + service;
-
- CollectdClient *client;
- if (use_ssl) {
- auto channel_creds = grpc::SslCredentials(ssl_opts);
- auto channel = grpc::CreateChannel(addr, channel_creds);
- client = new CollectdClient(channel);
- } else {
- auto channel = grpc::CreateChannel(addr, grpc::InsecureChannelCredentials());
- client = new CollectdClient(channel);
- }
-
- auto callback_name = grpc::string("grpc/") + addr;
- user_data_t ud = {
- .data = client,
- .free_func = c_grpc_destroy_write_callback,
- };
-
- plugin_register_write (callback_name.c_str(), c_grpc_write, &ud);
- return 0;
- } /* c_grpc_config_server() */
-
- static int c_grpc_config(oconfig_item_t *ci)
- {
- int i;
-
- for (i = 0; i < ci->children_num; i++) {
- oconfig_item_t *child = ci->children + i;
-
- if (!strcasecmp("Listen", child->key)) {
- if (c_grpc_config_listen(child))
- return -1;
- }
- else if (!strcasecmp("Server", child->key)) {
- if (c_grpc_config_server(child))
- return -1;
- }
-
- else {
- WARNING("grpc: Option `%s` not allowed here.", child->key);
- }
- }
-
- return 0;
- } /* c_grpc_config() */
-
- static int c_grpc_init(void)
- {
- server = new CollectdServer();
- if (!server) {
- ERROR("grpc: Failed to create server");
- return -1;
- }
-
- server->Start();
- return 0;
- } /* c_grpc_init() */
-
- static int c_grpc_shutdown(void)
- {
- if (!server)
- return 0;
-
- server->Shutdown();
-
- delete server;
- server = nullptr;
-
- return 0;
- } /* c_grpc_shutdown() */
-
- void module_register(void)
- {
- plugin_register_complex_config("grpc", c_grpc_config);
- plugin_register_init("grpc", c_grpc_init);
- plugin_register_shutdown("grpc", c_grpc_shutdown);
- } /* module_register() */
-} /* extern "C" */