netcmd plugin: Added a first version of a control socket plugin.
[collectd.git] / src / write_mongodb.c
index c7b7682..24151ce 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/write_mongodb.c
- * Copyright (C) 2010-2012  Florian Forster
+ * Copyright (C) 2010-2013  Florian Forster
  * Copyright (C) 2010       Akkarit Sangpetch
  * Copyright (C) 2012       Chris Lundquist
  *
@@ -23,7 +23,7 @@
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Florian Forster <ff at octo.it>
+ *   Florian Forster <octo at collectd.org>
  *   Akkarit Sangpetch <asangpet at andrew.cmu.edu>
  *   Chris Lundquist <clundquist at bluebox.net>
  **/
 #endif
 #include <mongo.h>
 
+#if (MONGO_MAJOR == 0) && (MONGO_MINOR < 8)
+# define bson_alloc()    bson_create()
+# define bson_dealloc(b) bson_dispose(b)
+#endif
+
 struct wm_node_s
 {
   char name[DATA_MAX_NAME_LEN];
@@ -51,6 +56,11 @@ struct wm_node_s
   int port;
   int timeout;
 
+  /* Authentication information */
+  char *db;
+  char *user;
+  char *passwd;
+
   _Bool store_rates;
 
   mongo conn[1];
@@ -69,7 +79,7 @@ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */
   gauge_t *rates;
   int i;
 
-  ret = bson_create ();
+  ret = bson_alloc (); /* matched by bson_dealloc() */
   if (ret == NULL)
   {
     ERROR ("write_mongodb plugin: bson_create failed.");
@@ -90,7 +100,7 @@ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */
     rates = NULL;
   }
 
-  bson_init (ret);
+  bson_init (ret); /* matched by bson_destroy() */
   bson_append_date (ret, "time", (bson_date_t) CDTIME_T_TO_MS (vl->time));
   bson_append_string (ret, "host", vl->host);
   bson_append_string (ret, "plugin", vl->plugin);
@@ -183,6 +193,23 @@ static int wm_write (const data_set_t *ds, /* {{{ */
       return (-1);
     }
 
+    if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL))
+    {
+      status = mongo_cmd_authenticate (node->conn,
+          node->db, node->user, node->passwd);
+      if (status != MONGO_OK)
+      {
+        ERROR ("write_mongodb plugin: Authenticating to [%s]%i for database "
+            "\"%s\" as user \"%s\" failed.",
+          (node->host != NULL) ? node->host : "localhost",
+          (node->port != 0) ? node->port : MONGO_DEFAULT_PORT,
+          node->db, node->user);
+        mongo_destroy (node->conn);
+        pthread_mutex_unlock (&node->lock);
+        return (-1);
+      }
+    }
+
     if (node->timeout > 0) {
       status = mongo_set_op_timeout (node->conn, node->timeout);
       if (status != MONGO_OK) {
@@ -203,13 +230,14 @@ static int wm_write (const data_set_t *ds, /* {{{ */
     status = mongo_insert (node->conn, collection_name, bson_record);
   #endif
 
-  if(status != MONGO_OK)
+  if (status != MONGO_OK)
   {
     ERROR ( "write_mongodb plugin: error inserting record: %d", node->conn->err);
     if (node->conn->err != MONGO_BSON_INVALID)
       ERROR ("write_mongodb plugin: %s", node->conn->errstr);
-    else if (bson_record->err)
-      ERROR ("write_mongodb plugin: %s", bson_record->errstr);
+    else
+      ERROR ("write_mongodb plugin: Invalid BSON structure, error = %#x",
+          (unsigned int) bson_record->err);
 
     /* Disconnect except on data errors. */
     if ((node->conn->err != MONGO_BSON_INVALID)
@@ -220,7 +248,8 @@ static int wm_write (const data_set_t *ds, /* {{{ */
   pthread_mutex_unlock (&node->lock);
 
   /* free our resource as not to leak memory */
-  bson_dispose (bson_record);
+  bson_destroy (bson_record); /* matches bson_init() */
+  bson_dealloc (bson_record); /* matches bson_alloc() */
 
   return (0);
 } /* }}} int wm_write */
@@ -281,6 +310,12 @@ static int wm_config_node (oconfig_item_t *ci) /* {{{ */
       status = cf_util_get_int (child, &node->timeout);
     else if (strcasecmp ("StoreRates", child->key) == 0)
       status = cf_util_get_boolean (child, &node->store_rates);
+    else if (strcasecmp ("Database", child->key) == 0)
+      status = cf_util_get_string (child, &node->db);
+    else if (strcasecmp ("User", child->key) == 0)
+      status = cf_util_get_string (child, &node->user);
+    else if (strcasecmp ("Password", child->key) == 0)
+      status = cf_util_get_string (child, &node->passwd);
     else
       WARNING ("write_mongodb plugin: Ignoring unknown config option \"%s\".",
           child->key);
@@ -289,6 +324,20 @@ static int wm_config_node (oconfig_item_t *ci) /* {{{ */
       break;
   } /* for (i = 0; i < ci->children_num; i++) */
 
+  if ((node->db != NULL) || (node->user != NULL) || (node->passwd != NULL))
+  {
+    if ((node->db == NULL) || (node->user == NULL) || (node->passwd == NULL))
+    {
+      WARNING ("write_mongodb plugin: Authentication requires the "
+          "\"Database\", \"User\" and \"Password\" options to be specified, "
+          "but at last one of them is missing. Authentication will NOT be "
+          "used.");
+      sfree (node->db);
+      sfree (node->user);
+      sfree (node->passwd);
+    }
+  }
+
   if (status == 0)
   {
     char cb_name[DATA_MAX_NAME_LEN];