Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(certs-v5): add domain info in certs list and info #1660

Merged
merged 4 commits into from
Oct 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion packages/certs-v5/commands/certs/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ function * run (context, heroku) {
headers: { 'Accept': `application/vnd.heroku+json; version=3.${endpoint._meta.variant}` }
}))

if (context.flags['show-domains']) {
let domains = yield Promise.all(endpoint.domains.map(domain => {
return heroku.request({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this handle paginated responses?

path: `/apps/${context.flags.app}/domains/${domain}`,
headers: { 'Accept': `application/vnd.heroku+json; version=3.allow_multiple_sni_endpoints` }
}).then(response => response.hostname)
}))
cert.domains = domains
} else {
delete cert.domains
}

certificateDetails(cert)
}

Expand All @@ -22,7 +34,8 @@ module.exports = {
command: 'info',
flags: [
{ name: 'name', hasValue: true, description: 'name to check info on' },
{ name: 'endpoint', hasValue: true, description: 'endpoint to check info on' }
{ name: 'endpoint', hasValue: true, description: 'endpoint to check info on' },
{ name: 'show-domains', hasValue: false, description: 'show associated domains' }
],
description: 'show certificate information for an SSL certificate',
needsApp: true,
Expand Down
12 changes: 9 additions & 3 deletions packages/certs-v5/lib/certificate_details.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@ module.exports = function (cert, message) {

let logMessage = message || 'Certificate details:'
cli.log(logMessage)
cli.styledObject({
let tableObject = {
'Common Name(s)': cert.ssl_cert.cert_domains,
'Expires At': formatDate(cert.ssl_cert.expires_at),
'Issuer': cert.ssl_cert.issuer,
'Starts At': formatDate(cert.ssl_cert.starts_at),
'Subject': cert.ssl_cert.subject
})
'Subject': cert.ssl_cert.subject,
}

if (cert.domains && cert.domains.length) {
tableObject['Domain(s)'] = cert.domains
}

cli.styledObject(tableObject)

if (cert.ssl_cert['ca_signed?']) {
cli.log('SSL certificate is verified by a root authority.')
Expand Down
18 changes: 15 additions & 3 deletions packages/certs-v5/lib/display_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,22 @@ function type (f) {

module.exports = function (certs) {
let mapped = certs.filter(function (f) { return f.ssl_cert }).map(function (f) {
return {
let tableContents = {
name: f.name,
cname: f.cname,
expires_at: f.ssl_cert.expires_at,
ca_signed: f.ssl_cert['ca_signed?'],
type: type(f),
common_names: f.ssl_cert.cert_domains.join(', ')
common_names: f.ssl_cert.cert_domains.join(', '),
}

// If they're using ACM it's not really worth showing the number of associated domains since
// it'll always be 1 and is entirely outside the user's control
if (!f.ssl_cert.acm) {
tableContents.associated_domains = (f.domains && f.domains.length) ? f.domains.length : '0'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit confused seeing this in the output and after reading the comment. What do you think about using 1 here instead of '0'? Or showing a blank space? 0 makes me think something isn't quite right since there is a cname for the cert. I might also be missing a key difference on the domains field vs the cname field.

Copy link
Contributor Author

@cafreeman cafreeman Oct 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes. The cname field is indicating the domain(s) provided when creating the cert. The "associated domains" field is referring to the number of actual connections made between this cert and actual domains that belong to the app on Heroku.

In other words, you may have a cert with a cname that reads "*.purple.com", and in Heroku, that cert could be assigned to "{foo,bar,baz}.purple.com" so you'd have 3 associated domains.

Likewise, you could have a cert uploaded that does not yet have any domains associated with it, in which case 0 seems like the best thing to display.

}

return tableContents
})

let columns = [
Expand All @@ -47,8 +55,12 @@ module.exports = function (certs) {
{label: 'Common Name(s)', key: 'common_names'},
{label: 'Expires', key: 'expires_at', format: function (f) { return f ? formatDate(f) : '' }},
{label: 'Trusted', key: 'ca_signed', format: function (f) { return f === undefined ? '' : (f ? 'True' : 'False') }},
{label: 'Type', key: 'type'}
{label: 'Type', key: 'type'},
])

if (certs.some(cert => !cert.ssl_cert || !cert.ssl_cert.acm)) {
columns.push({label: 'Domains', key: 'associated_domains'})
}

cli.table(mapped, { columns })
}
46 changes: 23 additions & 23 deletions packages/certs-v5/test/commands/certs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ describe('heroku certs', function () {
expect(cli.stderr).to.equal('')
/* eslint-disable no-trailing-spaces */
expect(cli.stdout).to.equal(
`Name Endpoint Common Name(s) Expires Trusted Type
────────── ──────────────────────── ────────────── ──────────────────── ─────── ────────
akita-7777 akita-7777.herokussl.com heroku.com 2013-08-01 21:34 UTC True Endpoint
tokyo-1050 tokyo-1050.herokussl.com example.org 2013-08-01 21:34 UTC False Endpoint
`Name Endpoint Common Name(s) Expires Trusted Type Domains
────────── ──────────────────────── ────────────── ──────────────────── ─────── ──────── ───────
akita-7777 akita-7777.herokussl.com heroku.com 2013-08-01 21:34 UTC True Endpoint 0
tokyo-1050 tokyo-1050.herokussl.com example.org 2013-08-01 21:34 UTC False Endpoint 0
`)
/* eslint-enable no-trailing-spaces */
})
Expand Down Expand Up @@ -82,10 +82,10 @@ tokyo-1050 tokyo-1050.herokussl.com example.org 2013-08-01 21:34 UTC Fals
expect(cli.stderr).to.equal('')
/* eslint-disable no-trailing-spaces */
expect(cli.stdout).to.equal(
`Name Endpoint Common Name(s) Expires Trusted Type
────────── ──────────────────────── ───────────────────────────────────────────────── ──────────────────── ─────── ────────
akita-7777 akita-7777.herokussl.com heroku.com 2013-08-01 21:34 UTC True Endpoint
tokyo-1050 (Not applicable for SNI) foo.example.org, bar.example.org, biz.example.com 2013-08-01 21:34 UTC False SNI
`Name Endpoint Common Name(s) Expires Trusted Type Domains
────────── ──────────────────────── ───────────────────────────────────────────────── ──────────────────── ─────── ──────── ───────
akita-7777 akita-7777.herokussl.com heroku.com 2013-08-01 21:34 UTC True Endpoint 0
tokyo-1050 (Not applicable for SNI) foo.example.org, bar.example.org, biz.example.com 2013-08-01 21:34 UTC False SNI 0
`)
/* eslint-enable no-trailing-spaces */
})
Expand All @@ -111,9 +111,9 @@ tokyo-1050 (Not applicable for SNI) foo.example.org, bar.example.org, biz.exam
expect(cli.stderr).to.equal('')
/* eslint-disable no-trailing-spaces */
expect(cli.stdout).to.equal(
`Name Endpoint Common Name(s) Expires Trusted Type
────────── ───────────────────────────────────── ────────────── ──────────────────── ─────── ─────────────────
tokyo-1050 tokyo-1050.japan-4321.herokuspace.com heroku.com 2013-08-01 21:34 UTC True Private Space App
`Name Endpoint Common Name(s) Expires Trusted Type Domains
────────── ───────────────────────────────────── ────────────── ──────────────────── ─────── ───────────────── ───────
tokyo-1050 tokyo-1050.japan-4321.herokuspace.com heroku.com 2013-08-01 21:34 UTC True Private Space App 0
`)
/* eslint-enable no-trailing-spaces */
})
Expand Down Expand Up @@ -165,9 +165,9 @@ tokyo-1050 heroku.com 2013-08-01 21:34 UTC True ACM
expect(cli.stderr).to.equal('')
/* eslint-disable no-trailing-spaces */
expect(cli.stdout).to.equal(
`Name Common Name(s) Expires Trusted Type
────────── ───────────────────────────────────────────────── ──────────────────── ─────── ────
tokyo-1050 foo.example.org, bar.example.org, biz.example.com 2013-08-01 21:34 UTC False SNI
`Name Common Name(s) Expires Trusted Type Domains
────────── ───────────────────────────────────────────────── ──────────────────── ─────── ──── ───────
tokyo-1050 foo.example.org, bar.example.org, biz.example.com 2013-08-01 21:34 UTC False SNI 0
`)
/* eslint-enable no-trailing-spaces */
})
Expand All @@ -192,9 +192,9 @@ tokyo-1050 foo.example.org, bar.example.org, biz.example.com 2013-08-01 21:34
expect(cli.stderr).to.equal('')
/* eslint-disable no-trailing-spaces */
expect(cli.stdout).to.equal(
`Name Common Name(s) Expires Trusted Type
────────── ────────────── ──────────────────── ─────── ────
tokyo-1050 fooexample.org 2013-08-01 21:34 UTC False SNI
`Name Common Name(s) Expires Trusted Type Domains
────────── ────────────── ──────────────────── ─────── ──── ───────
tokyo-1050 fooexample.org 2013-08-01 21:34 UTC False SNI 0
`)
/* eslint-enable no-trailing-spaces */
})
Expand All @@ -219,9 +219,9 @@ tokyo-1050 fooexample.org 2013-08-01 21:34 UTC False SNI
expect(cli.stderr).to.equal('')
/* eslint-disable no-trailing-spaces */
expect(cli.stdout).to.equal(
`Name Common Name(s) Expires Trusted Type
────────── ────────────── ──────────────────── ─────── ────
tokyo-1050 *.example.org 2013-08-01 21:34 UTC False SNI
`Name Common Name(s) Expires Trusted Type Domains
────────── ────────────── ──────────────────── ─────── ──── ───────
tokyo-1050 *.example.org 2013-08-01 21:34 UTC False SNI 0
`)
/* eslint-enable no-trailing-spaces */
})
Expand All @@ -246,9 +246,9 @@ tokyo-1050 *.example.org 2013-08-01 21:34 UTC False SNI
expect(cli.stderr).to.equal('')
/* eslint-disable no-trailing-spaces */
expect(cli.stdout).to.equal(
`Name Common Name(s) Expires Trusted Type
────────── ───────────────────────────────────────────────── ──────────────────── ─────── ────
tokyo-1050 foo.example.org, bar.example.org, biz.example.com 2013-08-01 21:34 UTC False SNI
`Name Common Name(s) Expires Trusted Type Domains
────────── ───────────────────────────────────────────────── ──────────────────── ─────── ──── ───────
tokyo-1050 foo.example.org, bar.example.org, biz.example.com 2013-08-01 21:34 UTC False SNI 0
`)
/* eslint-enable no-trailing-spaces */
})
Expand Down