-
Notifications
You must be signed in to change notification settings - Fork 224
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(redis-v5): use billing entity to look up config vars (#1572)
- Loading branch information
1 parent
0ad377a
commit 8ee4bb9
Showing
2 changed files
with
136 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,14 +8,17 @@ let expect = require('chai').expect | |
let Duplex = require('stream').Duplex | ||
let EventEmitter = require('events').EventEmitter | ||
|
||
let command, net, tls | ||
let command, net, tls, tunnel | ||
|
||
describe('heroku redis:cli', function () { | ||
let command = proxyquire('../../commands/cli.js', { net: {}, tls: {}, ssh2: {} }) | ||
require('../lib/shared').shouldHandleArgs(command) | ||
}) | ||
|
||
describe('heroku redis:cli', function () { | ||
const addonId = '1dcb269b-8be5-4132-8aeb-e3f3c7364958' | ||
const appId = '7b0ae612-8775-4502-a5b5-2b45a4d18b2d' | ||
|
||
beforeEach(function () { | ||
cli.mockConsole() | ||
|
||
|
@@ -33,12 +36,13 @@ describe('heroku redis:cli', function () { | |
} | ||
|
||
class Tunnel extends EventEmitter { | ||
connect () { | ||
this.emit('ready') | ||
} | ||
|
||
forwardOut (localHost, localPort, hostname, port, cb) { | ||
cb(null, new Client()) | ||
constructor () { | ||
super() | ||
tunnel = this | ||
this.forwardOut = sinon.stub().yields(null, new Client()) | ||
this.connect = sinon.stub().callsFake(() => { | ||
this.emit('ready') | ||
}) | ||
} | ||
} | ||
|
||
|
@@ -50,7 +54,16 @@ describe('heroku redis:cli', function () { | |
it('# for hobby it uses net.connect', function () { | ||
let app = nock('https://api.heroku.com:443') | ||
.get('/apps/example/addons').reply(200, [ | ||
{ name: 'redis-haiku', addon_service: { name: 'heroku-redis' }, config_vars: ['REDIS_FOO', 'REDIS_BAR'] } | ||
{ | ||
id: addonId, | ||
name: 'redis-haiku', | ||
addon_service: { name: 'heroku-redis' }, | ||
config_vars: ['REDIS_FOO', 'REDIS_BAR'], | ||
billing_entity: { | ||
id: appId, | ||
name: 'example' | ||
} | ||
} | ||
]) | ||
|
||
let configVars = nock('https://api.heroku.com:443') | ||
|
@@ -73,7 +86,16 @@ describe('heroku redis:cli', function () { | |
it('# for premium it uses tls.connect', function () { | ||
let app = nock('https://api.heroku.com:443') | ||
.get('/apps/example/addons').reply(200, [ | ||
{ name: 'redis-haiku', addon_service: { name: 'heroku-redis' }, config_vars: ['REDIS_FOO', 'REDIS_BAR'] } | ||
{ | ||
id: addonId, | ||
name: 'redis-haiku', | ||
addon_service: { name: 'heroku-redis' }, | ||
config_vars: ['REDIS_FOO', 'REDIS_BAR'], | ||
billing_entity: { | ||
id: appId, | ||
name: 'example' | ||
} | ||
} | ||
]) | ||
|
||
let configVars = nock('https://api.heroku.com:443') | ||
|
@@ -97,9 +119,16 @@ describe('heroku redis:cli', function () { | |
it('# for bastion it uses tunnel.connect', function () { | ||
let app = nock('https://api.heroku.com:443') | ||
.get('/apps/example/addons').reply(200, [ | ||
{ name: 'redis-haiku', | ||
{ | ||
id: addonId, | ||
name: 'redis-haiku', | ||
addon_service: { name: 'heroku-redis' }, | ||
config_vars: ['REDIS_URL', 'REDIS_BASTIONS', 'REDIS_BASTION_KEY', 'REDIS_BASTION_REKEYS_AFTER'] } | ||
config_vars: ['REDIS_URL', 'REDIS_BASTIONS', 'REDIS_BASTION_KEY', 'REDIS_BASTION_REKEYS_AFTER'], | ||
billing_entity: { | ||
id: appId, | ||
name: 'example' | ||
} | ||
} | ||
]) | ||
|
||
let configVars = nock('https://api.heroku.com:443') | ||
|
@@ -122,9 +151,15 @@ describe('heroku redis:cli', function () { | |
it('# for private spaces bastion with prefer_native_tls, it uses tls.connect', function () { | ||
let app = nock('https://api.heroku.com:443') | ||
.get('/apps/example/addons').reply(200, [ | ||
{ name: 'redis-haiku', | ||
{ id: addonId, | ||
name: 'redis-haiku', | ||
addon_service: { name: 'heroku-redis' }, | ||
config_vars: ['REDIS_URL', 'REDIS_BASTIONS', 'REDIS_BASTION_KEY', 'REDIS_BASTION_REKEYS_AFTER'] } | ||
config_vars: ['REDIS_URL', 'REDIS_BASTIONS', 'REDIS_BASTION_KEY', 'REDIS_BASTION_REKEYS_AFTER'], | ||
billing_entity: { | ||
id: appId, | ||
name: 'example' | ||
} | ||
} | ||
]) | ||
|
||
let configVars = nock('https://api.heroku.com:443') | ||
|
@@ -145,4 +180,79 @@ describe('heroku redis:cli', function () { | |
.then(() => expect(cli.stderr).to.equal('')) | ||
.then(() => expect(tls.connect.called).to.equal(true)) | ||
}) | ||
|
||
it('# selects correct connection information when multiple redises are present across multiple apps', async () => { | ||
let app = nock('https://api.heroku.com:443') | ||
.get('/apps/example/addons').reply(200, [ | ||
{ | ||
id: addonId, | ||
name: 'redis-haiku', | ||
addon_service: { name: 'heroku-redis' }, | ||
config_vars: ['REDIS_URL', 'REDIS_BASTIONS', 'REDIS_BASTION_KEY', 'REDIS_BASTION_REKEYS_AFTER'], | ||
billing_entity: { | ||
id: appId, | ||
name: 'example' | ||
} | ||
}, | ||
{ | ||
id: 'heroku-redis-addon-id-2', | ||
name: 'redis-sonnet', | ||
addon_service: { name: 'heroku-redis' }, | ||
config_vars: ['REDIS_6_URL', 'REDIS_6_BASTIONS', 'REDIS_6_BASTION_KEY', 'REDIS_6_BASTION_REKEYS_AFTER'], | ||
billing_entity: { | ||
id: 'app-2-id', | ||
name: 'example-app-2' | ||
} | ||
} | ||
]) | ||
|
||
let configVars = nock('https://api.heroku.com:443') | ||
.get('/apps/example-app-2/config-vars').reply(200, { | ||
'REDIS_6_URL': '[email protected]', | ||
'REDIS_6_BASTIONS': 'redis-6-bastion.example.com', | ||
'REDIS_6_BASTION_KEY': 'key2' | ||
}) | ||
|
||
let redis = nock('https://redis-api.heroku.com:443') | ||
.get('/redis/v0/databases/redis-sonnet').reply(200, { | ||
resource_url: 'redis://foobar:[email protected]:8649', | ||
plan: 'private-7', | ||
prefer_native_tls: true | ||
}) | ||
|
||
await command.run({ app: 'example', flags: { confirm: 'example' }, args: { database: 'redis-sonnet' }, auth: { username: 'foobar', password: 'password' } }) | ||
app.done() | ||
configVars.done() | ||
redis.done() | ||
|
||
expect(cli.stdout).to.equal('Connecting to redis-sonnet (REDIS_6_URL):\n') | ||
expect(cli.stderr).to.equal('') | ||
|
||
const connectArgs = tunnel.connect.args[0] | ||
expect(connectArgs).to.have.length(1) | ||
expect(connectArgs[0]).to.deep.equal({ | ||
host: 'redis-6-bastion.example.com', | ||
privateKey: 'key2', | ||
username: 'bastion' | ||
}) | ||
|
||
const tunnelArgs = tunnel.forwardOut.args[0] | ||
const [localAddr, localPort, remoteAddr, remotePort] = tunnelArgs | ||
expect(localAddr).to.equal('localhost') | ||
expect(localPort).to.be.a('number') | ||
expect(remoteAddr).to.equal('redis-6.example.com') | ||
expect(remotePort).to.equal('8649') | ||
|
||
const tlsConnectArgs = tls.connect.args[0] | ||
expect(tlsConnectArgs).to.have.length(1) | ||
const tlsConnectOptions = { | ||
...tlsConnectArgs[0] | ||
} | ||
delete tlsConnectOptions.socket | ||
expect(tlsConnectOptions).to.deep.equal({ | ||
port: 8649, | ||
host: 'redis-6.example.com', | ||
rejectUnauthorized: false | ||
}) | ||
}) | ||
}) |