/modules/scale/lib/action.php
https://gitlab.com/alexprowars/bitrix · PHP · 283 lines · 229 code · 27 blank · 27 comment · 29 complexity · a58b62a4dc30b112fddcfd0abbb9acc1 MD5 · raw file
- <?php
- namespace Bitrix\Scale;
- use Bitrix\Main\IO\File;
- use \Bitrix\Main\Localization\Loc;
- Loc::loadMessages(__FILE__);
- /**
- * Class Action
- * @package Bitrix\Scale
- */
- class Action
- {
- protected $id = "";
- protected $userParams = array();
- protected $freeParams = array();
- protected $actionParams = array();
- protected $serverHostname = "";
- protected $shellAdapter = null;
- protected $result = array();
- protected $logLevel = Logger::LOG_LEVEL_INFO;
- /**
- * @param string $actionId
- * @param array $actionParams
- * @param string $serverHostname
- * @param array $userParams
- * @param array $freeParams
- * @throws \Bitrix\Main\ArgumentNullException
- * @throws \Bitrix\Main\ArgumentTypeException
- * @throws \Exception
- */
- public function __construct($actionId, $actionParams, $serverHostname="", $userParams = array(), $freeParams = array())
- {
- if($actionId == '')
- throw new \Bitrix\Main\ArgumentNullException("actionId");
- if(!is_array($actionParams) || empty($actionParams))
- throw new \Exception("Params of action ".$actionId." are not defined correctly!");
- if(!isset($actionParams["START_COMMAND_TEMPLATE"]) || $actionParams["START_COMMAND_TEMPLATE"] == '')
- throw new \Exception("Required param START_COMMAND_TEMPLATE of action ".$actionId." are not defined!");
- if(!is_array($userParams))
- throw new \Bitrix\Main\ArgumentTypeException("userParams", "array");
- if(!is_array($freeParams))
- throw new \Bitrix\Main\ArgumentTypeException("freeParams", "array");
- $this->id = $actionId;
- $this->userParams = $userParams;
- $this->freeParams = $freeParams;
- $this->actionParams = $actionParams;
- $this->serverHostname = $serverHostname;
- $this->shellAdapter = new ShellAdapter;
- if(isset($actionParams["LOG_LEVEL"]))
- $this->logLevel = $actionParams["LOG_LEVEL"];
- }
- protected function getServerParams()
- {
- return ServersData::getServer($this->serverHostname);
- }
- /**
- * Makes command for shell action execution
- * @param array $inputParams
- * @return string - command to execute
- * @throws \Bitrix\Main\ArgumentTypeException
- */
- protected function makeStartCommand($inputParams = array())
- {
- if(!is_array($inputParams))
- throw new \Bitrix\Main\ArgumentTypeException("inputParams", "array");
- $retStr = $this->actionParams["START_COMMAND_TEMPLATE"];
- foreach ($this->userParams as $key => $paramValue)
- {
- if($this->actionParams['USER_PARAMS'][$key]['THROUGH_FILE'] == 'Y')
- {
- if($paramValue <> '')
- {
- $tmpDir = Helper::getTmpDir();
- $tmpFile = $tmpDir.'/.'.randString();
- $res = File::putFileContents($tmpFile, $paramValue);
- if($res === false)
- return '';
- $paramValue = $tmpFile;
- }
- }
- $retStr = str_replace('##USER_PARAMS:'.$key.'##', $paramValue, $retStr);
- }
- if($this->serverHostname <> '' && $this->serverHostname != "global")
- {
- $serverParams = $this->getServerParams();
- $serverParams["hostname"] = $this->serverHostname;
- if(is_array($serverParams))
- {
- foreach ($serverParams as $key => $paramValue)
- {
- if(is_string($paramValue))
- {
- $retStr = str_replace('##SERVER_PARAMS:' . $key . '##', $paramValue, $retStr);
- }
- }
- }
- }
- if(!empty($inputParams))
- foreach ($inputParams as $key => $paramValue)
- $retStr = str_replace('##INPUT_PARAMS:'.$key.'##', $paramValue, $retStr);
- if(isset($this->actionParams["CODE_PARAMS"]) && is_array($this->actionParams["CODE_PARAMS"]))
- {
- foreach($this->actionParams["CODE_PARAMS"] as $paramId => $paramCode)
- {
- $res = eval($paramCode);
- $retStr = str_replace('##CODE_PARAMS:'.$paramId.'##', $res, $retStr);
- }
- }
- foreach ($this->freeParams as $key => $paramValue)
- $retStr = str_replace('##'.$key.'##', $paramValue, $retStr);
- return $retStr;
- }
- /**
- * Starts the action execution
- * @param array $inputParams - params from previously started actions
- * @return int code returned by shell
- * @throws \Bitrix\Main\ArgumentTypeException
- * @throws \Exception
- */
- public function start(array $inputParams = array())
- {
- if(!is_array($inputParams))
- throw new \Bitrix\Main\ArgumentTypeException("inputParams", "array");
- if(isset($this->actionParams["MODIFYERS"]) && is_array($this->actionParams["MODIFYERS"]))
- {
- $needMoreUserInfo = false;
- foreach($this->actionParams["MODIFYERS"] as $modifyerFunction)
- {
- if(is_callable($modifyerFunction))
- {
- try
- {
- $this->actionParams = call_user_func($modifyerFunction, $this->id, $this->actionParams, $this->serverHostname, $this->userParams);
- }
- catch(NeedMoreUserInfoException $e)
- {
- $this->actionParams = $e->getActionParams();
- $needMoreUserInfo = true;
- }
- }
- }
- if($needMoreUserInfo)
- throw new NeedMoreUserInfoException("Need more user's info", $this->actionParams);
- }
- $result = null;
- $output = '';
- $arOutput = array();
- $command = $this->makeStartCommand($inputParams);
- if($command <> '')
- {
- $result = $this->shellAdapter->syncExec($command);
- $output = $this->shellAdapter->getLastOutput();
- $arOutput = array();
- if($output <> '')
- {
- $arOut = json_decode($output, true);
- if(is_array($arOut) && !empty($arOut))
- $arOutput = $arOut;
- }
- //error returned by shell
- $error = $this->shellAdapter->getLastError();
- //error returned by bitrix-env
- if(isset($arOutput["error"]) && intval($arOutput["error"]) > 0 && isset($arOutput["message"]) && $arOutput["message"] <> '')
- $error .= " ".$arOutput["message"];
- $this->makeLogRecords($command, $result, $output, $error);
- }
- else //$command == ''
- {
- $result = false;
- $error = 'Cant\'t create command for action execution';
- }
- $this->result = array(
- $this->id => array(
- "NAME" => isset($this->actionParams["NAME"]) ? $this->actionParams["NAME"] : "[".$this->id."]",
- "RESULT" => $result ? "OK" : "ERROR",
- "OUTPUT" => array(
- "TEXT" => $output,
- "DATA" => $arOutput
- ),
- "ERROR" => $error
- )
- );
- return $result;
- }
- /**
- * @return array Last command execution results
- */
- public function getResult()
- {
- return $this->result;
- }
- protected function makeLogRecords($command = "", $result = null, $output = "", $error = "")
- {
- if($command <> '')
- {
- //cut password data from log records
- $preg = "/(-p.*\s+|--mysql_password=.*\s+|--cluster_password=.*\s+|--replica_password=.*\s+|--password=.*\s+)/is";
- $command = preg_replace($preg, ' PASS_PARAMS ', $command);
- $this->log(
- ($result ? Logger::LOG_LEVEL_INFO : Logger::LOG_LEVEL_ERROR),
- "SCALE_ACTION_STARTED",
- $this->actionParams["NAME"],
- $command
- );
- }
- if($result !== null)
- {
- $this->log(
- ($result ? Logger::LOG_LEVEL_INFO : Logger::LOG_LEVEL_ERROR),
- "SCALE_ACTION_RESULT",
- $this->actionParams["NAME"],
- $result ? Loc::getMessage("SCALE_ACTION_RESULT_SUCCESS") : Loc::getMessage("SCALE_ACTION_RESULT_ERROR")
- );
- }
- if($output <> '')
- {
- $this->log(
- Logger::LOG_LEVEL_DEBUG,
- "SCALE_ACTION_OUTPUT",
- $this->actionParams["NAME"],
- $output
- );
- }
- if($error <> '')
- {
- $this->log(
- Logger::LOG_LEVEL_ERROR,
- "SCALE_ACTION_ERROR",
- $this->actionParams["NAME"],
- $error
- );
- }
- }
- protected function log($level, $auditType, $actionId, $description)
- {
- if($this->logLevel < $level)
- return false;
- return Logger::addRecord($level, $auditType, $actionId, $description);
- }
- }