diff --git a/README.md b/README.md index 5e564a1..2a7e1a6 100644 --- a/README.md +++ b/README.md @@ -385,6 +385,25 @@ You can use it to set all projects of an organization to use a storage backend. php ./cli.php manage:set-organization-storage-backend [--force/-f] ``` +## Delete Storage Backend +Delete one or more storage backends from a stack by their IDs. Dry-run by default. + +- Run the command + ``` + php ./cli.php manage:delete-backend [--force/-f] + ``` +Arguments: +- manage-token (required) Manage API token for the stack. +- backend-ids (required) Comma-separated list of storage backend IDs to delete (e.g. `123,456,789`). +- stack-url (required) Full stack URL, e.g. https://connection.keboola.com. + +Options: +- --force / -f Actually remove the backends. Without it the command runs in dry-run mode and only lists what would be removed. + +Behavior: +- Lists all storage backends on the stack. +- For each requested ID: skips it (with a message) when no such backend exists; otherwise prints the backend host and owner and (with --force) removes it via the Manage API. + ## Reset Workspace passwords for projects in an organization This command is rather specific to BYODB snowflake backend migration. It resets all legacy (not keypair type) Snowflake workspace passwords for all projects in an organization. diff --git a/cli.php b/cli.php index ddc6d18..6382762 100644 --- a/cli.php +++ b/cli.php @@ -6,6 +6,7 @@ use Keboola\Console\Command\AddFeature; use Keboola\Console\Command\AllStacksIterator; +use Keboola\Console\Command\DeleteStorageBackend; use Keboola\Console\Command\DeleteOrganizationOrphanedWorkspaces; use Keboola\Console\Command\DeleteOrganizationOwnerlessWorkspaces; use Keboola\Console\Command\DeleteOrphanedWorkspaces; @@ -57,4 +58,5 @@ $application->add(new UpdateDataRetention()); $application->add(new OrganizationResetWorkspacePasswords()); $application->add(new OrganizationsAddFeature()); +$application->add(new DeleteStorageBackend()); $application->run(); diff --git a/src/Keboola/Console/Command/DeleteStorageBackend.php b/src/Keboola/Console/Command/DeleteStorageBackend.php new file mode 100644 index 0000000..b87a451 --- /dev/null +++ b/src/Keboola/Console/Command/DeleteStorageBackend.php @@ -0,0 +1,73 @@ +setName('manage:delete-backend') + ->setDescription('Delete storage backends from a stack by their IDs. Dry-run by default.') + ->addArgument('token', InputArgument::REQUIRED, 'manage api token') + ->addArgument('ids', InputArgument::REQUIRED, 'list of storage backend IDs separated by a comma') + ->addArgument('url', InputArgument::REQUIRED, 'Stack URL') + ->addOption('force', 'f', InputOption::VALUE_NONE, 'Will actually do the work, otherwise it\'s dry run'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $apiToken = $input->getArgument('token'); + assert(is_string($apiToken)); + $apiUrl = $input->getArgument('url'); + assert(is_string($apiUrl)); + $ids = $input->getArgument('ids'); + assert(is_string($ids)); + $force = (bool) $input->getOption('force'); + $output->writeln($force ? 'DANGER: Using force mode! Backend will be removed.' : 'DRY RUN'); + + $client = $this->createClient($apiUrl, $apiToken); + + $allBackends = $client->listStorageBackend(); + $allBackendsAssociative = []; + foreach ($allBackends as $backend) { + $allBackendsAssociative[$backend['id']] = $backend; + } + $backendIds = array_filter(array_map('trim', explode(',', $ids)), 'is_numeric'); + foreach ($backendIds as $id) { + if (!array_key_exists($id, $allBackendsAssociative)) { + $output->writeln(sprintf('Backend with ID "%s" does not exist, skipping...', $id)); + continue; + } + $output->write(sprintf( + 'Removing backend "%s" (%s) by "%s" - ', + $id, + $allBackendsAssociative[$id]['host'], + $allBackendsAssociative[$id]['owner'] + )); + if ($force) { + $output->writeln('really'); + $client->removeStorageBackend((int) $id); + } else { + $output->writeln('just kidding - dry mode'); + } + } + + return 0; + } + + private function createClient(string $host, string $token): Client + { + return new Client([ + 'url' => $host, + 'token' => $token, + ]); + } +}