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

Update commands to work with published APIs #3070

Merged
merged 2 commits into from
Nov 4, 2024
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
54 changes: 24 additions & 30 deletions packages/cli/src/commands/telemetry/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {Args, ux} from '@oclif/core'
import {TelemetryDrain} from '../../lib/types/telemetry'
import heredoc from 'tsheredoc'
import {validateAndFormatSignals} from '../../lib/telemetry/util'
import {App, Space} from '@heroku-cli/schema'

export default class Add extends Command {
static description = 'Add and configure a new telemetry drain. Defaults to collecting all telemetry unless otherwise specified.'

Expand All @@ -21,26 +23,29 @@ export default class Add extends Command {

static example = heredoc(`
Add a telemetry drain to an app to collect logs and traces:
$ heroku telemetry:add --signals logs,traces --endpoint https://my-endpoint.com --transport http 'x-drain-example-team: API_KEY x-drain-example-dataset: METRICS_DATASET'
$ heroku telemetry:add --app myapp --signals logs,traces --endpoint https://my-endpoint.com --transport http '{"x-drain-example-team": "API_KEY", "x-drain-example-dataset": "METRICS_DATASET"}'
`)

private getTypeAndName = function (app: string | undefined, space: string | undefined) {
if (app) {
return {type: 'app', name: app}
}

return {type: 'space', name: space}
}

public async run(): Promise<void> {
const {flags, args} = await this.parse(Add)
const {app, space, signals, endpoint, transport} = flags
const {headers} = args
const typeAndName = this.getTypeAndName(app, space)
let id
if (app) {
const {body: herokuApp} = await this.heroku.get<App>(
`/apps/${app}`, {
headers: {Accept: 'application/vnd.heroku+json; version=3.sdk'},
})
id = herokuApp.id
} else {
const {body: herokuSpace} = await this.heroku.get<Space>(`/spaces/${space}`)
id = herokuSpace.id
}

const drainConfig = {
owner: {
type: typeAndName.type,
id: typeAndName.name,
type: app ? 'app' : 'space',
id,
},
signals: validateAndFormatSignals(signals),
exporter: {
Expand All @@ -50,24 +55,13 @@ export default class Add extends Command {
},
}

if (app) {
const {body: drain} = await this.heroku.post<TelemetryDrain>(`/apps/${app}/telemetry-drains`, {
body: drainConfig,
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})

ux.log(`successfully added drain ${drain.exporter.endpoint}`)
} else if (space) {
const {body: drain} = await this.heroku.post<TelemetryDrain>(`/spaces/${space}/telemetry-drains`, {
body: drainConfig,
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})
const {body: drain} = await this.heroku.post<TelemetryDrain>('/telemetry-drains', {
body: drainConfig,
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})

ux.log(`successfully added drain ${drain.exporter.endpoint}`)
}
ux.log(`successfully added drain ${drain.exporter.endpoint}`)
}
}
33 changes: 19 additions & 14 deletions packages/cli/src/commands/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,39 @@ export default class Index extends Command {
public async run(): Promise<void> {
const {flags} = await this.parse(Index)
const {app, space} = flags

let drains: TelemetryDrains = []
if (app) {
const {body: appTelemetryDrains} = await this.heroku.get<TelemetryDrains>(`/apps/${app}/telemetry-drains`, {
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})
this.display(appTelemetryDrains, 'App')
drains = appTelemetryDrains
} else if (space) {
const {body: spaceTelemetryDrains} = await this.heroku.get<TelemetryDrains>(`/spaces/${space}/telemetry-drains`, {
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})
this.display(spaceTelemetryDrains, 'Space')
drains = spaceTelemetryDrains
}

this.display(drains, app || space)
}

protected display(telemetryDrains: TelemetryDrains, ownerType: 'App' | 'Space') {
ux.styledHeader(`${ownerType} Telemetry Drains`)
ux.table(
telemetryDrains,
{
ID: {get: telemetryDrain => telemetryDrain.id},
Signals: {get: telemetryDrain => telemetryDrain.signals},
Endpoint: {get: telemetryDrain => telemetryDrain.exporter.endpoint},
[ownerType]: {get: telemetryDrain => telemetryDrain.owner.name},
},
)
protected display(telemetryDrains: TelemetryDrains, owner: string | undefined) {
if (telemetryDrains.length === 0) {
ux.log(`There are no telemetry drains in ${owner}`)
} else {
ux.styledHeader(`${owner} Telemetry Drains`)
ux.table(
telemetryDrains,
{
ID: {get: telemetryDrain => telemetryDrain.id},
Signals: {get: telemetryDrain => telemetryDrain.signals},
Endpoint: {get: telemetryDrain => telemetryDrain.exporter.endpoint},
},
)
}
}
}
4 changes: 2 additions & 2 deletions packages/cli/src/commands/telemetry/remove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export default class Remove extends Command {
}

if (telemetry_drain_id) {
const telemetryDrain = await this.removeDrain(telemetry_drain_id)
ux.action.start(`Removing telemetry drain ${telemetry_drain_id}, which was configured for ${telemetryDrain.owner.type} ${telemetryDrain.owner.name}`)
ux.action.start(`Removing telemetry drain ${telemetry_drain_id}`)
await this.removeDrain(telemetry_drain_id)
} else if (app) {
ux.action.start(`Removing all telemetry drains from app ${app}`)
const {body: telemetryDrains} = await this.heroku.get<TelemetryDrain[]>(`/apps/${app}/telemetry-drains`, {
Expand Down
27 changes: 24 additions & 3 deletions packages/cli/test/unit/commands/telemetry/add.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@ import {expect} from 'chai'
import * as nock from 'nock'
import expectOutput from '../../../helpers/utils/expectOutput'
import {spaceTelemetryDrain1, appTelemetryDrain1} from '../../../fixtures/telemetry/fixtures'
import {firApp} from '../../../fixtures/apps/fixtures'
import * as spaceFixtures from '../../../fixtures/spaces/fixtures'
import {SpaceWithOutboundIps} from '../../../../src/lib/types/spaces'

const appId = appTelemetryDrain1.owner.id
const spaceId = spaceTelemetryDrain1.owner.id
const testEndpoint = appTelemetryDrain1.exporter.endpoint

describe('telemetry:add', function () {
let space: SpaceWithOutboundIps

beforeEach(function () {
space = spaceFixtures.spaces['non-shield-space']
})

afterEach(function () {
return nock.cleanAll()
})
Expand All @@ -31,7 +40,7 @@ describe('telemetry:add', function () {
await runCommand(Cmd, [
'{"x-honeycomb-team": "your-api-key", "x-honeycomb-dataset": "your-dataset"}',
'--app',
'myapp',
firApp.name || '',
'--space',
'myspace',
])
Expand All @@ -43,7 +52,10 @@ describe('telemetry:add', function () {

it('successfully creates a telemetry drain for an app', async function () {
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.post(`/apps/${appId}/telemetry-drains`)
.get(`/apps/${appId}`)
.reply(200, firApp)
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.post('/telemetry-drains')
.reply(200, spaceTelemetryDrain1)

await runCommand(Cmd, [
Expand All @@ -62,8 +74,11 @@ describe('telemetry:add', function () {
})

it('successfully creates a telemetry drain for a space', async function () {
nock('https://api.heroku.com')
.get(`/spaces/${spaceId}`)
.reply(200, space)
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.post(`/spaces/${spaceId}/telemetry-drains`)
.post('/telemetry-drains')
.reply(200, spaceTelemetryDrain1)

await runCommand(Cmd, [
Expand All @@ -82,6 +97,9 @@ describe('telemetry:add', function () {
})

it('does not accept options other than logs, metrics, traces, or all for the --signal flag', async function () {
nock('https://api.heroku.com')
.get(`/spaces/${spaceId}`)
.reply(200, space)
try {
await runCommand(Cmd, [
'{"x-honeycomb-team": "your-api-key", "x-honeycomb-dataset": "your-dataset"}',
Expand All @@ -101,6 +119,9 @@ describe('telemetry:add', function () {
})

it('returns an error when the --signal flag is set to "all" in combination with other options', async function () {
nock('https://api.heroku.com')
.get(`/spaces/${spaceId}`)
.reply(200, space)
try {
await runCommand(Cmd, [
'{"x-honeycomb-team": "your-api-key", "x-honeycomb-dataset": "your-dataset"}',
Expand Down
32 changes: 23 additions & 9 deletions packages/cli/test/unit/commands/telemetry/index.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ describe('telemetry:index', function () {
spaceId,
])
expectOutput(stdout.output, heredoc(`
=== Space Telemetry Drains
Id Signals Endpoint Space
──────────────────────────────────── ─────────────────────────────── ───────────────────────── ───────
44444321-5717-4562-b3fc-2c963f66afa6 [ 'traces', 'metrics', 'logs' ] https://api.honeycomb.io/ myspace
=== ${spaceId} Telemetry Drains
Id Signals Endpoint
──────────────────────────────────── ─────────────────────────────── ─────────────────────────
44444321-5717-4562-b3fc-2c963f66afa6 [ 'traces', 'metrics', 'logs' ] https://api.honeycomb.io/
`))
})

Expand All @@ -51,11 +51,25 @@ describe('telemetry:index', function () {
appId,
])
expectOutput(stdout.output, heredoc(`
=== App Telemetry Drains
Id Signals Endpoint App
──────────────────────────────────── ─────────────────────── ─────────────────────────── ─────
3fa85f64-5717-4562-b3fc-2c963f66afa6 [ 'traces', 'metrics' ] https://api.honeycomb.io/ myapp
55555f64-5717-4562-b3fc-2c963f66afa6 [ 'logs' ] https://api.papertrail.com/ myapp
=== ${appId} Telemetry Drains
Id Signals Endpoint
──────────────────────────────────── ─────────────────────── ───────────────────────────
3fa85f64-5717-4562-b3fc-2c963f66afa6 [ 'traces', 'metrics' ] https://api.honeycomb.io/
55555f64-5717-4562-b3fc-2c963f66afa6 [ 'logs' ] https://api.papertrail.com/
`))
})

it('shows a message when there are no telemetry drains', async function () {
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.get(`/apps/${appId}/telemetry-drains`)
.reply(200, [])

await runCommand(Cmd, [
'--app',
appId,
])
expectOutput(stdout.output, heredoc(`
There are no telemetry drains in ${appId}
`))
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ describe('telemetry:remove', function () {
spaceTelemetryDrain1.id,
])
expectOutput(stderr.output, heredoc(`
Removing telemetry drain ${spaceTelemetryDrain1.id}, which was configured for space ${spaceTelemetryDrain1.owner.name}...
Removing telemetry drain ${spaceTelemetryDrain1.id}, which was configured for space ${spaceTelemetryDrain1.owner.name}... done
Removing telemetry drain ${spaceTelemetryDrain1.id}...
Removing telemetry drain ${spaceTelemetryDrain1.id}... done
`))
})

Expand All @@ -54,8 +54,8 @@ describe('telemetry:remove', function () {
appTelemetryDrain1.id,
])
expectOutput(stderr.output, heredoc(`
Removing telemetry drain ${appTelemetryDrain1.id}, which was configured for app ${appTelemetryDrain1.owner.name}...
Removing telemetry drain ${appTelemetryDrain1.id}, which was configured for app ${appTelemetryDrain1.owner.name}... done
Removing telemetry drain ${appTelemetryDrain1.id}...
Removing telemetry drain ${appTelemetryDrain1.id}... done
`))
})

Expand Down
Loading