diff --git a/Documentation/Reference/MaxCtrl.md b/Documentation/Reference/MaxCtrl.md index 53f313e4f..d5effed0d 100644 --- a/Documentation/Reference/MaxCtrl.md +++ b/Documentation/Reference/MaxCtrl.md @@ -43,10 +43,17 @@ All command accept the following global options. -h, --hosts List of MaxScale hosts. The hosts must be in HOST:PORT format and each value must be separated by a comma. [string] [default: "localhost:8989"] - -s, --secure Enable HTTPS requests [boolean] [default: "false"] - -t, --timeout Request timeout in milliseconds [number] [default: "10000"] - -q, --quiet Silence all output [boolean] [default: "false"] - --tsv Print tab separated output [boolean] [default: "false"] + -t, --timeout Request timeout in milliseconds [number] [default: 10000] + -q, --quiet Silence all output [boolean] [default: false] + --tsv Print tab separated output [boolean] [default: false] + +HTTPS/TLS Options: + -s, --secure Enable HTTPS requests [boolean] [default: false] + --tls-key Path to TLS private key [string] + --tls-cert Path to TLS public certificate [string] + --tls-ca-cert Path to TLS CA certificate [string] + --tls-verify-server-cert Whether to verify server TLS certificates + [boolean] [default: true] Options: --version Show version number [boolean] diff --git a/maxctrl/lib/common.js b/maxctrl/lib/common.js index 8497749a7..bf786d6dc 100644 --- a/maxctrl/lib/common.js +++ b/maxctrl/lib/common.js @@ -16,6 +16,7 @@ var colors = require('colors/safe'); var Table = require('cli-table'); var consoleLib = require('console') var os = require('os') +var fs = require('fs') module.exports = function() { @@ -57,6 +58,13 @@ module.exports = function() { argv.reject(err) }) }, function(err) { + + if (err.error.cert) { + // TLS errors cause extremely verbose errors, truncate the certifiate details + // from the error output + delete err.error.cert + } + // One of the HTTP request pings to the cluster failed, log the error argv.reject(JSON.stringify(err.error, null, 4)) }) @@ -181,6 +189,31 @@ module.exports = function() { return Promise.resolve(colors.green('OK')) } + + this.setTlsCerts = function(args) { + args.agentOptions = {} + if (this.argv['tls-key']) { + args.agentOptions.key = fs.readFileSync(this.argv['tls-key']) + } + + if (this.argv['tls-cert']) { + args.agentOptions.cert = fs.readFileSync(this.argv['tls-cert']) + } + + if (this.argv['tls-ca-cert']) { + args.agentOptions.ca = fs.readFileSync(this.argv['tls-ca-cert']) + } + + if (this.argv['tls-passphrase']) { + args.agentOptions.passphrase = this.argv['tls-passphrase'] + } + + if (!this.argv['tls-verify-server-cert']) { + args.agentOptions.checkServerIdentity = function() { + } + } + } + // Helper for executing requests and handling their responses, returns a // promise that is fulfilled when all requests successfully complete. The // promise is rejected if any of the requests fails. @@ -189,6 +222,7 @@ module.exports = function() { args.uri = getUri(host, this.argv.secure, resource) args.json = true args.timeout = this.argv.timeout + setTlsCerts(args) return request(args) .then(function(res) { @@ -275,7 +309,11 @@ function pingCluster(hosts) { var promises = [] hosts.forEach(function(i) { - promises.push(request(getUri(i, this.argv.secure, ''))) + args = {} + args.uri = getUri(i, this.argv.secure, '') + args.json = true + setTlsCerts(args) + promises.push(request(args)) }) return Promise.all(promises) diff --git a/maxctrl/lib/core.js b/maxctrl/lib/core.js index 7a3c34ee5..a386c9642 100644 --- a/maxctrl/lib/core.js +++ b/maxctrl/lib/core.js @@ -21,7 +21,7 @@ program .strict() .exitProcess(false) .showHelpOnFail(false) - .group(['u', 'p', 'h', 's', 't', 'q', 'tsv'], 'Global Options:') + .group(['u', 'p', 'h', 't', 'q', 'tsv'], 'Global Options:') .option('u', { alias:'user', global: true, @@ -42,27 +42,45 @@ program default: 'localhost:8989', type: 'string' }) - .option('s', { - alias: 'secure', - describe: 'Enable HTTPS requests', - default: 'false', - type: 'boolean' - }) .option('t', { alias: 'timeout', describe: 'Request timeout in milliseconds', - default: '10000', + default: 10000, type: 'number' }) .option('q', { alias: 'quiet', describe: 'Silence all output', - default: 'false', + default: false, type: 'boolean' }) .option('tsv', { describe: 'Print tab separated output', - default: 'false', + default: false, + type: 'boolean' + }) + .group(['s', 'tls-key', 'tls-cert', 'tls-ca-cert', 'tls-verify-server-cert'], 'HTTPS/TLS Options:') + .option('s', { + alias: 'secure', + describe: 'Enable HTTPS requests', + default: false, + type: 'boolean' + }) + .option('tls-key', { + describe: 'Path to TLS private key', + type: 'string' + }) + .option('tls-cert', { + describe: 'Path to TLS public certificate', + type: 'string' + }) + .option('tls-ca-cert', { + describe: 'Path to TLS CA certificate', + type: 'string' + }) + .option('tls-verify-server-cert', { + describe: 'Whether to verify server TLS certificates', + default: true, type: 'boolean' })