Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Cleanup Command to service #92

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
66 changes: 14 additions & 52 deletions src/Command/Cleanup.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@

namespace Valantic\ElasticaBridgeBundle\Command;

use Elastic\Elasticsearch\Exception\ElasticsearchException;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Valantic\ElasticaBridgeBundle\Constant\CommandConstants;
use Valantic\ElasticaBridgeBundle\Elastica\Client\ElasticsearchClient;
use Valantic\ElasticaBridgeBundle\Repository\IndexRepository;
use Valantic\ElasticaBridgeBundle\Service\CleanupService;

class Cleanup extends BaseCommand
{
use NonBundleIndexTrait;
private const OPTION_ALL_IN_CLUSTER = 'all';
private const OPTION_DRY_RUN = 'dry-run';

public function __construct(
private readonly ElasticsearchClient $esClient,
private readonly IndexRepository $indexRepository,
private readonly CleanupService $cleanupService,
) {
parent::__construct();
}
Expand All @@ -30,6 +28,7 @@ protected function configure(): void
{
$this->setName(CommandConstants::COMMAND_CLEANUP)
->setDescription('Deletes Elasticsearch indices and aliases known to (i.e. created by) the bundle')
->addOption(self::OPTION_DRY_RUN, 'd', InputOption::VALUE_NONE, 'Only simulate the cleanup')
->addOption(
self::OPTION_ALL_IN_CLUSTER,
'a',
Expand All @@ -45,63 +44,26 @@ protected function execute(InputInterface $input, OutputInterface $output): int
? 'Deleting ALL indices in the cluster'
: 'Only deleting KNOWN indices'
);
$verb = $this->input->getOption(self::OPTION_DRY_RUN) === true
? 'simulate'
: 'proceed';
/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion('Are you sure you want to proceed deleting indices and aliases? (y/N)', false);
$question = new ConfirmationQuestion(sprintf('Are you sure you want to %s deleting indices and aliases? (y/N)', $verb), false);

if ($helper->ask($input, $output, $question) === false) {
return self::FAILURE;
}

$indices = $this->getIndices();

foreach ($indices as $index) {
if (!$this->shouldProcessNonBundleIndex($index)) {
continue;
}

$client = $this->esClient->getIndex($index);

if ($client->getSettings()->getBool('hidden')) {
continue;
}

foreach ($client->getAliases() as $alias) {
$client->removeAlias($alias);
}
$messages = $this->cleanupService->cleanUp(
$this->input->getOption(self::OPTION_ALL_IN_CLUSTER) === true,
$this->input->getOption(self::OPTION_DRY_RUN) === true
);

try {
$client->delete();
} catch (ElasticsearchException $e) {
$this->output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
}
foreach ($messages as $message) {
$this->output->writeln($message);
}

return self::SUCCESS;
}

/**
* @return string[]
*/
private function getIndices(): array
{
if ($this->input->getOption(self::OPTION_ALL_IN_CLUSTER) === true) {
return $this->esClient->getCluster()->getIndexNames();
}

$indices = [];

foreach ($this->indexRepository->flattenedAll() as $indexConfig) {
if ($indexConfig->usesBlueGreenIndices()) {
$indices[] = $indexConfig->getBlueGreenActiveElasticaIndex()->getName();
$indices[] = $indexConfig->getBlueGreenInactiveElasticaIndex()->getName();

continue;
}

$indices[] = $indexConfig->getName();
}

return $indices;
}
}
101 changes: 101 additions & 0 deletions src/Service/CleanupService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

declare(strict_types=1);

namespace Valantic\ElasticaBridgeBundle\Service;

use Elastic\Elasticsearch\Exception\ClientResponseException;
use Elastic\Elasticsearch\Exception\ElasticsearchException;
use Elastic\Elasticsearch\Exception\MissingParameterException;
use Elastic\Elasticsearch\Exception\ServerResponseException;
use Valantic\ElasticaBridgeBundle\Elastica\Client\ElasticsearchClient;
use Valantic\ElasticaBridgeBundle\Repository\IndexRepository;

class CleanupService
{
public function __construct(
private readonly ElasticsearchClient $esClient,
private readonly IndexRepository $indexRepository,
) {}

/**
* @param bool $allIndices
*
* @throws ClientResponseException
* @throws MissingParameterException
* @throws ServerResponseException
*
* @return \Generator<string>
*/
public function cleanUp(bool $allIndices = false, bool $dryRun = true): \Generator
{
if ($dryRun === true) {
yield '<info>DRY-RUN MODE</info>';
}

$indices = $this->getIndices($allIndices);

foreach ($indices as $index) {
if ($index === '.geoip_databases') {
continue;
}

$esIndex = $this->esClient->getIndex($index);

if ($esIndex->getSettings()->getBool('hidden')) {
continue;
}

foreach ($esIndex->getAliases() as $alias) {
if ($dryRun === true) {
yield sprintf('<info>Would remove alias %s from index %s</info>', $alias, $index);

continue;
}
$esIndex->removeAlias($alias);

yield sprintf('<info>Removed alias %s from index %s</info>', $alias, $index);
}

try {
if ($dryRun === true) {
yield sprintf('<info>Would delete index %s</info>', $index);

continue;
}
$esIndex->delete();

yield sprintf('<info>Deleted index %s</info>', $index);
} catch (ElasticsearchException $e) {
yield sprintf('<error>%s</error>', $e->getMessage());
}
}
}

/**
* @param bool $allIndices
*
* @return string[]
*/
private function getIndices(bool $allIndices = false): array
{
if ($allIndices === true) {
return $this->esClient->getCluster()->getIndexNames();
}

$indices = [];

foreach ($this->indexRepository->flattenedAll() as $indexConfig) {
if ($indexConfig->usesBlueGreenIndices()) {
$indices[] = $indexConfig->getBlueGreenActiveElasticaIndex()->getName();
$indices[] = $indexConfig->getBlueGreenInactiveElasticaIndex()->getName();

continue;
}

$indices[] = $indexConfig->getName();
}

return $indices;
}
}
Loading