diff --git a/packages/cli/src/commands/spaces/destroy.ts b/packages/cli/src/commands/spaces/destroy.ts index f5fd959cf0..ce6d535728 100644 --- a/packages/cli/src/commands/spaces/destroy.ts +++ b/packages/cli/src/commands/spaces/destroy.ts @@ -5,6 +5,7 @@ import * as Heroku from '@heroku-cli/schema' import heredoc from 'tsheredoc' import confirmCommand from '../../lib/confirmCommand' import {displayNat} from '../../lib/spaces/spaces' +import chalk from 'chalk' type RequiredSpaceWithNat = Required & {outbound_ips?: Required} @@ -43,7 +44,19 @@ export default class Destroy extends Command { if (space.state === 'allocated') { ({body: space.outbound_ips} = await this.heroku.get>(`/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` + natWarning = heredoc` + ${chalk.dim('===')} ${chalk.bold('WARNING: Outbound IPs Will Be Reused')} + ${chalk.yellow('⚠️ The following outbound IPs (IPv4 and IPv6) will become available for reuse:')} + ${chalk.bold(displayNat(space.outbound_ips) ?? '')} + + ${chalk.dim('Please update the following configurations:')} + ${chalk.dim('=')} IP allowlists + ${chalk.dim('=')} Firewall rules + ${chalk.dim('=')} Security group configurations + ${chalk.dim('=')} Network ACLs + + ${chalk.yellow('Ensure all IPv4 and IPv6 addresses are removed from your security configurations.')} + ` } } diff --git a/packages/cli/test/unit/commands/spaces/destroy.unit.test.ts b/packages/cli/test/unit/commands/spaces/destroy.unit.test.ts index 2bea983a55..f9d3e3d10d 100644 --- a/packages/cli/test/unit/commands/spaces/destroy.unit.test.ts +++ b/packages/cli/test/unit/commands/spaces/destroy.unit.test.ts @@ -1,15 +1,21 @@ -import {stderr} from 'stdout-stderr' +import { stderr, stdout } from 'stdout-stderr' import Cmd from '../../../../src/commands/spaces/destroy' 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 () { @@ -21,13 +27,29 @@ describe('spaces:destroy', function () { .delete('/spaces/my-space') .reply(200) - await runCommand(Cmd, ['--space', 'my-space', '--confirm', 'my-space']) - + await runCommand(Cmd, ['--space', 'my-space']) api.done() - expect(stderr.output).to.eq(heredoc` - Destroying space my-space... - Destroying space my-space... done + expect(stderr.output).to.eq(heredoc` › Warning: Destructive Action + › This command will destroy the space my-space + › === WARNING: Outbound IPs Will Be Reused + › ⚠️ The following outbound IPs (IPv4 and IPv6) will become available for + › reuse: + › 1.1.1.1, 2.2.2.2 + › + › Please update the following configurations: + › = IP allowlists + › = Firewall rules + › = Security group configurations + › = Network ACLs + › + › Ensure all IPv4 and IPv6 addresses are removed from your security + › configurations. + › + › + + Destroying space my-space... + Destroying space my-space... done `) }) })