Guest User

Untitled

a guest
Jan 10th, 2019
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.41 KB | None | 0 0
  1. 'use strict';
  2.  
  3. import {createAction} from 'Utils';
  4. import {Client} from 'ssh2';
  5. import net from 'net';
  6. import Redis from 'ioredis';
  7.  
  8. function getIndex(getState) {
  9. const {activeInstanceKey, instances} = getState()
  10. return instances.findIndex(instance => instance.get('key') === activeInstanceKey)
  11. }
  12.  
  13. export const updateConnectStatus = createAction('UPDATE_CONNECT_STATUS', status => ({getState, next}) => {
  14. next({status, index: getIndex(getState)})
  15. })
  16.  
  17. export const disconnect = createAction('DISCONNECT', () => ({getState, next}) => {
  18. next({index: getIndex(getState)})
  19. })
  20.  
  21. export const connectToRedis = createAction('CONNECT', config => ({getState, dispatch, next}) => {
  22. let sshErrorThrown = false
  23. let redisErrorMessage
  24.  
  25. if (config.ssh) {
  26. dispatch(updateConnectStatus('SSH connecting...'))
  27.  
  28. const conn = new Client();
  29. conn.on('ready', () => {
  30. const server = net.createServer(function (sock) {
  31. conn.forwardOut(sock.remoteAddress, sock.remotePort, config.host, config.port, (err, stream) => {
  32. if (err) {
  33. sock.end()
  34. } else {
  35. sock.pipe(stream).pipe(sock)
  36. }
  37. })
  38. }).listen(0, function () {
  39. handleRedis(config, { host: '127.0.0.1', port: server.address().port })
  40. })
  41. }).on('error', err => {
  42. sshErrorThrown = true;
  43. dispatch(disconnect());
  44. alert(`SSH Error: ${err.message}`);
  45. })
  46.  
  47. try {
  48. const connectionConfig = {
  49. host: config.sshHost,
  50. port: config.sshPort || 22,
  51. username: config.sshUser
  52. }
  53. if (config.sshKey) {
  54. conn.connect(Object.assign(connectionConfig, {
  55. privateKey: config.sshKey,
  56. passphrase: config.sshKeyPassphrase
  57. }))
  58. } else {
  59. conn.connect(Object.assign(connectionConfig, {
  60. password: config.sshPassword
  61. }))
  62. }
  63. } catch (err) {
  64. dispatch(disconnect());
  65. alert(`SSH Error: ${err.message}`);
  66. }
  67. } else {
  68. handleRedis(config);
  69. }
  70.  
  71. function handleRedis(config, override) {
  72. dispatch(updateConnectStatus('Redis connecting...'))
  73. if (config.ssl) {
  74. config.tls = {};
  75. if (config.tlsca) config.tls.ca = config.tlsca;
  76. if (config.tlskey) config.tls.key = config.tlskey;
  77. if (config.tlscert) config.tls.cert = config.tlscert;
  78. }
  79. const redis = new Redis(Object.assign({}, config, override, {
  80. retryStrategy() {
  81. return false;
  82. }
  83. }));
  84. redis.defineCommand('setKeepTTL', {
  85. numberOfKeys: 1,
  86. lua: 'local ttl = redis.call("pttl", KEYS[1]) if ttl > 0 then return redis.call("SET", KEYS[1], ARGV[1], "PX", ttl) else return redis.call("SET", KEYS[1], ARGV[1]) end'
  87. });
  88. redis.defineCommand('lremindex', {
  89. numberOfKeys: 1,
  90. lua: 'local FLAG = "$$#__@DELETE@_REDIS_@PRO@__#$$" redis.call("lset", KEYS[1], ARGV[1], FLAG) redis.call("lrem", KEYS[1], 1, FLAG)'
  91. });
  92. redis.defineCommand('duplicateKey', {
  93. numberOfKeys: 2,
  94. lua: 'local dump = redis.call("dump", KEYS[1]) local pttl = 0 if ARGV[1] == "TTL" then pttl = redis.call("pttl", KEYS[1]) end return redis.call("restore", KEYS[2], pttl, dump)'
  95. });
  96. redis.once('connect', function () {
  97. redis.ping((err, res) => {
  98. if (err) {
  99. if (err.message === 'Ready check failed: NOAUTH Authentication required.') {
  100. err.message = 'Redis Error: Access denied. Please double-check your password.';
  101. }
  102. if (err.message !== 'Connection is closed.') {
  103. alert(err.message);
  104. redis.disconnect();
  105. }
  106. return;
  107. }
  108. const version = redis.serverInfo.redis_version;
  109. if (version && version.length >= 5) {
  110. const versionNumber = Number(version[0] + version[2]);
  111. if (versionNumber < 28) {
  112. alert('Medis only supports Redis >= 2.8 because servers older than 2.8 don\'t support SCAN command, which means it not possible to access keys without blocking Redis.');
  113. dispatch(disconnect());
  114. return;
  115. }
  116. }
  117. next({redis, config, index: getIndex(getState)});
  118. })
  119. });
  120. redis.once('error', function (error) {
  121. redisErrorMessage = error;
  122. });
  123. redis.once('end', function () {
  124. dispatch(disconnect());
  125. if (!sshErrorThrown) {
  126. let msg = 'Redis Error: Connection failed. ';
  127. if (redisErrorMessage) {
  128. msg += `(${redisErrorMessage})`;
  129. }
  130. alert(msg);
  131. }
  132. });
  133. }
  134. })
Add Comment
Please, Sign In to add comment