Search code examples
mongodbmongodb-querymongo-shell

How to get list of all the hosts connected to a mongodb cluster from cli


I have a mongodb cluster haveing 5 shards of 3 replica sets each , along with a replica set of config servers and few mongoses servers. Is there is a way from command line mongosh i could get list of all the hosts of this cluster ?

If i try sh.status() it will only show me the shard info not the hosts of mongoses or config servers


Solution

  • The mongos servers you can query with

    db.getSiblingDB('config').mongos.find({}, { _id: 1 })
    

    For shard and config servers, use db.adminCommand("getShardMap")

    db.adminCommand("getShardMap").map
    {
      shard_01: 'shard_01/d-mipmdb-sh1-01:27018,d-mipmdb-sh2-01:27018',
      shard_02: 'shard_02/d-mipmdb-sh1-02:27018,d-mipmdb-sh2-02:27018',
      shard_03: 'shard_03/d-mipmdb-sh1-03:27018,d-mipmdb-sh2-03:27018',
      shard_04: 'shard_04/d-mipmdb-sh1-04:27018,d-mipmdb-sh2-04:27018',
      config: 'configRepSet/d-mipmdb-cfg-01:27019,d-mipmdb-cfg-02:27019,d-mipmdb-cfg-03:27019'
    }
    

    However, it does not list any ARBITER. If you need to list also ARBITER then you have to connect to each shard and query the Replica Set configuration. Could be done like this:

    function getConnectionURL(uri) {
       const mongoURI = require("mongodb-uri");
       const uriObj = mongoURI.parse(db.getMongo()._connectionInfo.connectionString);
    
       let ret = { scheme: 'mongodb', options: { readPreference: 'primaryPreferred' } };
       if (uri.includes('/')) {
          ret.hosts = uri.split('/').pop().split(',').map(x => { let h = x.split(':'); return { host: h[0], port: h[1] } })
          ret.options.replicaSet = uri.split('/').shift();
       } else {
          ret.hosts = uri.split(',').map(x => { let h = x.split(':'); return { host: h[0], port: h[1] } })
       }
    
       for (let k of ['database', 'password', 'username'])
          if (uriObj[k] != undefined) ret[k] = uriObj[k];
    
       for (let k of ['tls', 'authSource', 'authMechanism', 'tlsCertificateKeyFile', 'tlsCAFile'])
          if (uriObj.options[k] != undefined) ret.options[k] = uriObj.options[k];
    
       if (ret.options.tlsCAFile == undefined && ret.options.tls == 'true') {
          const cmdLineOpts = db.serverCmdLineOpts().parsed;
          if (cmdLineOpts.net.tls != undefined && cmdLineOpts.net.tls.CAFile != undefined) {
             ret.options.tlsCAFile = cmdLineOpts.net.tls.CAFile;
          } else {
             ret.options.tlsCAFile = '/etc/ssl/certs/ca-bundle.crt';
          }
       }
    
       return mongoURI.format(ret);
    }
    
    
    const map = db.adminCommand("getShardMap").map;
    for (let rs of Object.keys(map)) {
       const replicaSet = Mongo(getConnectionURL(map[rs])).getDB("admin");
       print(replicaSet.adminCommand({ replSetGetConfig: 1 }).config.members.map(x => x.host));
    }
    

    Note, when you use Mongo(), then sh.status() does not work, you must use adminCommand({ replSetGetStatus: 1 }) which does the same.