Sindbad~EG File Manager
<?php
namespace App\Processor;
use App\Orm\RedisEntityManager;
use App\Service\Ocsp\OcspFetcher;
use App\Service\Ocsp\OcspResponse;
use O2switch\CpanelLib\Client\OpenrestyInternalApi;
use App\Entity\Redis\VhostEntity;
use App\Repository\Redis\VhostRepository;
use App\Traits\VerboseProcessor;
/**
* Take data from the Parser or DataTransformer and load this into a Redis DB for the Openresty server
* Class RedisVhost
* @package O2switch\Processor
*/
class OpenrestyProcessor implements ProcessorInterface
{
use VerboseProcessor;
/** @var VhostRepository */
private $vhostRepository;
/** @var OpenrestyInternalApi */
private $openrestyApiClient;
/** @var RedisEntityManager */
private $redisEm;
/** @var string */
private $cpUserdataDir;
/** @var int */
private $period;
/** @var bool */
protected $verbosity = false;
protected $output = null;
/**
* @var OcspFetcher
*/
private $ocspFetcher;
public function __construct(VhostRepository $vhostRepository, RedisEntityManager $redisEm, OpenrestyInternalApi $api,
OcspFetcher $ocspFetcher, int $period, string $cpUserdataDir)
{
$this->vhostRepository = $vhostRepository;
$this->period = $period + 10;
$this->openrestyApiClient = $api;
$this->redisEm = $redisEm;
$this->cpUserdataDir = $cpUserdataDir;
$this->ocspFetcher = $ocspFetcher;
}
public function generate(array $data, ?string $domainToUpdate = null) : bool{
$pipe = $this->redisEm->getPipeline();
$this->debug("Starting to generate/inserting data");
$i = 0;
foreach($data as $k => $vhost){
// Important : this bug was a real pain in the ass to found...
// Flush the pipe regularly otherwise it will block redis for too long. Don't flush all at the end.
// Then openresty will start to send SSL error because it can't retrieve data from redis
if($i > 30){
$this->redisEm->executePipeline($pipe);
$pipe = $this->redisEm->getPipeline();
$i = 0;
}
$this->debug("Working on : $k");
// Purge the OpenResty internal cache if something changed in the userdata of the user
// Or if the SSL file changed
if(isset($vhost['cpUser']) && !empty($vhost['cpUser']) &&
time() - (60*25+180) < filemtime($this->cpUserdataDir . $vhost['cpUser'])){
// Kind of brute force ...
$this->debug("Purging Openresty internal cache for $k (userdata were changed)");
$this->openrestyApiClient->purgeDomain($k);
} elseif(isset($vhost['sslCertificateFilepath'])){
if(time() - (60*25+180) < filemtime($vhost['sslCertificateFilepath'])){
$this->debug("Purging Openresty internal cache for $k (ssl files were changed)");
$this->openrestyApiClient->purgeDomain($k);
}
} elseif(!empty($domainToUpdate)){
$this->openrestyApiClient->purgeDomain($k);
}
$this->debug("Inserting " . $k . " data");
$vhostEntity = (new VhostEntity())->createFromArray($k, $vhost);
$pem = null;
if(!empty($vhostEntity->getRawSslContent())){
$pem = $this->ocspFetcher->extractCertificateFromPemString($vhostEntity->getRawSslContent());
}
if(!empty($pem)) {
$ocspResponse = $this->ocspFetcher->fetchOcsp($pem);
}
if(isset($ocspResponse) && $ocspResponse instanceof OcspResponse && $ocspResponse->isValid()){
$vhostEntity->setOcsp($ocspResponse->getDerOcspResponse());
}
$this->redisEm->persist($vhostEntity, $pipe);
$i++;
}
if($domainToUpdate === null) {
$this->removeOldVhost($data);
}
$this->redisEm->executePipeline($pipe);
return true;
}
public function removeOldVhost($data){
$this->debug("Checking if we need to remove old vhosts/data");
$keys = $this->vhostRepository->getAllKeys();
$pipe = $this->redisEm->getPipeline();
$i = 0;
foreach($keys as $k){
if(!isset($data[$k])){
// Important : this bug was a real pain in the ass to found...
// Flush the pipe regularly otherwise it will block redis for too long. Don't flush all at the end.
// Then openresty will start to send SSL error because it can't retrieve data from redis
if($i > 30){
$this->redisEm->executePipeline($pipe);
$pipe = $this->redisEm->getPipeline();
$i = 0;
}
$this->debug("Removing old data and purging OpenResty internal cache for " . $k);
$this->openrestyApiClient->purgeDomain($k);
$this->redisEm->remove((new VhostEntity())->setKey($k), false, $pipe);
$i++;
}
}
$this->redisEm->executePipeline($pipe);
return true;
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists