Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,28 @@ Command execution:
cat data.csv | php cli.php storage:notify-projects MANAGETOKEN
```


### Force Unlink Shared and Linked Buckets

List all buckets in the project and force-unlink those that are both shared and linked. By default, the command runs in dry-run mode and only reports what would be unlinked. Use the `--force` flag to actually perform the unlinking.

```
php cli.php storage:force-unlink-shared-buckets [--force|-f] <storageToken> <url>
```
Arguments:
- `storageToken` (required): Storage API token for the target project.
- `url` (required): Stack URL, including `https://`.

Options:
- `--force` / `-f`: Actually perform the unlinking. Without this flag, the command only reports what would be unlinked (dry-run).

Behavior:
- Lists all buckets in the project.
- For each bucket, checks if it is both shared and linked.
- In dry-run mode, lists the buckets that would be unlinked.
- With `--force`, unlinks each shared and linked bucket and confirms the action.
- Prints a summary of unlinked or would-be-unlinked buckets.

### Mass enablement of dynamic backends for multiple projects
Prerequisities: https://keboola.atlassian.net/wiki/spaces/KB/pages/2135982081/Enable+Dynamic+Backends#Enable-for-project

Expand Down Expand Up @@ -433,6 +455,7 @@ Behavior:
- If the user is a member, logs removal (and performs it if forced).
- Prints final count of affected projects.


# License

MIT licensed, see [LICENSE](./LICENSE) file.
2 changes: 2 additions & 0 deletions cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use Symfony\Component\Console\Application;
use Keboola\Console\Command\SetDataRetention;
use Keboola\Console\Command\UpdateDataRetention;
use Keboola\Console\Command\ForceUnlinkSharedBuckets;

$application = new Application();
$application->add(new ProjectsAddFeature());
Expand All @@ -55,4 +56,5 @@
$application->add(new MassDeleteProjectWorkspaces());
$application->add(new UpdateDataRetention());
$application->add(new OrganizationResetWorkspacePasswords());
$application->add(new ForceUnlinkSharedBuckets());
$application->run();
61 changes: 61 additions & 0 deletions src/Keboola/Console/Command/ForceUnlinkSharedBuckets.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Keboola\Console\Command;

use Keboola\StorageApi\Client as StorageApiClient;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class ForceUnlinkSharedBuckets extends Command
{
protected function configure()
{
$this
->setName('storage:force-unlink-shared-buckets')
->setDescription('List all buckets in the project and force-unlink those that are shared BY this project and linked TO other projects.')
->addArgument('storageToken', InputArgument::REQUIRED, 'Keboola Storage API token to use')
->addArgument('url', InputArgument::REQUIRED, 'stack URL. Including https://')
->addOption('force', 'f', InputOption::VALUE_NONE, 'Use [--force, -f] to actually unlink. Otherwise, dry-run.');
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$token = $input->getArgument('storageToken');
$url = $input->getArgument('url');
$isForce = $input->getOption('force');
$prefix = $isForce ? 'FORCE: ' : 'DRY-RUN: ';

$client = new StorageApiClient([
'token' => $token,
'url' => $url,
]);

$buckets = $client->listBuckets(['include' => 'linkedBuckets']);

foreach ($buckets as $bucket) {
if (array_key_exists('linkedBy', $bucket)) {
foreach ($bucket['linkedBy'] as $link) {
if ($isForce) {
$client->forceUnlinkBucket($bucket['id'], $link['project']['id']);
}
$output->writeln(
sprintf(
'%s bucket "%s" force unlinked from project "%s" (%s)',
$prefix,
$bucket['id'],
$link['project']['name'],
$link['project']['id'],
)
);
}
} else {
$output->writeln(sprintf('No linked buckets found for bucket "%s"', $bucket['id']));
}
}

return 0;
}
}