|  | import * as utils from './utils.js'; | 
|  | import log from 'npmlog'; | 
|  | import Wreck from 'wreck'; | 
|  | import Promise from 'bluebird'; | 
|  | import prettyjson from 'prettyjson'; | 
|  | import nmo from './nmo.js'; | 
|  | import isonline from './isonline.js'; | 
|  | import { getClusterUrls } from './utils.js'; | 
|  |  | 
|  | export function cli (cmd, cluster, section, key, value) { | 
|  | return new Promise((resolve, reject) => { | 
|  |  | 
|  | if (!cmd || !cluster || !exports[cmd]) { | 
|  | const msg = [ | 
|  | 'Usage:', | 
|  | '', | 
|  | 'nmo couch-config get <cluster> [<section>] [--json]', | 
|  | 'nmo config-config set <cluster> <section>, <key>, <value>' | 
|  | ].join('\n'); | 
|  |  | 
|  | const err = new Error(msg); | 
|  | err.type = 'EUSAGE'; | 
|  | return reject(err); | 
|  | } | 
|  |  | 
|  | exports[cmd].apply(exports[cmd], [cluster, getClusterNodes(cluster), section, key, value]) | 
|  | .then(resolve) | 
|  | .catch(reject); | 
|  | }); | 
|  | } | 
|  |  | 
|  | export function getClusterNodes (clusterName) { | 
|  | const nodes = nmo.config.get(clusterName); | 
|  | if (!nodes) { | 
|  | const err = new Error('Cluster does not exist'); | 
|  | err.type = 'EUSAGE'; | 
|  | throw err; | 
|  | } | 
|  |  | 
|  | return nodes; | 
|  | } | 
|  |  | 
|  | export function get (cluster, nodes, section) { | 
|  | const promise = Promise.reduce(Object.keys(nodes), (obj, node) => { | 
|  | const url = buildConfigUrl(node, nodes[node], section); | 
|  | return getConfig(node, url).then(({node, config}) => { | 
|  | obj[node] = config; | 
|  | return obj; | 
|  | }); | 
|  | }, {}); | 
|  |  | 
|  | promise.then((nodeConfigs) => { | 
|  | const jsonOut = nmo.config.get('json'); | 
|  |  | 
|  | if (jsonOut) { | 
|  | console.log(nodeConfigs); | 
|  | return nodeConfigs; | 
|  | } | 
|  |  | 
|  | Object.keys(nodeConfigs).forEach(node => { | 
|  | console.log('NODE:', node); | 
|  | console.log(prettyjson.render(nodeConfigs[node], {})); | 
|  | }); | 
|  | }); | 
|  |  | 
|  | return promise; | 
|  | } | 
|  |  | 
|  | export function set(cluster, nodes, section, key, value) { | 
|  | const urls = getClusterUrls(cluster); | 
|  | return isonline.apply(isonline, urls).then(results => { | 
|  | const offline = Object.keys(results).filter(node => { | 
|  | if (!results[node]) { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | return false; | 
|  | }); | 
|  |  | 
|  | if (offline.length > 0) { | 
|  | const msg = offline.map(node => 'Node ' + offline + ' is offline.').join(''); | 
|  | const err = new Error(msg); | 
|  | err.type = 'EUSAGE'; | 
|  | throw err; | 
|  | } | 
|  |  | 
|  | const promises = Object.keys(nodes).map(node => { | 
|  | return setConfig(node, buildConfigUrl(node, nodes[node], section, key), value); | 
|  | }); | 
|  |  | 
|  | const allPromise = Promise.all(promises); | 
|  | allPromise | 
|  | .then((resp) => { | 
|  | console.log(prettyjson.render(resp)); | 
|  | }) | 
|  | .catch((err) => { | 
|  | throw err; | 
|  | }); | 
|  |  | 
|  | return allPromise; | 
|  | }); | 
|  | } | 
|  |  | 
|  | export function setConfig (node, url, value) { | 
|  | return new Promise((resolve, reject) => { | 
|  | let er = utils.validUrl(url); | 
|  |  | 
|  | if (er) { | 
|  | er.type = 'EUSAGE'; | 
|  | return reject(er); | 
|  | } | 
|  | const cleanedUrl = utils.removeUsernamePw(url); | 
|  | log.http('request', 'PUT', cleanedUrl); | 
|  |  | 
|  | Wreck.put(url, {payload: JSON.stringify(value)}, (err, res, payload) => { | 
|  | if (err) { | 
|  | const error = new Error('Error on set config for node ' + node + ' ' + err); | 
|  | error.type = 'EUSAGE'; | 
|  | return reject(error); | 
|  | } | 
|  |  | 
|  | log.http(res.statusCode, cleanedUrl); | 
|  | resolve({ | 
|  | node: node, | 
|  | oldvalue: JSON.parse(payload), | 
|  | newvalue: value | 
|  | }); | 
|  | }); | 
|  | }); | 
|  | } | 
|  |  | 
|  | export function buildConfigUrl (node, url, section, key) { | 
|  | let configUrl = url + '/_node/' + node + '/_config'; | 
|  |  | 
|  | if (section) { | 
|  | configUrl += '/' + section; | 
|  | } | 
|  |  | 
|  | if (key) { | 
|  | configUrl += '/' + key; | 
|  | } | 
|  |  | 
|  | return configUrl; | 
|  | } | 
|  |  | 
|  | export function getConfig (node, url) { | 
|  | return new Promise((resolve, reject) => { | 
|  | let er = utils.validUrl(url); | 
|  |  | 
|  | if (er) { | 
|  | er.type = 'EUSAGE'; | 
|  | return reject(er); | 
|  | } | 
|  | const cleanedUrl = utils.removeUsernamePw(url); | 
|  | log.http('request', 'GET', cleanedUrl); | 
|  |  | 
|  | Wreck.get(url, (err, res, payload) => { | 
|  | if (err) { | 
|  | if (err.code === 'ECONNREFUSED' || err.code === 'ENOTFOUND') { | 
|  | const noNodeErr = new Error('Could not find node ' + node + | 
|  | ' this could mean the node is down.'); | 
|  | noNodeErr.type = 'EUSAGE'; | 
|  | return reject(noNodeErr); | 
|  | } | 
|  |  | 
|  | err.type = 'EUSAGE'; | 
|  | return reject(err); | 
|  | } | 
|  |  | 
|  | log.http(res.statusCode, cleanedUrl); | 
|  | resolve({node: node, config: JSON.parse(payload)}); | 
|  | }); | 
|  | }); | 
|  | } |