forked from magento/ece-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MAGECLOUD-4076: Service EOL validation (magento#625)
- Loading branch information
1 parent
96c2b42
commit b1a882e
Showing
16 changed files
with
853 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Service EOLs (YYYY-MM-DD). | ||
php: | ||
- version: '7.0' | ||
eol: 2019-01-10 | ||
- version: '7.1' | ||
eol: 2019-12-01 | ||
- version: '7.2' | ||
eol: 2020-11-30 | ||
- version: '7.3' | ||
eol: 2021-12-06 | ||
mariadb: | ||
- version: '10.0' | ||
eol: 2019-03-31 | ||
- version: '10.1' | ||
eol: 2020-10-17 | ||
- version: '10.2' | ||
eol: 2022-05-23 | ||
elasticsearch: | ||
- version: '1.7' | ||
eol: 2017-01-16 | ||
- version: '2.4' | ||
eol: 2018-02-28 | ||
- version: '5.2' | ||
eol: 2018-07-31 | ||
- version: '6.5' | ||
eol: 2020-05-14 | ||
rabbitmq: | ||
- version: '3.5' | ||
eol: 2016-10-31 | ||
- version: '3.7' | ||
eol: 2020-03-31 | ||
redis: | ||
- version: '3.2' | ||
eol: | ||
- version: '4.0' | ||
eol: | ||
- version: '5.0' | ||
eol: | ||
- version: '5.2' | ||
eol: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\MagentoCloud\Config\Validator\Deploy; | ||
|
||
use Magento\MagentoCloud\Config\Validator; | ||
use Magento\MagentoCloud\Filesystem\FileSystemException; | ||
use Magento\MagentoCloud\Service\EolValidator as EOLValidator; | ||
use Magento\MagentoCloud\Config\ValidatorInterface; | ||
use Magento\MagentoCloud\Service\ServiceMismatchException; | ||
|
||
/** | ||
* Class to check if services approaching their EOLs. | ||
*/ | ||
class ServiceEol implements ValidatorInterface | ||
{ | ||
/** | ||
* @var integer | ||
*/ | ||
private $errorLevel; | ||
|
||
/** | ||
* @var Validator\ResultFactory | ||
*/ | ||
private $resultFactory; | ||
|
||
/** | ||
* @var EOLValidator | ||
*/ | ||
private $eolValidator; | ||
|
||
/** | ||
* @param Validator\ResultFactory $resultFactory | ||
* @param EOLValidator $eolValidator | ||
* @param int $errorLevel | ||
*/ | ||
public function __construct( | ||
Validator\ResultFactory $resultFactory, | ||
EOLValidator $eolValidator, | ||
int $errorLevel | ||
) { | ||
$this->resultFactory = $resultFactory; | ||
$this->eolValidator = $eolValidator; | ||
$this->errorLevel = $errorLevel; | ||
} | ||
|
||
/** | ||
* Get the defined services and versions and check for their EOLs by error level. | ||
* | ||
* @return Validator\ResultInterface | ||
* @throws FileSystemException | ||
*/ | ||
public function validate(): Validator\ResultInterface | ||
{ | ||
try { | ||
$errors = $this->eolValidator->validateServiceEol(); | ||
|
||
if (isset($errors[$this->errorLevel])) { | ||
$message = $this->errorLevel == ValidatorInterface::LEVEL_WARNING ? | ||
'Some services have passed EOL.' : | ||
'Some services are approaching EOL.'; | ||
return $this->resultFactory->error( | ||
$message, | ||
implode(PHP_EOL, $errors[$this->errorLevel]) | ||
); | ||
} | ||
} catch (ServiceMismatchException $e) { | ||
return $this->resultFactory->error('Can\'t validate version of some services: ' . $e->getMessage()); | ||
} | ||
|
||
return $this->resultFactory->success(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\MagentoCloud\Service; | ||
|
||
use Carbon\Carbon; | ||
use Composer\Semver\Semver; | ||
use Magento\MagentoCloud\Config\ValidatorInterface; | ||
use Magento\MagentoCloud\Filesystem\Driver\File; | ||
use Magento\MagentoCloud\Filesystem\FileList; | ||
use Magento\MagentoCloud\Filesystem\FileSystemException; | ||
use Symfony\Component\Yaml\Yaml; | ||
|
||
/** | ||
* Service EOL validator. | ||
* | ||
* Class EolValidator | ||
*/ | ||
class EolValidator | ||
{ | ||
/** | ||
* Set the notification period. | ||
*/ | ||
private const NOTIFICATION_PERIOD = 3; | ||
|
||
/** | ||
* @var FileList | ||
*/ | ||
private $fileList; | ||
|
||
/** | ||
* @var File | ||
*/ | ||
private $file; | ||
|
||
/** | ||
* @var ServiceFactory | ||
*/ | ||
private $serviceFactory; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private $eolConfigs; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private $services = [ | ||
ServiceInterface::NAME_PHP, | ||
ServiceInterface::NAME_ELASTICSEARCH, | ||
ServiceInterface::NAME_RABBITMQ, | ||
ServiceInterface::NAME_REDIS, | ||
ServiceInterface::NAME_DB | ||
]; | ||
|
||
/** | ||
* @param FileList $fileList | ||
* @param ServiceFactory $serviceFactory | ||
*/ | ||
public function __construct( | ||
FileList $fileList, | ||
File $file, | ||
ServiceFactory $serviceFactory | ||
) { | ||
$this->fileList = $fileList; | ||
$this->file = $file; | ||
$this->serviceFactory = $serviceFactory; | ||
} | ||
|
||
/** | ||
* Validate the EOL of a given service and version by error level. | ||
* | ||
* @return array | ||
* @throws FileSystemException | ||
* @throws ServiceMismatchException | ||
*/ | ||
public function validateServiceEol(): array | ||
{ | ||
$errors = []; | ||
|
||
foreach ($this->services as $serviceName) { | ||
$service = $this->serviceFactory->create($serviceName); | ||
$serviceVersion = $service->getVersion(); | ||
|
||
if ($validationResult = $this->validateService( | ||
$this->getConvertedServiceName($serviceName), | ||
$serviceVersion | ||
)) { | ||
$errorLevel = current(array_keys($validationResult)); | ||
$errors[$errorLevel][] = $validationResult[$errorLevel]; | ||
} | ||
} | ||
return $errors; | ||
} | ||
|
||
/** | ||
* Validates a given service and version. | ||
* | ||
* @param string $serviceName | ||
* @param string $serviceVersion | ||
* @return array | ||
* @throws FileSystemException | ||
*/ | ||
public function validateService(string $serviceName, string $serviceVersion) : array | ||
{ | ||
$serviceConfigs = $this->getServiceConfigs($serviceName); | ||
|
||
$versionConfigs = array_filter($serviceConfigs, function ($v) use ($serviceVersion) { | ||
return Semver::satisfies($serviceVersion, sprintf('%s.x', $v['version'])); | ||
}); | ||
|
||
if (!isset($versionConfigs[current(array_keys($versionConfigs))]['eol'])) { | ||
return []; | ||
} | ||
|
||
$eolDate = Carbon::createFromTimestamp($versionConfigs[current(array_keys($versionConfigs))]['eol']); | ||
|
||
if (!$eolDate->isFuture()) { | ||
return [ValidatorInterface::LEVEL_WARNING => sprintf( | ||
'%s %s has passed EOL (%s).', | ||
$serviceName, | ||
$serviceVersion, | ||
date_format($eolDate, 'Y-m-d') | ||
)]; | ||
} elseif ($eolDate->isFuture() | ||
&& $eolDate->diffInMonths(Carbon::now()) <= self::NOTIFICATION_PERIOD | ||
) { | ||
return [ValidatorInterface::LEVEL_NOTICE => sprintf( | ||
'%s %s is approaching EOL (%s).', | ||
$serviceName, | ||
$serviceVersion, | ||
date_format($eolDate, 'Y-m-d') | ||
)]; | ||
} | ||
|
||
return []; | ||
} | ||
|
||
/** | ||
* Gets the EOL configurations for the current service from eol.yaml. | ||
* | ||
* @param string $serviceName | ||
* @return array | ||
* @throws FileSystemException | ||
*/ | ||
private function getServiceConfigs(string $serviceName) : array | ||
{ | ||
if ($this->eolConfigs === null) { | ||
$this->eolConfigs = []; | ||
$configsPath = $this->fileList->getServiceEolsConfig(); | ||
if ($this->file->isExists($configsPath)) { | ||
$this->eolConfigs = Yaml::parse($this->file->fileGetContents($configsPath)); | ||
} | ||
} | ||
|
||
return $this->eolConfigs[$serviceName] ?? []; | ||
} | ||
|
||
/** | ||
* Perform service name conversions. | ||
* Explicitly resetting 'mysql' to 'mariadb' for MariaDB validation; getting the version from | ||
* relationship returns mysql:<version>. | ||
* | ||
* @param string $serviceName | ||
* @return string | ||
*/ | ||
private function getConvertedServiceName(string $serviceName) : string | ||
{ | ||
return $serviceName == 'mysql' ? 'mariadb' : $serviceName; | ||
} | ||
} |
Oops, something went wrong.