<p>I'm looking to automate the process of setting up a MongoDb replica set via a sidecar when using Docker and Kubernetes.</p>

<p><strong>The above setup isn't terribly important</strong>, what it boils down to is that I need to be able to call the mongo replica set commands (e.g. <code>rs.initiate()</code>, <code>rs.add('anotherserver')</code>, <code>rs.conf()</code>, <code>rs.reconfig()</code>, etc) from a node.js application. </p>

<p>Note: it doesn't have to be from a node application, if someone knows of another way of getting the same thing done, please share your thoughts.</p>

<p><strong>UPDATE:</strong> I was able to get this working and have made the sidecar open source for others to use.</p>

<ul>
<li><a href="https://github.com/leportlabs/mongo-k8s-sidecar" rel="noreferrer">https://github.com/leportlabs/mongo-k8s-sidecar</a></li>
<li><a href="https://registry.hub.docker.com/u/leportlabs/mongo-k8s-sidecar" rel="noreferrer">https://registry.hub.docker.com/u/leportlabs/mongo-k8s-sidecar</a></li>
</ul>

<h2>How are the replica set admin helpers implemented?</h2>

<p>The <a href="http://docs.mongodb.org/manual/reference/method/js-replication/" rel="noreferrer"><code>rs.*</code> replica set admin helpers</a> in the <code>mongo</code> shell are wrappers for MongoDB commands which you can send from any driver.</p>

<p>You can see which command(s) each shell helper wraps by referring to the MongoDB documentation:</p>

<ul>
<li><a href="http://docs.mongodb.org/manual/reference/method/rs.initiate/" rel="noreferrer"><code>rs.initiate()</code></a> provides a wrapper around the <a href="http://docs.mongodb.org/manual/reference/command/replSetInitiate/" rel="noreferrer"><code>replSetInitiate</code></a> database command.</li>
<li><a href="http://docs.mongodb.org/manual/reference/method/rs.add/" rel="noreferrer"><code>rs.add()</code></a> provides a wrapper around some of the functionality of the <a href="http://docs.mongodb.org/manual/reference/command/replSetReconfig/" rel="noreferrer"><code>replSetReconfig</code></a> database command and the corresponding mongo shell helper <code>rs.reconfig()</code>.</li>
<li><a href="http://docs.mongodb.org/manual/reference/method/rs.conf/" rel="noreferrer"><code>rs.conf()</code></a> wraps the <a href="http://docs.mongodb.org/manual/reference/method/rs.conf/" rel="noreferrer"><code>replSetGetConfig</code></a> database command.</li>
</ul>

<p>Note that the <code>mongo</code> shell helpers may do some extra validation or manipulation of configs as they are intended to be used via the interactive <code>mongo</code> shell.</p>

<p>You can confirm how any of the shell helpers are implemented by invoking the command in the shell without trailing parentheses, eg:</p>

<pre><code>&gt; rs.initiate
function (c) { return db._adminCommand({ replSetInitiate: c }); }
</code></pre>

<h3>Calling replica set database commands from Node.js</h3>

<p>The equivalent logic can be implemented via the Node.js driver API using <a href="http://mongodb.github.io/node-mongodb-native/2.0/api/Admin.html#command" rel="noreferrer"><code>command()</code></a>:</p>

<pre><code>// Rough equivalent of rs.initiate()
var MongoClient = require('mongodb').MongoClient;

MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {

  // Use the admin database for commands
  var adminDb = db.admin();

  // Default replica set conf
  var conf = {};

  adminDb.command({replSetInitiate: conf}, function(err, info) {
     console.log(info);
  });
});
</code></pre>

<blockquote>
  <p>Note: it doesn't have to be from a node application, if someone knows of another way of getting the same thing done, please share your thoughts.</p>
</blockquote>

<p>Rather than reimplementing the replica set helpers in Node.js, you could invoke a <code>mongo</code> shell with the <code>--eval</code> command to run the shell helper (tip: include <code>--quiet</code> to suppress unnecessary messages).</p>

<p>For example, calling from your Node app:</p>

<pre><code>var exec = require('child_process').exec;
var rsAdmin = exec('mongo --eval "var res = rs.initiate(); printjson(res)" --quiet', function (error, stdout, stderr) {
   // output is in stdout
   console.log(stdout);
});
</code></pre>
