
The REST API tests are now located under the maxctrl directory. This allows both tests to use the same framework for testing.
215 lines
6.2 KiB
JavaScript
215 lines
6.2 KiB
JavaScript
/*
|
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
|
*
|
|
* Use of this software is governed by the Business Source License included
|
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
|
*
|
|
* Change Date: 2020-01-01
|
|
*
|
|
* On the date above, in accordance with the Business Source License, use
|
|
* of this software will be governed by version 2 or later of the General
|
|
* Public License.
|
|
*/
|
|
|
|
var request = require('request');
|
|
var colors = require('colors/safe');
|
|
var Table = require('cli-table');
|
|
|
|
module.exports = function() {
|
|
|
|
this._ = require('lodash-getpath')
|
|
// Common options for all commands
|
|
this.program = require('yargs');
|
|
|
|
// Request a resource collection and format it as a table
|
|
this.getCollection = function (resource, fields) {
|
|
|
|
doRequest(resource, function(res) {
|
|
|
|
var header = []
|
|
|
|
fields.forEach(function(i) {
|
|
header.push(Object.keys(i))
|
|
})
|
|
|
|
var table = getTable(header)
|
|
|
|
res.data.forEach(function(i) {
|
|
row = []
|
|
|
|
fields.forEach(function(p) {
|
|
var v = _.getPath(i, p[Object.keys(p)[0]], '')
|
|
|
|
if (Array.isArray(v)) {
|
|
v = v.join(', ')
|
|
}
|
|
row.push(v)
|
|
})
|
|
|
|
table.push(row)
|
|
})
|
|
|
|
console.log(table.toString())
|
|
})
|
|
}
|
|
|
|
// Request a part of a resource as a collection
|
|
this.getSubCollection = function (resource, subres, fields) {
|
|
|
|
doRequest(resource, function(res) {
|
|
|
|
var header = []
|
|
|
|
fields.forEach(function(i) {
|
|
header.push(Object.keys(i))
|
|
})
|
|
|
|
var table = getTable(header)
|
|
|
|
_.getPath(res.data, subres, []).forEach(function(i) {
|
|
row = []
|
|
|
|
fields.forEach(function(p) {
|
|
var v = _.getPath(i, p[Object.keys(p)[0]], '')
|
|
|
|
if (Array.isArray(v) && typeof(v[0]) != 'object') {
|
|
v = v.join(', ')
|
|
} else if (typeof(v) == 'object') {
|
|
v = JSON.stringify(v, null, 4)
|
|
}
|
|
row.push(v)
|
|
})
|
|
|
|
table.push(row)
|
|
})
|
|
|
|
console.log(table.toString())
|
|
})
|
|
}
|
|
|
|
// Request a single resource and format it as a key-value list
|
|
this.getResource = function (resource, fields) {
|
|
|
|
doRequest(resource, function(res) {
|
|
var table = getList()
|
|
|
|
fields.forEach(function(i) {
|
|
var k = Object.keys(i)[0]
|
|
var path = i[k]
|
|
var v = _.getPath(res.data, path, '')
|
|
|
|
if (Array.isArray(v) && typeof(v[0]) != 'object') {
|
|
v = v.join(', ')
|
|
} else if (typeof(v) == 'object') {
|
|
v = JSON.stringify(v, null, 4)
|
|
}
|
|
|
|
var o = {}
|
|
o[k] = v
|
|
table.push(o)
|
|
})
|
|
|
|
console.log(table.toString())
|
|
})
|
|
}
|
|
|
|
// Helper for converting endpoints to acutal URLs
|
|
this.getUri = function(host, endpoint) {
|
|
var base = 'http://'
|
|
var argv = this.program.argv
|
|
|
|
if (argv.secure) {
|
|
base = 'https://'
|
|
}
|
|
|
|
return base + argv.user + ':' + argv.password + '@' + host + '/v1/' + endpoint
|
|
}
|
|
|
|
// Helper for executing requests and handling their responses
|
|
this.doRequest = function(resource, cb, obj) {
|
|
pingCluster()
|
|
.then(function() {
|
|
var argv = this.program.argv
|
|
argv.hosts.forEach(function(host) {
|
|
args = obj || {}
|
|
args.uri = getUri(host, resource)
|
|
args.json = true
|
|
args.timeout = argv.timeout
|
|
|
|
request(args, function(err, resp, res) {
|
|
if (err) {
|
|
// Failed to request
|
|
console.log(colors.yellow(host) + ':')
|
|
logError(JSON.stringify(err, null, 4))
|
|
} else if (resp.statusCode == 200 && cb) {
|
|
// Request OK, returns data
|
|
console.log(colors.yellow(host) + ':')
|
|
cb(res)
|
|
} else if (resp.statusCode == 204) {
|
|
// Request OK, no data
|
|
console.log(colors.yellow(host) + ': ' + colors.green('OK'))
|
|
} else {
|
|
// Unexpected return code, probably an error
|
|
var errstr = resp.statusCode + ' ' + resp.statusMessage
|
|
if (res) {
|
|
errstr += ' ' + JSON.stringify(res, null, 4)
|
|
}
|
|
console.log(colors.yellow(host) + ':')
|
|
logError(errstr)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
this.updateValue = function(resource, key, value) {
|
|
var body = {}
|
|
_.set(body, key, value)
|
|
doRequest(resource, null, { method: 'PATCH', body: body })
|
|
}
|
|
|
|
this.logError = function(err) {
|
|
console.log(colors.red('Error:'), err)
|
|
}
|
|
}
|
|
|
|
function getList() {
|
|
return new Table({ style: { head: ['cyan'] } })
|
|
}
|
|
|
|
// Creates a table-like array for output. The parameter is an array of header names
|
|
function getTable(headobj) {
|
|
|
|
for (i = 0; i < headobj.length; i++) {
|
|
headobj[i] = colors.cyan(headobj[i])
|
|
}
|
|
|
|
return new Table({
|
|
head: headobj
|
|
})
|
|
}
|
|
|
|
function pingMaxScale(host) {
|
|
return new Promise(function(resolve, reject) {
|
|
request('http://' + host + '/v1', function(err, resp, res) {
|
|
if (err) {
|
|
reject(err)
|
|
} else if (resp.statusCode != 200) {
|
|
reject(resp.statusCode + ' ' + resp.statusMessage)
|
|
} else {
|
|
resolve()
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
function pingCluster() {
|
|
var promises = []
|
|
|
|
this.program.argv.hosts.forEach(function(i) {
|
|
promises.push(pingMaxScale(i))
|
|
})
|
|
|
|
return Promise.all(promises)
|
|
}
|