@heroku-cli/plugin-ps-exec
Version:
Heroku Exec CLI
68 lines (56 loc) • 2.33 kB
JavaScript
const cli = require('@heroku/heroku-cli-util')
const exec = require('@heroku-cli/heroku-exec-util');
const co = require('co');
const socks = require('@heroku/socksv5')
var net = require("net");
module.exports = function(topic, command) {
return {
topic: topic,
command: command,
description: 'Forward traffic on a local port to a dyno',
help: `Provide a port or comma-separated list of ports to forward.
For example, "4000,9000:9001" will forward port 4000 to port 4000 and
port 9000 to port 9001.
Example:
$ heroku ps:forward 8080 --app murmuring-headland-14719`,
args: [{name: 'port', optional: false}],
flags: [
{ name: 'dyno', char: 'd', hasValue: true, description: 'specify the dyno to connect to' },
{ name: 'localPort', char: 'p', hasValue: true, hidden: true, description: 'the local port to use' } ],
needsApp: true,
needsAuth: true,
run: cli.command(co.wrap(run))
}
};
function * run(context, heroku) {
yield exec.initFeature(context, heroku, 'forward', function *(configVars) {
const portMappings = context.args.port.split(',').map(function(portMapping) {
const ports = portMapping.split(':')
// this will error out if localPort is used with multiple ports, but
// that's ok because localPort is only here for backwards compat
return [ports[0], ports[1] || context.flags.localPort || ports[0]]
})
yield exec.createSocksProxy(context, heroku, configVars, function(dynoIp, dynoName, socksPort) {
portMappings.forEach(function(portMapping) {
const localPort = portMapping[0]
const remotePort = portMapping[1]
cli.log(`Listening on ${cli.color.white.bold(localPort)} and forwarding to ${cli.color.white.bold(`${dynoName}:${remotePort}`)}`)
net.createServer(function(connIn) {
socks.connect({
host: '0.0.0.0',
port: remotePort,
proxyHost: 'localhost',
proxyPort: socksPort,
auths: [ socks.auth.None() ]
}, function(socket) {
connIn.pipe(socket);
socket.pipe(connIn);
});
}).listen(localPort);
})
cli.log(`Use ${cli.color.magenta('CTRL+C')} to stop port forwarding`)
});
});
return new Promise(resolve => {})
}
;