diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 80551d9064..b7f94bb53e 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -10,7 +10,7 @@ JQ_FILTERS_CONFIG="." # for multiple endpoint locations if [[ "$ENDPOINT" ]]; then IFS="," read -ra HOST_NAMES <<< "$ENDPOINT" - for host in "${HOST_NAMES[@]}"; do + for host in "${HOST_NAMES[@]}"; do JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .restEndpoints[\"$host\"]=\"us-east-1\"" done echo "Host name has been modified to ${HOST_NAMES[@]}" @@ -94,21 +94,31 @@ if [[ "$MONGODB_DATABASE" ]]; then JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .mongodb.database=\"$MONGODB_DATABASE\"" fi -if [[ "$REDIS_HOST" ]]; then +if [ -z "$REDIS_HA_NAME" ]; then + REDIS_HA_NAME='mymaster' +fi + +if [[ "$REDIS_SENTINELS" ]]; then + JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .localCache.name=\"$REDIS_HA_NAME\"" + JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .localCache.sentinels=\"$REDIS_SENTINELS\"" +elif [[ "$REDIS_HOST" ]]; then JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .localCache.host=\"$REDIS_HOST\"" JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .localCache.port=6379" fi -if [[ "$REDIS_PORT" ]]; then +if [[ "$REDIS_PORT" ]] && [[ ! "$REDIS_SENTINELS" ]]; then JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .localCache.port=$REDIS_PORT" fi -if [[ "$REDIS_HA_HOST" ]]; then +if [[ "$REDIS_SENTINELS" ]]; then + JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .redis.name=\"$REDIS_HA_NAME\"" + JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .redis.sentinels=\"$REDIS_SENTINELS\"" +elif [[ "$REDIS_HA_HOST" ]]; then JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .redis.host=\"$REDIS_HA_HOST\"" JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .redis.port=6379" fi -if [[ "$REDIS_HA_PORT" ]]; then +if [[ "$REDIS_HA_PORT" ]] && [[ ! "$REDIS_SENTINELS" ]]; then JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .redis.port=$REDIS_HA_PORT" fi diff --git a/lib/Config.js b/lib/Config.js index 6f738c480d..d73f4bd95b 100644 --- a/lib/Config.js +++ b/lib/Config.js @@ -392,7 +392,7 @@ class Config extends EventEmitter { item.substr(0, lastColon); // the port should not include the colon const port = item.substr(lastColon + 1); - assert(parseInt(port, 10), + assert(Number.parseInt(port, 10), 'bad config: listenOn port must be a positive integer'); this.listenOn.push({ ip: ipAddress, port }); }); @@ -444,9 +444,9 @@ class Config extends EventEmitter { '`replicationEndpoints` must be an array'); servers.forEach(item => { assert(typeof item === 'string' && item !== '', - 'bad config: each item of ' + - '`replicationEndpoints:servers` must be a non-empty ' + - 'string'); + 'bad config: each item of ' + + '`replicationEndpoints:servers` must be a ' + + 'non-empty string'); }); } }); @@ -651,20 +651,53 @@ class Config extends EventEmitter { assert(typeof config.localCache === 'object', 'config: invalid local cache configuration. localCache must ' + 'be an object'); - assert(typeof config.localCache.host === 'string', - 'config: invalid host for localCache. host must be a string'); - assert(typeof config.localCache.port === 'number', - 'config: invalid port for localCache. port must be a number'); - if (config.localCache.password !== undefined) { - assert(this._verifyRedisPassword(config.localCache.password), - 'config: invalid password for localCache. password must' + + if (config.localCache.sentinels) { + this.localCache = { sentinels: [], name: null }; + + assert(typeof config.localCache.name === 'string', + 'bad config: localCache sentinel name must be a string'); + this.localCache.name = config.localCache.name; + + assert(Array.isArray(config.localCache.sentinels) || + typeof config.localCache.sentinels === 'string', + 'bad config: localCache sentinels' + + 'must be an array or string'); + + if (typeof config.localCache.sentinels === 'string') { + config.localCache.sentinels.split(',').forEach(item => { + const [host, port] = item.split(':'); + this.localCache.sentinels.push({ host, + port: Number.parseInt(port, 10) }); + }); + } else if (Array.isArray(config.localCache.sentinels)) { + config.localCache.sentinels.forEach(item => { + const { host, port } = item; + assert(typeof host === 'string', + 'bad config: localCache' + + 'sentinel host must be a string'); + assert(typeof port === 'number', + 'bad config: localCache' + + 'sentinel port must be a number'); + this.localCache.sentinels.push({ host, port }); + }); + } + } else { + assert(typeof config.localCache.host === 'string', + 'config: bad host for localCache. host must be a string'); + assert(typeof config.localCache.port === 'number', + 'config: bad port for localCache. port must be a number'); + if (config.localCache.password !== undefined) { + assert( + this._verifyRedisPassword(config.localCache.password), + 'config: vad password for localCache. password must' + ' be a string'); + } + this.localCache = { + host: config.localCache.host, + port: config.localCache.port, + password: config.localCache.password, + }; } - this.localCache = { - host: config.localCache.host, - port: config.localCache.port, - password: config.localCache.password, - }; } if (config.mongodb) { @@ -680,17 +713,26 @@ class Config extends EventEmitter { assert(typeof config.redis.name === 'string', 'bad config: redis sentinel name must be a string'); this.redis.name = config.redis.name; - - assert(Array.isArray(config.redis.sentinels), - 'bad config: redis sentinels must be an array'); - config.redis.sentinels.forEach(item => { - const { host, port } = item; - assert(typeof host === 'string', - 'bad config: redis sentinel host must be a string'); - assert(typeof port === 'number', - 'bad config: redis sentinel port must be a number'); - this.redis.sentinels.push({ host, port }); - }); + assert(Array.isArray(config.redis.sentinels) || + typeof config.redis.sentinels === 'string', + 'bad config: redis sentinels must be an array or string'); + + if (typeof config.redis.sentinels === 'string') { + config.redis.sentinels.split(',').forEach(item => { + const [host, port] = item.split(':'); + this.redis.sentinels.push({ host, + port: Number.parseInt(port, 10) }); + }); + } else if (Array.isArray(config.redis.sentinels)) { + config.redis.sentinels.forEach(item => { + const { host, port } = item; + assert(typeof host === 'string', + 'bad config: redis sentinel host must be a string'); + assert(typeof port === 'number', + 'bad config: redis sentinel port must be a number'); + this.redis.sentinels.push({ host, port }); + }); + } } else { // check for standalone configuration this.redis = {}; @@ -709,7 +751,6 @@ class Config extends EventEmitter { this.redis.password = config.redis.password; } } - if (config.utapi) { this.utapi = { component: 's3' }; if (config.utapi.port) { diff --git a/lib/server.js b/lib/server.js index 64f82b67d3..8b897d554a 100644 --- a/lib/server.js +++ b/lib/server.js @@ -29,11 +29,7 @@ updateAllEndpoints(); // redis client let localCacheClient; if (_config.localCache) { - localCacheClient = new RedisClient({ - host: _config.localCache.host, - port: _config.localCache.port, - password: _config.localCache.password, - }, logger); + localCacheClient = new RedisClient(_config.localCache, logger); } // stats client const STATS_INTERVAL = 5; // 5 seconds