Uploaded image for project: 'Compass '
  1. Compass
  2. COMPASS-139

Add "test" connection

    • Type: Icon: Task Task
    • Resolution: Won't Fix
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Connectivity

      User Story

      "As a Compass user with commercial support, I want to easily copy and paste diagnostic info when a connection fails so that I can include it in the SFSC I open enabling faster resolution from MongoDB Support"

      Summary

      > Note @lucas: Updated with complete context per COMPASS-2848

      When customers are having problems connecting via Compass we can now provide a much better experience than instructing customers to enable debugging and open the devtools console (see CS-32525).

      Gathering Diagnostic Data

      mongodb-connection-model@5.0.0 added a new `status` event. These status events are propagated via mongodb-data-service. Status events are emitted while establishing a connection for each step in the process. Each step has an underlying with a human-readable message property and one property pending||error||complete||skipped.

      The implementation of these steps/checks can be found in mongodb-connection-model/lib/connect.js (line 170 at time of this writing).

      Steps Explained

      The possible values for a status event message are:

      • Validate Validate the user input against mongodb-connection-model's business logic
      • Load SSL files Checks that the SSL files specified by the user are readable (if specified)
      • Create SSH Tunnel Checks that SSH Tunnel can be successfully created and written to (if specified)
      • Connect to MongoDB Given all of the above, can we connect to MongoDB using the node.js driver?
      • List Databases Inactive. See below.

      Example Usage

      test: function(done) {
        var onTested = function(err) {
          if (err) {
            metrics.error(err);
            return done(err);
          }
      
          debug('test worked!');
          done(null, this);
        }.bind(this);
        var diagnosticMessages = [];
      
        var dataService = new DataService(this);
        debug('Testing connection to `%j`...', this.serialize());
        dataService.on('status', (evt) => {
          /**
           * Example status events:
           *
           * >>> { message: 'Validate', pending: true }
           * >>> { message: 'Validate', complete: true }
           * >>> { message: 'Load SSL files', pending: true }
           * >>> { message: 'Load SSL files', skipped: true, reason: 'The selected SSL mode does not need to load any files.' }
           * >>>  { message: 'Create SSH Tunnel', pending: true }
           * >>>  { message: 'Create SSH Tunnel', complete: true}
           * >>> { message: 'Connect to MongoDB', pending: true }
           * >>> { message: 'Connect to MongoDB', complete: true }
           * >>> { message: 'Connect to MongoDB', error: MongoError('Invalid or missing certificate', stack: 'Error: self signed certificate in certificate chain...') }
           */
           // TODO Write these as nice messages to populate the diagnostic info
        });
        dataService.connect(onTested);
        return this;
      }
      

      List Databases

      This is currently commented out in mongodb-connection-model and here is the primary reason: it's tricky to actually listDatabases(). The actual command requires the authenticated mongodb user to have escalated privileges. However, there is a workaround detailed in mongodb-data-service/lib/instance-detail-helper.js.

      This workaround leverages the server's connectionStatus and userInfo commands. It's complicated but very possible to list collections and databases without having underlying escalated privs. See the implementation in mongodb-data-service/lib/instance-detail-helper.js starting at roughly line 283.

      This underlying complexity would be mitigated by PM-544 (see comments there for more details).

      UX

      In the Compass connect window, when a connection fails, add a link to show "Diagnostic Info" which toggles textarea containing status event messages. Under the textarea, include a "copy diagnostic info" button which writes the contents of the textarea to the clipboard using electron's clipboard API.

      Prior Art

      RoboMongo

      See Robomongo RC8 blog post for more details.

      While in the area as this will be at least a minor release, please also refactor to split up the ssh-connection-options which appear to be unnecessarily coupled together as discovered on COMPASS-396:

      const opts = {
      // TODO: Would be nice to split this into connectOptions (passed to .connect()),
      // TODO: ... forwardOutOptions (i.e. srcAddr, dstPort, dstAddr) and
      // TODO: ... startLocalSSHServerOptions (e.g. localPort, localAddr)
        readyTimeout: 5000,
        forwardTimeout: 5000,
        keepaliveInterval: 5000,
        srcAddr: '127.0.0.1',    // OS should figure out an ephemeral srcPort
        dstPort: 27000,          // final mongod port
        dstAddr: '10.0.0.131',   // final mongod IP
        localPort: 29000,        // TODO: Choose this ephemeral port randomly
        localAddr: '127.0.0.1',
        host: '35.163.143.252',  // Jump box IP
        port: 22,
        username: 'ec2-user'
      };
      

        1. image-2018-11-01-16-03-41-398.png
          52 kB
          Massimiliano Marcon
        2. image-2018-11-01-16-04-48-403.png
          66 kB
          Massimiliano Marcon
        3. image-2018-11-01-16-05-28-821.png
          60 kB
          Massimiliano Marcon
        4. image-2018-11-01-16-09-07-440.png
          20 kB
          Massimiliano Marcon
        5. robomongo-connection-test-failed.png
          64 kB
          Lucas Hrabovsky

            Assignee:
            durran.jordan@mongodb.com Durran Jordan
            Reporter:
            sam.weaver Sam Weaver
            Votes:
            3 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: