UNPKG

@openzeppelin/defender-as-code

Version:
199 lines (198 loc) 11.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const prompt_1 = __importDefault(require("prompt")); const logger_1 = __importDefault(require("../utils/logger")); const utils_1 = require("../utils"); class DefenderRemove { constructor(serverless, options, logging) { this.serverless = serverless; this.options = options; this.logging = logging; this.resources = this.serverless.service.resources; this.log = logger_1.default.getInstance(); this.hooks = { 'before:remove:remove': () => this.validateKeys(), 'remove:remove': this.requestConfirmation.bind(this), }; } validateKeys() { this.teamKey = (0, utils_1.getTeamAPIkeysOrThrow)(this.serverless); } async wrapper(context, resourceType, resources, retrieveExistingResources, onRemove, output = []) { try { this.log.progress('component-info', `Retrieving ${resourceType}`); const existing = (await retrieveExistingResources()).filter((e) => (0, utils_1.isTemplateResource)(context, e, resourceType, resources ?? [])); this.log.progress('component-remove', `Removing ${resourceType} from Defender`); await onRemove(existing); output.push(...existing); } catch (e) { this.log.tryLogDefenderError(e); } } async requestConfirmation() { if (process.stdout.isTTY) { const properties = [ { name: 'confirm', validator: /^(y|n){1}$/i, warning: 'Confirmation must be `y` (yes) or `n` (no)', }, ]; prompt_1.default.start({ message: 'This action will remove your resources from Defender permanently. Are you sure you wish to continue [y/n]?', }); const { confirm } = await prompt_1.default.get(properties); if (confirm.toString().toLowerCase() !== 'y') { this.log.error('Confirmation not acquired. Terminating command'); return; } this.log.success('Confirmation acquired'); } await this.remove(); } async remove() { this.log.notice('========================================================'); const stackName = (0, utils_1.getStackName)(this.serverless); this.log.progress('remove', `Running Defender Remove on stack: ${stackName}`); const stdOut = { stack: stackName, monitors: [], actions: [], contracts: [], relayers: [], relayerGroups: [], notifications: [], secrets: [], forkedNetworks: [], privateNetworks: [], }; // Forked Networks const forkedNetworkClient = (0, utils_1.getNetworkClient)(this.teamKey); const listForkedNetworks = () => forkedNetworkClient.listForkedNetworks(); await this.wrapper(this.serverless, 'Forked Networks', (0, utils_1.removeDefenderIdReferences)(this.resources?.['forked-networks']), listForkedNetworks, async (forkedNetworks) => { await Promise.all(forkedNetworks.map(async (e) => { this.log.progress('component-remove-extra', `Removing ${e.stackResourceId} (${e.tenantNetworkId}) from Defender`); await forkedNetworkClient.deleteForkedNetwork(e.tenantNetworkId); this.log.success(`Removed ${e.stackResourceId} (${e.tenantNetworkId})`); })); }, stdOut.forkedNetworks); // Private Networks const privateNetworkClient = (0, utils_1.getNetworkClient)(this.teamKey); const listPrivateNetworks = () => privateNetworkClient.listPrivateNetworks(); await this.wrapper(this.serverless, 'Private Networks', (0, utils_1.removeDefenderIdReferences)(this.resources?.['private-networks']), listPrivateNetworks, async (privateNetworks) => { await Promise.all(privateNetworks.map(async (e) => { this.log.progress('component-remove-extra', `Removing ${e.stackResourceId} (${e.tenantNetworkId}) from Defender`); await privateNetworkClient.deletePrivateNetwork(e.tenantNetworkId); this.log.success(`Removed ${e.stackResourceId} (${e.tenantNetworkId})`); })); }, stdOut.privateNetworks); // Monitors const monitorClient = (0, utils_1.getMonitorClient)(this.teamKey); const listMonitors = () => monitorClient.list().then((i) => i.items); await this.wrapper(this.serverless, 'Monitors', (0, utils_1.removeDefenderIdReferences)(this.resources?.monitors), listMonitors, async (monitors) => { await Promise.all(monitors.map(async (e) => { this.log.progress('component-remove-extra', `Removing ${e.stackResourceId} (${e.monitorId}) from Defender`); await monitorClient.delete(e.monitorId); this.log.success(`Removed ${e.stackResourceId} (${e.monitorId})`); })); }, stdOut.monitors); // Actions const actionClient = (0, utils_1.getActionClient)(this.teamKey); const listActions = () => actionClient.list().then((i) => i.items); await this.wrapper(this.serverless, 'Actions', (0, utils_1.removeDefenderIdReferences)(this.resources.actions), listActions, async (actions) => { await Promise.all(actions.map(async (e) => { this.log.progress('component-remove-extra', `Removing ${e.stackResourceId} (${e.actionId}) from Defender`); await actionClient.delete(e.actionId); this.log.success(`Removed ${e.stackResourceId} (${e.actionId})`); })); }, stdOut.actions); // Contracts const adminClient = (0, utils_1.getProposalClient)(this.teamKey); const listContracts = () => adminClient.listContracts(); await this.wrapper(this.serverless, 'Contracts', (0, utils_1.removeDefenderIdReferences)(this.resources?.contracts), listContracts, async (contracts) => { await Promise.all(contracts.map(async (e) => { const id = `${e.network}-${e.address}`; this.log.progress('component-remove-extra', `Removing ${id} (${e.name}) from Defender`); await adminClient.deleteContract(id); this.log.success(`Removed ${id} (${e.name})`); })); }, stdOut.contracts); try { // Relayer API keys const relayClient = (0, utils_1.getRelayClient)(this.teamKey); const listRelayers = (await relayClient.list()).items; const existingRelayers = listRelayers.filter((e) => (0, utils_1.isTemplateResource)(this.serverless, e, 'Relayers', (0, utils_1.removeDefenderIdReferences)(this.resources?.relayers) ?? {})); this.log.error('Deleting Relayers is currently only possible via the Defender UI.'); this.log.progress('component-info', `Retrieving Relayer API Keys`); await Promise.all(existingRelayers.map(async (relayer) => { this.log.progress('component-info', `Retrieving API Keys for relayer ${relayer.stackResourceId}`); const relayerApiKeys = await relayClient.listKeys(relayer.relayerId); await Promise.all(relayerApiKeys.map(async (e) => { this.log.progress('component-remove-extra', `Removing ${e.stackResourceId} (${e.keyId}) from Defender`); await relayClient.deleteKey(e.relayerId, e.keyId); this.log.success(`Removed ${e.stackResourceId} (${e.keyId})`); })); stdOut.relayers.push({ relayerId: relayer.relayerId, relayerApiKeys, }); })); } catch (e) { this.log.tryLogDefenderError(e); } try { // Relayer Group API keys const relayGroupClient = (0, utils_1.getRelayGroupClient)(this.teamKey); const listRelayerGroups = await relayGroupClient.list(); const existingRelayerGroups = listRelayerGroups.filter((e) => (0, utils_1.isTemplateResource)(this.serverless, e, 'Relayer Groups', (0, utils_1.removeDefenderIdReferences)(this.resources?.['relayer-groups']) ?? {})); this.log.error('Deleting Relayer Groups is currently only possible via the Defender UI.'); this.log.progress('component-info', `Retrieving Relayer Group API Keys`); await Promise.all(existingRelayerGroups.map(async (relayerGroup) => { this.log.progress('component-info', `Retrieving API Keys for relayer group ${relayerGroup.stackResourceId}`); const relayerGroupApiKeys = await relayGroupClient.listKeys(relayerGroup.relayerGroupId); await Promise.all(relayerGroupApiKeys.map(async (e) => { this.log.progress('component-remove-extra', `Removing ${e.stackResourceId} (${e.keyId}) from Defender`); await relayGroupClient.deleteKey(e.relayerId, e.keyId); this.log.success(`Removed ${e.stackResourceId} (${e.keyId})`); })); stdOut.relayerGroups.push({ relayerGroupId: relayerGroup.relayerGroupId, relayerGroupApiKeys, }); })); } catch (e) { this.log.tryLogDefenderError(e); } // Notifications const listNotifications = () => monitorClient.listNotificationChannels(); await this.wrapper(this.serverless, 'Notifications', (0, utils_1.removeDefenderIdReferences)(this.resources?.notifications), listNotifications, async (notifications) => { await Promise.all(notifications.map(async (e) => { this.log.progress('component-remove-extra', `Removing ${e.stackResourceId} (${e.notificationId}) from Defender`); await monitorClient.deleteNotificationChannel(e.notificationId, e.type); this.log.success(`Removed ${e.stackResourceId} (${e.notificationId})`); })); }, stdOut.notifications); // Secrets const listSecrets = () => actionClient.listSecrets().then((r) => r.secretNames ?? []); const allSecrets = (0, utils_1.getConsolidatedSecrets)(this.serverless, this.resources); await this.wrapper(this.serverless, 'Secrets', allSecrets, listSecrets, async (secrets) => { this.log.progress('component-remove-extra', `Removing (${secrets.join(', ')}) from Defender`); await actionClient.createSecrets({ deletes: secrets, secrets: {}, }); if (secrets.length) this.log.success(`Removed (${secrets.join(', ')})`); }, stdOut.secrets); this.log.notice('========================================================'); if (!process.stdout.isTTY) this.log.stdOut(JSON.stringify(stdOut, null, 2)); } } exports.default = DefenderRemove;