-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathremove.ts
122 lines (107 loc) · 4.31 KB
/
remove.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import {HTTP, HTTPError} from '@heroku/http-call'
import color from '@heroku-cli/color'
import {Command, flags} from '@heroku-cli/command'
import {ux} from '@oclif/core'
import {applyActionSpinner} from '../../../async-actions'
import {getBorealisPgApiUrl, getBorealisPgAuthHeader} from '../../../borealis-api'
import {
addonOptionName,
appOptionName,
cliArgs,
cliOptions,
consoleColours,
pgExtensionArgName,
processAddonAttachmentInfo,
} from '../../../command-components'
import {createHerokuAuth, fetchAddonAttachmentInfo, removeHerokuAuth} from '../../../heroku-api'
const pgExtensionColour = consoleColours.pgExtension
const confirmOptionName = 'confirm'
const suppressMissingOptionName = 'suppress-missing'
const addonResourceType = 'addon'
export default class RemovePgExtensionCommand extends Command {
static description =
'removes a Postgres extension from a Borealis Isolated Postgres add-on database'
static examples = [
`$ heroku borealis-pg:extensions:remove --${suppressMissingOptionName} --${appOptionName} sushi postgis`,
`$ heroku borealis-pg:extensions:remove --${appOptionName} sushi --${addonOptionName} BOREALIS_PG_MAROON btree_gist`,
`$ heroku borealis-pg:extensions:remove --${confirmOptionName} uuid-ossp --${addonOptionName} borealis-pg-hex-12345 uuid-ossp`,
]
static args = {
[pgExtensionArgName]: cliArgs.pgExtension,
}
static flags = {
[addonOptionName]: cliOptions.addon,
[appOptionName]: cliOptions.app,
[confirmOptionName]: flags.string({
char: 'c',
description: 'bypass the prompt for confirmation by specifying the name of the extension',
}),
[suppressMissingOptionName]: flags.boolean({
char: 's',
default: false,
description: 'suppress nonzero exit code when an extension is not installed',
}),
}
async run() {
const {args, flags} = await this.parse(RemovePgExtensionCommand)
const pgExtension = args[pgExtensionArgName]
const suppressMissing = flags[suppressMissingOptionName]
const confirmation = flags.confirm ?
flags.confirm :
(await ux.prompt('Enter the name of the extension to confirm its removal'))
if (confirmation.trim() !== pgExtension) {
this.error(`Invalid confirmation provided. Expected ${pgExtensionColour(pgExtension)}.`)
}
const authorization = await createHerokuAuth(this.heroku)
const attachmentInfo =
await fetchAddonAttachmentInfo(this.heroku, flags.addon, flags.app, this.error)
const {addonName} = processAddonAttachmentInfo(attachmentInfo, this.error)
try {
await applyActionSpinner(
`Removing Postgres extension ${pgExtensionColour(pgExtension)} from add-on ${color.addon(addonName)}`,
HTTP.delete(
getBorealisPgApiUrl(`/heroku/resources/${addonName}/pg-extensions/${pgExtension}`),
{headers: {Authorization: getBorealisPgAuthHeader(authorization)}}),
)
} catch (error) {
if (
error instanceof HTTPError &&
error.statusCode === 404 &&
error.body.resourceType !== addonResourceType &&
suppressMissing) {
this.warn(getNotInstalledMessage(pgExtension))
} else {
throw error
}
} finally {
await removeHerokuAuth(this.heroku, authorization.id as string)
}
}
async catch(err: any) {
const {args} = await this.parse(RemovePgExtensionCommand)
const pgExtension = args[pgExtensionArgName]
/* istanbul ignore else */
if (err instanceof HTTPError) {
if (err.statusCode === 400) {
this.error(
`Extension ${pgExtensionColour(pgExtension)} has dependent extensions or objects. ` +
'It can only be removed after its dependents are removed first.')
} else if (err.statusCode === 404) {
if (err.body.resourceType === addonResourceType) {
this.error('Add-on is not a Borealis Isolated Postgres add-on')
} else {
this.error(getNotInstalledMessage(pgExtension))
}
} else if (err.statusCode === 422) {
this.error('Add-on is not finished provisioning')
} else {
this.error('Add-on service is temporarily unavailable. Try again later.')
}
} else {
throw err
}
}
}
function getNotInstalledMessage(pgExtension: string): string {
return `Extension ${pgExtensionColour(pgExtension)} is not installed`
}