From 3d0d23b704c138bc23684df3d12f0e18931e5a1a Mon Sep 17 00:00:00 2001 From: marc Date: Tue, 30 Apr 2024 16:05:20 +0200 Subject: [PATCH 1/2] add command manage:describe-organization-workspaces --- cli.php | 2 + .../DescribeOrganizationWorkspaces.php | 147 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/Keboola/Console/Command/DescribeOrganizationWorkspaces.php diff --git a/cli.php b/cli.php index 1f92b82..97b8f6f 100644 --- a/cli.php +++ b/cli.php @@ -9,6 +9,7 @@ use Keboola\Console\Command\DeleteOrganizationOrphanedWorkspaces; use Keboola\Console\Command\DeleteOrphanedWorkspaces; use Keboola\Console\Command\DeleteOwnerlessWorkspaces; +use Keboola\Console\Command\DescribeOrganizationWorkspaces; use Keboola\Console\Command\LineageEventsExport; use Keboola\Console\Command\MassDedup; use Keboola\Console\Command\MassProjectEnableDynamicBackends; @@ -57,4 +58,5 @@ $application->add(new DeleteProjectSandboxes()); $application->add(new RemoveUserFromOrganizationProjects()); $application->add(new ReactivateSchedules()); +$application->add(new DescribeOrganizationWorkspaces()); $application->run(); diff --git a/src/Keboola/Console/Command/DescribeOrganizationWorkspaces.php b/src/Keboola/Console/Command/DescribeOrganizationWorkspaces.php new file mode 100644 index 0000000..042dd59 --- /dev/null +++ b/src/Keboola/Console/Command/DescribeOrganizationWorkspaces.php @@ -0,0 +1,147 @@ +setName('manage:describe-organization-workspaces') + ->setDescription('Describe workspaces of this organization.') + ->addArgument( + 'manageToken', + InputArgument::REQUIRED, + 'Keboola Storage API token to use' + ) + ->addArgument( + 'organizationId', + InputArgument::REQUIRED, + 'ID of the organization to clean' + ) + ->addArgument( + 'outputFile', + InputArgument::REQUIRED, + 'file to output the csv results' + ) + ->addArgument( + 'hostnameSuffix', + InputArgument::OPTIONAL, + 'Keboola Connection Hostname Suffix', + 'keboola.com' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): void + { + $manageToken = $input->getArgument('manageToken'); + $organizationId = $input->getArgument('organizationId'); + $outputFile = $input->getArgument('outputFile'); + $kbcUrl = sprintf('https://connection.%s', $input->getArgument('hostnameSuffix')); + $manageClient = new Client(['token' => $manageToken, 'url' => $kbcUrl]); + $organization = $manageClient->getOrganization($organizationId); + $projects = $organization['projects']; + $output->writeln( + sprintf( + 'Checking workspaces for "%d" projects', + count($projects) + ) + ); + + $storageUrl = 'https://connection.' . $input->getArgument('hostnameSuffix'); + + $totalWorkspaces = 0; + $totalDeletedWorkspaces = 0; + + $csvFile = new CsvFile($outputFile); + $csvFile->writeRow([ + 'projectId', + 'projectName', + 'branchId', + 'branchName', + 'componentId', + 'configurationId', + 'creatorEmail', + 'createdDate', + 'snowflakeSchema', + 'readOnlyStorageAccess' + ]); + + foreach ($projects as $project) { + $storageToken = $manageClient->createProjectStorageToken( + $project['id'], + ['description' => 'Fetching Workspace Details'] + ); + $storageClient = new StorageApiClient([ + 'token' => $storageToken['token'], + 'url' => $storageUrl, + ]); + $devBranches = new DevBranches($storageClient); + $branchesList = $devBranches->listBranches(); + $output->writeln( + sprintf( + 'Retrieving workspaces for project %s : %s ', + $project['id'], + $project['name'] + ) + ); + $totalProjectWorkspaces = 0; + foreach ($branchesList as $branch) { + $branchId = $branch['id']; + $branchStorageClient = new BranchAwareClient($branchId, [ + 'token' => $storageToken['token'], + 'url' => $storageUrl, + ]); + $workspacesClient = new Workspaces($branchStorageClient); + $workspaceList = $workspacesClient->listWorkspaces(); + $output->writeln('Found ' . count($workspaceList) . ' workspaces in branch ' . $branch['name']); + $totalProjectWorkspaces += count($workspaceList); + foreach ($workspaceList as $workspace) { + $row = [ + $project['id'], + $project['name'], + $branch['id'], + $branch['name'], + $workspace['component'], + $workspace['configurationId'], + $workspace['creatorToken']['description'], + $workspace['created'], + $workspace['name'], + $workspace['readOnlyStorageAccess'] + ]; + $csvFile->writeRow($row); + $totalProjectWorkspaces ++; + + } + } + $output->writeln( + sprintf( + 'Project %s has a total of %d workspaces.', + $project['id'], + $totalProjectWorkspaces + ) + ); + $tokensClient = new Tokens($storageClient); + $tokensClient->dropToken($storageToken['id']); + + $totalWorkspaces += $totalProjectWorkspaces; + } + $output->writeln( + sprintf( + 'A grand total of %d workspaces in this organisation', + $totalWorkspaces + ) + ); + } +} From bc2564e4211a30f37b883283b92eaf819c2fdeec Mon Sep 17 00:00:00 2001 From: marc Date: Tue, 30 Apr 2024 16:15:04 +0200 Subject: [PATCH 2/2] cs fix + readme update --- README.md | 27 ++++++++++++++++++- .../DescribeOrganizationWorkspaces.php | 1 - 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cc80914..545d36c 100644 --- a/README.md +++ b/README.md @@ -277,7 +277,7 @@ It will perform a dry run unleass the `--force/-f` option is applied. Arguments: - Storage Token *required* -- Hostname sUffix *optional* (default: keboola.com) +- Hostname suffix *optional* (default: keboola.com) Options: - `--force/-f` @@ -288,6 +288,31 @@ Options: php ./cli.php storage:delete-ownerless-workspaces [--force/-f] [--includeShared] ``` +## Describe Connection Workspaces for an organization +This command takes an output file argument and writes out a csv describing all connection workspaces in an organisation. +The output file has header: +'projectId', +'projectName', +'branchId', +'branchName', +'componentId', +'configurationId', +'creatorEmail', +'createdDate', +'snowflakeSchema', +'readOnlyStorageAccess' + +Arguments: +- Manage Token *required* +- Organisation Id *required* +- Output File *required* +- Hostname suffix *optional* (default: keboola.com) + +- Run the command + ``` + php ./cli.php manage:describe-organization-workspaces + ``` + ## License MIT licensed, see [LICENSE](./LICENSE) file. diff --git a/src/Keboola/Console/Command/DescribeOrganizationWorkspaces.php b/src/Keboola/Console/Command/DescribeOrganizationWorkspaces.php index 042dd59..58ae32a 100644 --- a/src/Keboola/Console/Command/DescribeOrganizationWorkspaces.php +++ b/src/Keboola/Console/Command/DescribeOrganizationWorkspaces.php @@ -122,7 +122,6 @@ protected function execute(InputInterface $input, OutputInterface $output): void ]; $csvFile->writeRow($row); $totalProjectWorkspaces ++; - } } $output->writeln(