UNPKG

3.37 kBJavaScriptView Raw
1'use strict'
2
3const co = require('co')
4const cli = require('heroku-cli-util')
5const sortBy = require('lodash.sortby')
6const printf = require('printf')
7
8function * run (context, heroku) {
9 const fetcher = require('../lib/fetcher')(heroku)
10
11 const {app, args, flags} = context
12
13 let showCredentials = co.wrap(function * () {
14 const host = require('../lib/host')
15 let addon = yield fetcher.addon(app, args.database)
16 let attachments = []
17
18 function formatAttachment (attachment) {
19 let attName = cli.color.addon(attachment.name)
20
21 let output = [cli.color.dim('as'), attName]
22 let appInfo = `on ${cli.color.app(attachment.app.name)} app`
23 output.push(cli.color.dim(appInfo))
24
25 return output.join(' ')
26 }
27
28 function renderAttachment (attachment, app, isLast) {
29 let line = isLast ? '└─' : '├─'
30 let attName = formatAttachment(attachment)
31 return printf(' %s %s', cli.color.dim(line), attName)
32 }
33
34 function presentCredential (cred) {
35 let credAttachments = []
36 if (cred !== 'default') {
37 credAttachments = attachments.filter(a => a.namespace === `credential:${cred}`)
38 } else {
39 credAttachments = attachments.filter(a => a.namespace === null)
40 }
41 let isForeignApp = (attOrAddon) => attOrAddon.app.name !== app
42 let atts = sortBy(credAttachments,
43 isForeignApp,
44 'name',
45 'app.name'
46 )
47
48 // render each attachment under the credential
49 let attLines = atts.map(function (attachment, idx) {
50 let isLast = (idx === credAttachments.length - 1)
51 return renderAttachment(attachment, app, isLast)
52 })
53
54 return [cred].concat(attLines).join('\n')
55 }
56
57 try {
58 let credentials = yield heroku.get(`/postgres/v0/databases/${addon.name}/credentials`,
59 { host: host(addon) })
60 let isDefaultCredential = (cred) => cred.name !== 'default'
61 credentials = sortBy(credentials, isDefaultCredential, 'name')
62 attachments = yield heroku.get(`/addons/${addon.name}/addon-attachments`)
63
64 cli.table(credentials, {
65 columns: [
66 {key: 'name', label: 'Credential', format: presentCredential},
67 {key: 'state', label: 'State'}
68 ]
69 })
70 } catch (err) {
71 if (!err.statusCode || err.statusCode !== 422) throw err
72 let db = yield fetcher.database(app, args.database)
73 cli.log(`Connection info string:
74 "dbname=${db.database} host=${db.host} port=${db.port || 5432} user=${db.user} password=${db.password} sslmode=require"
75Connection URL:
76 ${db.url.href}`)
77 }
78 })
79
80 let reset = co.wrap(function * () {
81 const host = require('../lib/host')
82 let db = yield fetcher.addon(app, args.database)
83 yield cli.action(`Resetting credentials on ${cli.color.addon(db.name)}`, co(function * () {
84 yield heroku.post(`/client/v11/databases/${db.id}/credentials_rotation`, {host: host(db)})
85 }))
86 })
87
88 if (flags.reset) {
89 yield reset()
90 } else {
91 yield showCredentials()
92 }
93}
94
95module.exports = {
96 topic: 'pg',
97 command: 'credentials',
98 description: 'manage the database credentials',
99 needsApp: true,
100 needsAuth: true,
101 flags: [{name: 'reset', description: 'reset database credentials'}],
102 args: [{name: 'database', optional: true}],
103 run: cli.command({preauth: true}, co.wrap(run))
104}