Skip to content

Commit

Permalink
feature: Update command warning message for Fir spaces (#3171)
Browse files Browse the repository at this point in the history
* feature:  Update  command warning message for Fir spaces

* updated to use color from @heroku-cli/color instead of chalk

* Update packages/cli/src/commands/spaces/destroy.ts

Co-authored-by: Sandy Lai <[email protected]>

* Update packages/cli/src/commands/spaces/destroy.ts

Co-authored-by: Sandy Lai <[email protected]>

* Update packages/cli/src/commands/spaces/destroy.ts

Co-authored-by: Sandy Lai <[email protected]>

* Updated to differentiate between fir and non-fir spaces

* Updated to differentiate between fir and cedar

* Removed cheveron for windows tests

---------

Co-authored-by: Sandy Lai <[email protected]>
  • Loading branch information
justinwilaby and SandyPantsLai authored Jan 13, 2025
1 parent 1ee8f62 commit 43d9164
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 10 deletions.
21 changes: 18 additions & 3 deletions packages/cli/src/commands/spaces/destroy.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {Args, ux} from '@oclif/core'
import color from '@heroku-cli/color'
import {Command, flags} from '@heroku-cli/command'
import * as Heroku from '@heroku-cli/schema'
import heredoc from 'tsheredoc'
import confirmCommand from '../../lib/confirmCommand'
import {displayNat} from '../../lib/spaces/spaces'
import color from '@heroku-cli/color'
import {Space} from '../../lib/types/fir'

type RequiredSpaceWithNat = Required<Heroku.Space> & {outbound_ips?: Required<Heroku.SpaceNetworkAddressTranslation>}
type RequiredSpaceWithNat = Required<Space> & {outbound_ips?: Required<Heroku.SpaceNetworkAddressTranslation>}

export default class Destroy extends Command {
static topic = 'spaces'
Expand Down Expand Up @@ -40,10 +41,24 @@ export default class Destroy extends Command {

let natWarning = ''
const {body: space} = await this.heroku.get<RequiredSpaceWithNat>(`/spaces/${spaceName}`)

if (space.state === 'allocated') {
({body: space.outbound_ips} = await this.heroku.get<Required<Heroku.SpaceNetworkAddressTranslation>>(`/spaces/${spaceName}/nat`))
if (space.outbound_ips && space.outbound_ips.state === 'enabled') {
natWarning = `The Outbound IPs for this space will be reused!\nEnsure that external services no longer allow these Outbound IPs: ${displayNat(space.outbound_ips)}\n`
const ipv6 = space.generation?.name === 'fir' ? ' and IPv6' : ''
natWarning = heredoc`
${color.dim('===')} ${color.bold('WARNING: Outbound IPs Will Be Reused')}
${color.yellow(`⚠️ Deleting this space frees up the following outbound IPv4${ipv6} IPs for reuse:`)}
${color.bold(displayNat(space.outbound_ips) ?? '')}
${color.dim('Update the following configurations:')}
${color.dim('=')} IP allowlists
${color.dim('=')} Firewall rules
${color.dim('=')} Security group configurations
${color.dim('=')} Network ACLs
${color.yellow(`Ensure that you remove the listed IPv4${ipv6} addresses from your security configurations.`)}
`
}
}

Expand Down
85 changes: 78 additions & 7 deletions packages/cli/test/unit/commands/spaces/destroy.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,101 @@ import runCommand from '../../../helpers/runCommand'
import * as nock from 'nock'
import {expect} from 'chai'
import heredoc from 'tsheredoc'
import {ux} from '@oclif/core'
import * as sinon from 'sinon'

describe('spaces:destroy', function () {
const now = new Date()

beforeEach(function () {
sinon.stub(ux, 'prompt').resolves('my-space')
})

afterEach(function () {
nock.cleanAll()
sinon.restore()
})

it('destroys a space', async function () {
it('shows extended NAT warning for fir generation space', async function () {
const api = nock('https://api.heroku.com')
.get('/spaces/my-space')
.reply(200, {name: 'my-space', team: {name: 'my-team'}, region: {name: 'my-region'}, state: 'allocated', created_at: now})
.reply(200, {
name: 'my-space',
team: {name: 'my-team'},
region: {name: 'my-region'},
state: 'allocated',
created_at: now,
generation: {name: 'fir'},
})
.get('/spaces/my-space/nat')
.reply(200, {state: 'enabled', sources: ['1.1.1.1', '2.2.2.2']})
.delete('/spaces/my-space')
.reply(200)

await runCommand(Cmd, ['--space', 'my-space', '--confirm', 'my-space'])
await runCommand(Cmd, ['--space', 'my-space'])
api.done()
const replacer = /([»])/g
expect(stderr.output.replace(replacer, '')).to.eq(heredoc(` › Warning: Destructive Action
› This command will destroy the space my-space
› === WARNING: Outbound IPs Will Be Reused
› ⚠️ Deleting this space frees up the following outbound IPv4 and IPv6 IPs
› for reuse:
› 1.1.1.1, 2.2.2.2
› Update the following configurations:
› = IP allowlists
› = Firewall rules
› = Security group configurations
› = Network ACLs
› Ensure that you remove the listed IPv4 and IPv6 addresses from your
› security configurations.
Destroying space my-space...
Destroying space my-space... done
`.replace(replacer, '')))
})

it('shows simple NAT warning for non-fir generation space', async function () {
const api = nock('https://api.heroku.com')
.get('/spaces/my-space')
.reply(200, {
name: 'my-space',
team: {name: 'my-team'},
region: {name: 'my-region'},
state: 'allocated',
created_at: now,
generation: {name: 'cedar'},
})
.get('/spaces/my-space/nat')
.reply(200, {state: 'enabled', sources: ['1.1.1.1', '2.2.2.2']})
.delete('/spaces/my-space')
.reply(200)

await runCommand(Cmd, ['--space', 'my-space'])
api.done()
const replacer = /([»])/g
expect(stderr.output.replace(replacer, '')).to.eq(heredoc(` › Warning: Destructive Action
› This command will destroy the space my-space
› === WARNING: Outbound IPs Will Be Reused
› ⚠️ Deleting this space frees up the following outbound IPv4 IPs for reuse:
› 1.1.1.1, 2.2.2.2
› Update the following configurations:
› = IP allowlists
› = Firewall rules
› = Security group configurations
› = Network ACLs
› Ensure that you remove the listed IPv4 addresses from your security
› configurations.
expect(stderr.output).to.eq(heredoc`
Destroying space my-space...
Destroying space my-space... done
`)
Destroying space my-space...
Destroying space my-space... done
`.replace(replacer, '')))
})
})

0 comments on commit 43d9164

Please sign in to comment.