/** * @param int $farmId * @param int $farmRoleId optional * @param string $serverId optional * @param int $scriptId optional * @param string $scriptPath optional * @param int $scriptIsSync * @param int $scriptTimeout * @param int $scriptVersion * @param array $scriptParams optional * @param int $shortcutId optional * @param int $editShortcut optional * @throws Exception */ public function xExecuteAction($farmId, $farmRoleId = 0, $serverId = '', $scriptId = 0, $scriptPath = '', $scriptIsSync, $scriptTimeout, $scriptVersion, array $scriptParams = [], $shortcutId = null, $editShortcut = null) { $this->request->restrictAccess(Acl::RESOURCE_SCRIPTS_ENVIRONMENT, Acl::PERM_SCRIPTS_ENVIRONMENT_EXECUTE); if ($serverId) { $dbServer = DBServer::LoadByID($serverId); $this->user->getPermissions()->validate($dbServer); $target = Script::TARGET_INSTANCE; $serverId = $dbServer->serverId; $farmRoleId = $dbServer->farmRoleId; $farmId = $dbServer->farmId; } else { if ($farmRoleId) { $dbFarmRole = DBFarmRole::LoadByID($farmRoleId); $this->user->getPermissions()->validate($dbFarmRole); $target = Script::TARGET_ROLE; $farmRoleId = $dbFarmRole->ID; $farmId = $dbFarmRole->FarmID; } else { if (!$farmId) { $target = Script::TARGET_ALL; } else { $dbFarm = DBFarm::LoadByID($farmId); $this->user->getPermissions()->validate($dbFarm); $target = Script::TARGET_FARM; $farmId = $dbFarm->ID; } } } if ($farmId) { $this->request->checkPermissions(Entity\Farm::findPk($farmId), Acl::PERM_FARMS_SERVERS); } if ($scriptId) { $script = Script::findPk($scriptId); /* @var $script Script */ if (!$script) { throw new Scalr_UI_Exception_NotFound(); } $script->checkPermission($this->user, $this->getEnvironmentId()); } elseif (!$scriptPath) { throw new Scalr_Exception_Core('scriptId or scriptPath should be set'); } if (!$scriptTimeout) { $scriptTimeout = $scriptIsSync == 1 ? Scalr::config('scalr.script.timeout.sync') : Scalr::config('scalr.script.timeout.async'); } $executeScript = true; if ($shortcutId && ($target != Script::TARGET_INSTANCE || $target != Script::TARGET_ALL)) { if ($shortcutId == -1) { $shortcut = new ScriptShortcut(); $shortcut->farmId = $farmId; } else { $shortcut = ScriptShortcut::findPk($shortcutId); /* @var $shortcut ScriptShortcut */ if (!$shortcut) { throw new Scalr_UI_Exception_NotFound(); } if ($editShortcut == 1) { $executeScript = false; } } $shortcut->farmRoleId = $farmRoleId == 0 ? NULL : $farmRoleId; if ($scriptId) { $shortcut->scriptId = $scriptId; $shortcut->scriptPath = ''; } else { $shortcut->scriptPath = $scriptPath; $shortcut->scriptId = NULL; } $shortcut->isSync = $scriptIsSync; $shortcut->version = $scriptVersion; $shortcut->timeout = $scriptTimeout; $shortcut->params = $scriptParams; $shortcut->save(); } if ($executeScript) { switch ($target) { case Script::TARGET_FARM: $servers = $this->db->GetAll("\n SELECT server_id\n FROM servers\n WHERE is_scalarized = 1 AND status IN (?,?) AND farm_id=?", [SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmId]); break; case Script::TARGET_ROLE: $servers = $this->db->GetAll("\n SELECT server_id\n FROM servers\n WHERE is_scalarized = 1 AND status IN (?,?) AND farm_roleid=?", [SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmRoleId]); break; case Script::TARGET_INSTANCE: $servers = $this->db->GetAll("\n SELECT server_id\n FROM servers\n WHERE is_scalarized = 1 AND status IN (?,?) AND server_id=?", [SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $serverId]); break; case Script::TARGET_ALL: $sql = "\n SELECT s.server_id\n FROM servers s\n JOIN farms f ON f.id = s.farm_id\n WHERE s.is_scalarized = 1\n AND s.status IN (?,?)\n AND s.env_id = ?\n AND " . $this->request->getFarmSqlQuery(Acl::PERM_FARMS_SERVERS); $args = [SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $this->getEnvironmentId()]; $servers = $this->db->GetAll($sql, $args); break; } $scriptSettings = array('version' => $scriptVersion, 'timeout' => $scriptTimeout, 'issync' => $scriptIsSync, 'params' => serialize($scriptParams)); if ($scriptId) { $scriptSettings['scriptid'] = $scriptId; $scriptSettings['type'] = Scalr_Scripting_Manager::ORCHESTRATION_SCRIPT_TYPE_SCALR; } else { $scriptSettings['script_path'] = $scriptPath; $scriptSettings['type'] = Scalr_Scripting_Manager::ORCHESTRATION_SCRIPT_TYPE_LOCAL; } $serializer = Scalr_Messaging_JsonSerializer::getInstance(); $cryptoTool = \Scalr::getContainer()->srzcrypto; // send message to start executing task (starts script) if (count($servers) > 0) { foreach ($servers as $server) { $DBServer = DBServer::LoadByID($server['server_id']); $msg = new Scalr_Messaging_Msg_ExecScript("Manual"); $msg->setServerMetaData($DBServer); $script = Scalr_Scripting_Manager::prepareScript($scriptSettings, $DBServer); if ($script) { $DBServer->executeScript($script, $msg); $this->auditLog("script.execute", $script, $DBServer); $manualLog = new OrchestrationLogManualScript($script['execution_id'], $msg->serverId); $manualLog->userId = $this->getUser()->getId(); $manualLog->userEmail = $this->getUser()->getEmail(); $manualLog->added = new DateTime('now', new DateTimeZone('UTC')); $manualLog->save(); } } } $this->response->success('Script execution has been queued and will occur on the selected instance(s) within a couple of minutes.'); } else { $this->response->success('Script shortcut successfully saved'); } }
/** * Returns prepared orchestration log data for response * * @param EntityIterator $logs List of Orchestration Log objects * @return array */ private function prepareOrchestrationLogData($logs) { $farmIds = []; $serverIds = []; $taskIds = []; $eventIds = []; $ids = []; foreach ($logs as $row) { /* @var $row OrchestrationLog */ $farmIds[] = $row->farmId; $serverIds[] = $row->serverId; if ($row->eventServerId) { $serverIds[] = $row->eventServerId; } if ($row->taskId) { $taskIds[] = $row->taskId; } if ($row->eventId) { $eventIds[] = $row->eventId; } if ($row->type == OrchestrationLog::TYPE_MANUAL) { $ids[] = $row->id; } } if (!empty($farmIds)) { $farms = Farm::find([['id' => ['$in' => array_unique($farmIds)]]]); foreach ($farms as $farm) { /* @var $farm Farm */ $farmData[$farm->id] = $farm->name; } } if (!empty($serverIds)) { $servers = Server::find([['serverId' => ['$in' => array_unique($serverIds)]]]); $farmRoleIds = []; $serverFarmIds = []; foreach ($servers as $server) { /* @var $server Server */ $serverData[$server->serverId]['serverIndex'] = $server->index; $farmRoleIds[$server->serverId] = $server->farmRoleId; $serverFarmIds[$server->serverId] = $server->farmId; } $farms = Farm::find([['id' => ['$in' => array_unique(array_values($serverFarmIds))]]]); foreach ($farms as $farm) { /* @var $farm Farm */ foreach ($serverFarmIds as $serverId => $farmId) { if ($farmId == $farm->id) { $serverData[$serverId]['farmName'] = $farm->name; $serverData[$serverId]['farmId'] = $farm->id; } } } $farmRoles = FarmRole::find([['id' => ['$in' => array_unique(array_values($farmRoleIds))]]]); foreach ($farmRoles as $farmRole) { /* @var $farmRole FarmRole */ foreach ($farmRoleIds as $serverId => $farmRoleId) { if ($farmRoleId == $farmRole->id) { $serverData[$serverId]['alias'] = $farmRole->alias; $serverData[$serverId]['farmRoleId'] = $farmRole->id; } } } } if (!empty($taskIds)) { $tasks = SchedulerTask::find([['id' => ['$in' => array_unique($taskIds)]]]); foreach ($tasks as $task) { /* @var $task SchedulerTask */ $taskData[$task->id] = $task->name; } } if (!empty($eventIds)) { $events = Event::find([['eventId' => ['$in' => array_unique($eventIds)]]]); foreach ($events as $event) { /* @var $event Event */ $eventData[$event->eventId] = $event->type; } } if (!empty($ids)) { $manualLogs = OrchestrationLogManualScript::find([['orchestrationLogId' => ['$in' => array_unique($ids)]]]); foreach ($manualLogs as $manualLog) { /* @var $manualLog OrchestrationLogManualScript */ $scriptData[$manualLog->orchestrationLogId] = $manualLog->userEmail; } } $data = []; foreach ($logs as $row) { /* @var $row OrchestrationLog */ $dataRow = get_object_vars($row); $dataRow['targetFarmName'] = isset($farmData[$row->farmId]) ? $farmData[$row->farmId] : null; $dataRow['targetFarmId'] = $row->farmId; $dataRow['targetServerId'] = $row->serverId; $dataRow['targetServerIndex'] = isset($serverData[$row->serverId]['serverIndex']) ? $serverData[$row->serverId]['serverIndex'] : null; $dataRow['targetFarmRoleId'] = isset($serverData[$row->serverId]['farmRoleId']) ? $serverData[$row->serverId]['farmRoleId'] : null; $dataRow['targetRoleName'] = isset($serverData[$row->serverId]['alias']) ? $serverData[$row->serverId]['alias'] : null; $dataRow['added'] = Scalr_Util_DateTime::convertTz($row->added); if (\Scalr::config('scalr.system.scripting.logs_storage') == 'scalr') { $dataRow['executionId'] = null; } if ($dataRow['message']) { $dataRow['message'] = nl2br(htmlspecialchars($dataRow['message'])); } if ($row->eventServerId) { $dataRow['eventFarmName'] = isset($serverData[$row->eventServerId]['farmName']) ? $serverData[$row->eventServerId]['farmName'] : null; $dataRow['eventFarmId'] = isset($serverData[$row->eventServerId]['farmId']) ? $serverData[$row->eventServerId]['farmId'] : null; $dataRow['eventFarmRoleId'] = isset($serverData[$row->eventServerId]['farmRoleId']) ? $serverData[$row->eventServerId]['farmRoleId'] : null; $dataRow['eventRoleName'] = isset($serverData[$row->eventServerId]['alias']) ? $serverData[$row->eventServerId]['alias'] : null; $dataRow['eventServerIndex'] = isset($serverData[$row->eventServerId]['serverIndex']) ? $serverData[$row->eventServerId]['serverIndex'] : null; } $dataRow['event'] = null; if ($row->taskId) { $dataRow['event'] = isset($taskData[$row->taskId]) ? $taskData[$row->taskId] : null; } if ($row->eventId) { $dataRow['event'] = isset($eventData[$row->eventId]) ? $eventData[$row->eventId] : null; } if ($row->type == OrchestrationLog::TYPE_MANUAL) { $dataRow['event'] = isset($scriptData[$row->id]) ? $scriptData[$row->id] : null; } $data[] = $dataRow; } return $data; }
function handle($queue, Scalr_Messaging_Msg $message, $rawMessage) { $dbserver = DBServer::LoadByID($message->getServerId()); $msg = ''; if ($message instanceof Scalr_Messaging_Msg_ExecScriptResult) { try { $storage = \Scalr::config('scalr.system.scripting.logs_storage'); if (!$message->executionId || $storage == 'scalr') { $msg = sprintf("STDERR: %s \n\n STDOUT: %s", base64_decode($message->stderr), base64_decode($message->stdout)); } if ($message->scriptPath) { $name = stristr($message->scriptPath, 'C:\\Windows\\TEMP\\scalr-scripting') || stristr($message->scriptPath, '/usr/local/bin/scalr-scripting') || preg_match('/fatmouse-agent\\/tasks\\/[^\\/]+\\/[^\\/]+\\/bin/', $message->scriptPath) ? $message->scriptName : $message->scriptPath; } else { $name = $message->scriptName; } $log = new OrchestrationLog(); if (strpos($message->eventName, 'Scheduler (TaskID: ') === 0) { $type = OrchestrationLog::TYPE_SCHEDULER; $log->taskId = filter_var($message->eventName, FILTER_SANITIZE_NUMBER_INT); } else { if ($message->eventName == 'Manual') { $type = OrchestrationLog::TYPE_MANUAL; } else { $type = OrchestrationLog::TYPE_EVENT; } } $log->farmId = $dbserver->farmId; $log->serverId = $message->getServerId(); $log->type = $type; $log->message = $msg; $log->added = new DateTime('now'); $log->scriptName = $name; $log->execTime = round($message->timeElapsed, 2); $log->execExitCode = $message->returnCode; $log->eventId = $message->eventId; $log->eventServerId = $message->eventServerId; $log->executionId = $message->executionId; $log->runAs = $message->runAs; $log->save(); if ($type === OrchestrationLog::TYPE_MANUAL) { $logManual = OrchestrationLogManualScript::findOne([['executionId' => $message->executionId], ['serverId' => $message->getServerId()]]); /* @var $logManual OrchestrationLogManualScript */ if ($logManual && empty($logManual->orchestrationLogId)) { $logManual->orchestrationLogId = $log->id; $logManual->save(); } } if ($message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION]) { DBServer::LoadByID($message->getServerId())->setScalarizrVersion($message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION]); } if ($message->eventId) { $updateTotal = ''; if ($message->returnCode == 130) { $field = 'scripts_timedout'; } elseif ($message->returnCode != 0) { $field = 'scripts_failed'; } else { $field = 'scripts_completed'; } if (stristr($name, '[Scalr built-in]')) { $updateTotal = ', `scripts_total` = `scripts_total`+1'; } $this->db->Execute("UPDATE events SET `{$field}` = `{$field}`+1 {$updateTotal} WHERE event_id = ?", [$message->eventId]); } } catch (Exception $e) { $this->logger->fatal($e->getMessage()); } } elseif ($message instanceof Scalr_Messaging_Msg_Log) { try { if ($message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION]) { DBServer::LoadByID($message->getServerId())->setScalarizrVersion($message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION]); } } catch (Exception $e) { } foreach ($message->entries as $entry) { if (self::$severityCodes[$entry->level] < 3) { continue; } $level = $entry->level === "WARNING" ? "warn" : strtolower($entry->level); \Scalr::getContainer()->logger($entry->name)->{$level}(new FarmLogMessage($dbserver, !empty($entry->msg) ? $entry->msg : null)); } } elseif ($message instanceof Scalr_Messaging_Msg_RebundleLog) { try { $this->db->Execute("INSERT INTO bundle_task_log SET\n bundle_task_id = ?,\n dtadded = NOW(),\n message = ?\n ", [$message->bundleTaskId, $message->message]); } catch (Exception $e) { $this->logger->error($e->getMessage()); } } }