Skip to content

Commit

Permalink
Add telemetry remove command (#3035)
Browse files Browse the repository at this point in the history
* Add telemetry remove command

* Allow for passing --app or --space to delete drains

* switch to 3.sdk variant, use fixutres in tests
  • Loading branch information
eablack authored Oct 17, 2024
1 parent 82372c1 commit af5fcb8
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 0 deletions.
67 changes: 67 additions & 0 deletions packages/cli/src/commands/telemetry/remove.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {flags, Command} from '@heroku-cli/command'
import {Args, ux} from '@oclif/core'
import {TelemetryDrain} from '../../lib/types/telemetry'
import heredoc from 'tsheredoc'

export default class Remove extends Command {
static topic = 'telemetry'
static description = 'remove a telemetry drain'
static args = {
telemetry_drain_id: Args.string({description: 'ID of the drain to remove'}),
}

static flags = {
app: flags.app({description: 'name of the app to remove all drains from'}),
space: flags.string({char: 's', description: 'name of the space to remove all drains from'}),
}

public async run(): Promise<void> {
const {args, flags} = await this.parse(Remove)
const {app, space} = flags
const {telemetry_drain_id} = args
if (!(app || space || telemetry_drain_id)) {
ux.error(heredoc(`
Requires either --app or --space or a TELEMETRY_DRAIN_ID to be provided.
See more help with --help
`))
}

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}`)
} 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`, {
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})

for (const telemetryDrain of telemetryDrains) {
await this.removeDrain(telemetryDrain.id)
}
} else if (space) {
ux.action.start(`Removing all telemetry drains from space ${space}`)
const {body: telemetryDrains} = await this.heroku.get<TelemetryDrain[]>(`/spaces/${space}/telemetry-drains`, {
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})

for (const telemetryDrain of telemetryDrains) {
await this.removeDrain(telemetryDrain.id)
}
}

ux.action.stop()
}

protected async removeDrain(telemetry_drain_id: string) {
const {body: telemetryDrain} = await this.heroku.delete<TelemetryDrain>(`/telemetry-drains/${telemetry_drain_id}`, {
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})
return telemetryDrain
}
}
105 changes: 105 additions & 0 deletions packages/cli/test/unit/commands/telemetry/remove.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {stderr} from 'stdout-stderr'
import Cmd from '../../../../src/commands/telemetry/remove'
import runCommand from '../../../helpers/runCommand'
import * as nock from 'nock'
import expectOutput from '../../../helpers/utils/expectOutput'
import heredoc from 'tsheredoc'
import {expect} from 'chai'
import {spaceTelemetryDrain1, appTelemetryDrain1, appTelemetryDrain2} from '../../../fixtures/telemetry/fixtures'
import {TelemetryDrains} from '../../../../src/lib/types/telemetry'

describe('telemetry:remove', function () {
let appId: string
let spaceId: string
let appTelemetryDrains: TelemetryDrains
let spaceTelemetryDrains: TelemetryDrains

beforeEach(function () {
appId = appTelemetryDrain1.owner.id
spaceId = spaceTelemetryDrain1.owner.id
appTelemetryDrains = [appTelemetryDrain1, appTelemetryDrain2]
spaceTelemetryDrains = [spaceTelemetryDrain1]
})

afterEach(function () {
return nock.cleanAll()
})

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

await runCommand(Cmd, [
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
`))
})

it('deletes an app telemetry drains', async function () {
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.get(`/telemetry-drains/${appTelemetryDrain1.id}`)
.reply(200, appTelemetryDrain1)
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.delete(`/telemetry-drains/${appTelemetryDrain1.id}`)
.reply(200, appTelemetryDrain1)

await runCommand(Cmd, [
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
`))
})

it('deletes all drains from an app', async function () {
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.get(`/apps/${appId}/telemetry-drains`)
.reply(200, appTelemetryDrains)
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.delete(`/telemetry-drains/${appTelemetryDrain1.id}`)
.reply(200, appTelemetryDrain1)
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.delete(`/telemetry-drains/${appTelemetryDrain2.id}`)
.reply(200, appTelemetryDrain2)

await runCommand(Cmd, [
'--app', appId,
])
expectOutput(stderr.output, heredoc(`
Removing all telemetry drains from app ${appId}...
Removing all telemetry drains from app ${appId}... done
`))
})

it('deletes all drains from a space', async function () {
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.get(`/spaces/${spaceId}/telemetry-drains`)
.reply(200, spaceTelemetryDrains)
nock('https://api.heroku.com', {reqheaders: {Accept: 'application/vnd.heroku+json; version=3.sdk'}})
.delete(`/telemetry-drains/${spaceTelemetryDrain1.id}`)
.reply(200, spaceTelemetryDrain1)

await runCommand(Cmd, [
'--space', spaceId,
])
expectOutput(stderr.output, heredoc(`
Removing all telemetry drains from space ${spaceId}...
Removing all telemetry drains from space ${spaceId}... done
`))
})

it('requires a telemetry id, an app id, or a space id', async function () {
const errorMessage = 'Requires either --app or --space or a TELEMETRY_DRAIN_ID to be provided.'
await runCommand(Cmd, []).catch(error => {
expect(error.message).to.contain(errorMessage)
})
})
})

0 comments on commit af5fcb8

Please sign in to comment.