ExportXMLWordPrintableJSON

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

      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
          image-2018-11-01-16-03-41-398.png
          52 kB
        2. image-2018-11-01-16-04-48-403.png
          image-2018-11-01-16-04-48-403.png
          66 kB
        3. image-2018-11-01-16-05-28-821.png
          image-2018-11-01-16-05-28-821.png
          60 kB
        4. image-2018-11-01-16-09-07-440.png
          image-2018-11-01-16-09-07-440.png
          20 kB
        5. robomongo-connection-test-failed.png
          robomongo-connection-test-failed.png
          64 kB

            Assignee:
            Durran Jordan (Inactive)
            Reporter:
            Sam Weaver (Inactive)
            Votes:
            3 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: