From 2437eae715cff945b9f6dca68eedab5585fac3ae Mon Sep 17 00:00:00 2001 From: nomura yoshihiro Date: Mon, 18 Mar 2019 13:23:49 +0900 Subject: [PATCH] feat(sentinel): support Sentinel instances with authentication. (#817) --- README.md | 1 + lib/connectors/SentinelConnector/index.ts | 2 ++ test/functional/sentinel.js | 26 +++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/README.md b/README.md index fe49a48d..f72b2a69 100644 --- a/README.md +++ b/README.md @@ -673,6 +673,7 @@ redis.set('foo', 'bar'); The arguments passed to the constructor are different from the ones you use to connect to a single node, where: * `name` identifies a group of Redis instances composed of a master and one or more slaves (`mymaster` in the example); +* `sentinelPassword` (optional) password for Sentinel instances. * `sentinels` are a list of sentinels to connect to. The list does not need to enumerate all your sentinel instances, but a few so that if one is down the client will try the next one. * `role` (optional) with a value of `slave` will return a random slave from the Sentinel group. * `preferredSlaves` (optional) can be used to prefer a particular slave or set of slaves based on priority. It accepts a function or array. diff --git a/lib/connectors/SentinelConnector/index.ts b/lib/connectors/SentinelConnector/index.ts index a7105a6c..1607770d 100644 --- a/lib/connectors/SentinelConnector/index.ts +++ b/lib/connectors/SentinelConnector/index.ts @@ -25,6 +25,7 @@ type PreferredSlaves = interface ISentinelConnectionOptions extends ITcpConnectionOptions { role: 'master' | 'slave' name: 'string' + sentinelPassword?: 'string' sentinels: Array sentinelRetryStrategy?: (retryAttempts: number) => number preferredSlaves?: PreferredSlaves @@ -219,6 +220,7 @@ export default class SentinelConnector extends AbstractConnector { var client = new Redis({ port: endpoint.port || 26379, host: endpoint.host, + password: this.options.sentinelPassword || null, family: endpoint.family || (isIIpcConnectionOptions(this.options) ? undefined : this.options.family), tls: this.options.sentinelTLS, retryStrategy: null, diff --git a/test/functional/sentinel.js b/test/functional/sentinel.js index 75180a1a..87fc495b 100644 --- a/test/functional/sentinel.js +++ b/test/functional/sentinel.js @@ -186,7 +186,33 @@ describe('sentinel', function () { name: 'master' }); }); + it('should connect to sentinel with authentication successfully', function (done) { + var authed = false; + var redisServer = new MockServer('17380', function (argv) { + if (argv[0] === 'auth' && argv[1] === 'pass') { + authed = true; + } else if (argv[0] === 'get' && argv[1] === 'foo') { + expect(authed).to.eql(true); + redisServer.disconnect(); + done(); + } + }) + var sentinel = new MockServer(27379, function (argv) { + if (argv[0] === 'sentinel' && argv[1] === 'get-master-addr-by-name') { + sentinel.disconnect(done); + return ['127.0.0.1', '17380']; + } + }); + var redis = new Redis({ + sentinelPassword: 'pass', + sentinels: [ + { host: '127.0.0.1', port: '27379' } + ], + name: 'master' + }); + redis.get('foo').catch(function () {}); + }); }); describe('master', function () {