-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce a new helper command
cleanup
to delete unused resources c…
…reated by aws-simple. Currently, this command is used to find and delete REST-API CloudWatch roles that are no longer associated to a stack (see issue #169). In addition, the CDK is now required in version `^2.38.0`.
- Loading branch information
Showing
8 changed files
with
358 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import {APIGatewayClient, GetAccountCommand} from '@aws-sdk/client-api-gateway'; | ||
import type {CommandModule} from 'yargs'; | ||
import {deleteRole} from './sdk/delete-role.js'; | ||
import {findRoles} from './sdk/find-roles.js'; | ||
import {findStackResourceIds} from './sdk/find-stack-resource-ids.js'; | ||
import {findStacks} from './sdk/find-stacks.js'; | ||
import {print} from './utils/print.js'; | ||
|
||
const commandName = `cleanup`; | ||
|
||
export const cleanupCommand: CommandModule<{}, {readonly yes: boolean}> = { | ||
command: `${commandName} [options]`, | ||
describe: `Deletes unused account-wide resources created by aws-simple.`, | ||
|
||
builder: (argv) => | ||
argv | ||
.options(`yes`, { | ||
describe: `Confirm the deletion of unused account-wide resources`, | ||
boolean: true, | ||
default: false, | ||
}) | ||
.example([[`npx $0 ${commandName}`], [`npx $0 ${commandName} --yes`]]), | ||
|
||
handler: async (args): Promise<void> => { | ||
print.info(`Searching unused account-wide resources...`); | ||
|
||
const stacks = await findStacks(); | ||
const allResourceIds = new Set<string>(); | ||
|
||
for (const stack of stacks) { | ||
if (stack.StackName) { | ||
const resourceIds = await findStackResourceIds(stack.StackName); | ||
|
||
for (const resourceId of resourceIds) { | ||
allResourceIds.add(resourceId); | ||
} | ||
} | ||
} | ||
|
||
const client = new APIGatewayClient({}); | ||
const {cloudwatchRoleArn} = await client.send(new GetAccountCommand({})); | ||
|
||
const roleNames = (await findRoles()) | ||
.filter( | ||
(role) => | ||
role.RoleName?.startsWith(`aws-simple-`) && | ||
role.Arn?.includes(`RestApiCloudWatchRole`) && | ||
role.Arn !== cloudwatchRoleArn && | ||
!allResourceIds.has(role.RoleName), | ||
) | ||
.map((role) => role.RoleName!); | ||
|
||
if (roleNames.length === 0) { | ||
print.success(`No unused account-wide resources found.`); | ||
|
||
return; | ||
} | ||
|
||
for (const roleName of roleNames) { | ||
print.listItem(0, { | ||
type: `entry`, | ||
key: `REST-API CloudWatch role`, | ||
value: roleName, | ||
}); | ||
} | ||
|
||
if (args.yes) { | ||
print.warning( | ||
`The found account-wide resources will be deleted automatically.`, | ||
); | ||
} else { | ||
const confirmed = await print.confirmation( | ||
`Confirm to delete the found account-wide resources.`, | ||
); | ||
|
||
if (!confirmed) { | ||
return; | ||
} | ||
} | ||
|
||
print.info(`Deleting the found account-wide resources...`); | ||
|
||
const results = await Promise.allSettled( | ||
roleNames.map(async (roleName) => deleteRole(roleName)), | ||
); | ||
|
||
const rejectedResults = results.filter( | ||
(result): result is PromiseRejectedResult => result.status === `rejected`, | ||
); | ||
|
||
if (rejectedResults.length > 0) { | ||
for (const {reason} of rejectedResults) { | ||
print.error(String(reason)); | ||
} | ||
|
||
process.exit(1); | ||
} else { | ||
print.success( | ||
`The found account-wide resources have been successfully deleted.`, | ||
); | ||
} | ||
}, | ||
}; |
Oops, something went wrong.