private function SendExecMessage(DBServer $DBServer, Event $Event, Scalr_Messaging_Msg $msg) { $c = $this->DB->GetOne("SELECT COUNT(*) FROM farm_role_scripts WHERE farmid=? AND event_name=?", array($Event->GetFarmID(), $Event->GetName())); if ($c == 0) { return; } $DBFarm = DBFarm::LoadByID($Event->GetFarmID()); $servers = $DBFarm->GetServersByFilter(array(), array('status' => SERVER_STATUS::TERMINATED)); foreach ($servers as $farmDBServer) { // For some events we must sent trap to all instances include instance where ip adress changed. // For other events we must exclude instance that fired event from trap list. if ($DBServer && $DBServer->serverId == $farmDBServer->serverId) { if (!in_array($Event->GetName(), array(EVENT_TYPE::INSTANCE_IP_ADDRESS_CHANGED, EVENT_TYPE::EBS_VOLUME_MOUNTED, EVENT_TYPE::BEFORE_INSTANCE_LAUNCH, EVENT_TYPE::BEFORE_HOST_TERMINATE))) { continue; } } if (!$farmDBServer->IsSupported("0.5")) { $farmDBServer->SendMessage($msg, true); } } }
private function sendPromoteToMasterMessage(Event $event) { if ($event->DBServer->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER) || $event->DBServer->GetFarmRoleObject()->GetSetting(Scalr_Db_Msr::SLAVE_TO_MASTER)) { //Check if master already running: do not send promote_to_master $msg = new Scalr_Messaging_Msg_DbMsr_PromoteToMaster(); $msg->tmpEventName = $event->GetName(); $msg->dbType = $event->DBServer->GetFarmRoleObject()->GetRoleObject()->getDbMsrBehavior(); $msg->cloudLocation = $event->DBServer->GetCloudLocation(); if (in_array($event->DBServer->platform, array(SERVER_PLATFORMS::EC2, SERVER_PLATFORMS::CLOUDSTACK, SERVER_PLATFORMS::IDCF, SERVER_PLATFORMS::UCLOUD))) { try { $volume = Scalr_Storage_Volume::init()->loadById($event->DBServer->GetFarmRoleObject()->GetSetting(Scalr_Db_Msr::VOLUME_ID)); $msg->volumeConfig = $volume->getConfig(); } catch (Exception $e) { $this->Logger->error(new FarmLogMessage($event->DBServer->farmId, "Cannot create volumeConfig for PromoteToMaster message: {$e->getMessage()}")); } } if ($event->DBServer->farmRoleId != 0) { foreach (Scalr_Role_Behavior::getListForRole(DBRole::loadById($event->DBServer->roleId)) as $behavior) { $msg = $behavior->extendMessage($msg, $event->DBServer); } } // Send Mysql_PromoteToMaster to the first server in the same avail zone as old master (if exists) // Otherwise send to first in role $platform = $event->DBServer->platform; if ($platform == SERVER_PLATFORMS::EC2) { $availZone = $event->DBServer->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE); } $dbFarmRole = $event->DBServer->GetFarmRoleObject(); $servers = $dbFarmRole->GetServersByFilter(array('status' => array(SERVER_STATUS::RUNNING))); $firstInRoleServer = false; foreach ($servers as $DBServer) { if ($DBServer->serverId == $event->DBServer->serverId) { continue; } if (!$firstInRoleServer) { $firstInRoleServer = $DBServer; } if ($platform == SERVER_PLATFORMS::EC2 && $DBServer->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE) == $availZone || $platform != SERVER_PLATFORMS::EC2) { $event->DBServer->SetProperty(Scalr_Db_Msr::REPLICATION_MASTER, 0); $dbFarmRole->SetSetting(Scalr_Db_Msr::SLAVE_TO_MASTER, 1); $DBServer->SetProperty(Scalr_Db_Msr::REPLICATION_MASTER, 1); $DBServer->SendMessage($msg, false, true); return; } } if ($firstInRoleServer) { $dbFarmRole->SetSetting(Scalr_Db_Msr::SLAVE_TO_MASTER, 1); $firstInRoleServer->SetProperty(Scalr_Db_Msr::REPLICATION_MASTER, 1); $firstInRoleServer->SendMessage($msg, false, true); } } }
/** * Store event in database * * @param integer $farmid * @param string $event_name */ public static function StoreEvent($farmid, Event $event, $eventTime = null) { if ($event->DBServer) { $eventServerId = $event->DBServer->serverId; } try { $DB = self::getDb(); // Generate event message $message = $event->getTextDetails(); //short_message temporary used for time tracking // Store event in database $DB->Execute("INSERT INTO events SET\n farmid\t= ?,\n type\t= ?,\n dtadded\t= NOW(),\n message\t= ?,\n event_object = '',\n event_id\t = ?,\n event_server_id = ?,\n short_message = ?,\n msg_expected = ?,\n msg_created = ?,\n scripts_total = ?,\n is_suspend = ?", array($farmid, $event->GetName(), $message, $event->GetEventID(), $eventServerId, $eventTime, $event->msgExpected, $event->msgCreated, $event->scriptsCount, $event->isSuspended ? 1 : 0)); } catch (Exception $e) { Logger::getLogger(__CLASS__)->fatal(sprintf(_("Cannot store event in database: %s"), $e->getMessage())); } try { if ($eventServerId) { $dbServer = DBServer::LoadByID($eventServerId); if (!$dbServer->farmRoleId) { return true; } $dt = new DateTime('now', new DateTimeZone("UTC")); $timestamp = $dt->format("D d M Y H:i:s e"); $payload = new stdClass(); $payload->eventName = $event->GetName(); $payload->eventId = $event->GetEventID(); $payload->timestamp = $timestamp; $globalVars = Scalr_Scripting_GlobalVariables::listServerGlobalVariables($dbServer, true, $event); $webhooks = WebhookConfig::findByEvent($event->GetName(), $farmid, $dbServer->clientId, $dbServer->envId); $count = 0; foreach ($webhooks as $webhook) { /* @var $webhook \Scalr\Model\Entity\WebhookConfig */ $payload->configurationId = $webhook->webhookId; $payload->data = array(); $variables = []; foreach ($globalVars as $gv) { $variables[$gv->name] = $gv->value; if ($gv->private && $webhook->skipPrivateGv == 1 && !$gv->system) { continue; } $payload->data[$gv->name] = $gv->value; } if ($webhook->postData) { //Parse variable $keys = array_keys($variables); $f = create_function('$item', 'return "{".$item."}";'); $keys = array_map($f, $keys); $values = array_values($variables); // Strip undefined variables & return value $payload->userData = preg_replace("/{[A-Za-z0-9_-]+}/", "", str_replace($keys, $values, $webhook->postData)); } else { $payload->userData = ''; } foreach ($webhook->getEndpoints() as $ce) { /* @var $ce \Scalr\Model\Entity\WebhookConfigEndpoint */ $endpoint = $ce->getEndpoint(); if (!$endpoint->isValid) { continue; } $payload->endpointId = $endpoint->endpointId; $encPayload = json_encode($payload); $history = new WebhookHistory(); $history->eventId = $event->GetEventID(); $history->eventType = $event->GetName(); $history->payload = $encPayload; $history->serverId = $event->DBServer ? $event->DBServer->serverId : null; $history->endpointId = $endpoint->endpointId; $history->webhookId = $webhook->webhookId; $history->farmId = $farmid; $history->save(); $count++; } } if ($count != 0) { $DB->Execute("UPDATE events SET wh_total = ? WHERE event_id = ?", array($count, $event->GetEventID())); } } } catch (Exception $e) { Logger::getLogger(__CLASS__)->fatal(sprintf(_("WebHooks: %s"), $e->getMessage())); } }
/** * Store event in database * * @param integer $farmid * @param string $event_name */ public static function StoreEvent($farmid, Event $event) { if ($event->SkipDeferredOperations) { return true; } try { $DB = Core::GetDBInstance(); // Get Smarty object $Smarty = Core::GetSmartyInstance(); // Assign vars $Smarty->assign(array("event" => $event)); // Generate event message if (file_exists(CF_TEMPLATES_PATH . "/event_messages/{$event->GetName()}.tpl")) { $message = $Smarty->fetch("event_messages/{$event->GetName()}.tpl"); $short_message = $Smarty->fetch("event_messages/{$event->GetName()}.short.tpl"); // Store event in database $DB->Execute("INSERT INTO events SET \r\n\t\t\t\t\t\tfarmid\t= ?, \r\n\t\t\t\t\t\ttype\t= ?, \r\n\t\t\t\t\t\tdtadded\t= NOW(),\r\n\t\t\t\t\t\tmessage\t= ?,\r\n\t\t\t\t\t\tshort_message = ?, \r\n\t\t\t\t\t\tevent_object = ?,\r\n\t\t\t\t\t\tevent_id\t = ?\r\n\t\t\t\t\t\t", array($farmid, $event->GetName(), $message, $short_message, serialize($event), $event->GetEventID())); $eventid = $DB->Insert_ID(); // Add task for fire deferred event TaskQueue::Attach(QUEUE_NAME::DEFERRED_EVENTS)->AppendTask(new FireDeferredEventTask($eventid)); } else { Logger::getLogger(__CLASS__)->warn(sprintf(_("Cannot store event in database: '{$event->GetName()}' message template not found"))); } } catch (Exception $e) { Logger::getLogger(__CLASS__)->fatal(sprintf(_("Cannot store event in database: %s"), $e->getMessage())); } }
/** * File event in database * * @param integer $farmid * @param string $event_name */ public static function FireEvent($farmid, Event $event) { if (!self::$observersSetuped) { self::setupObservers(); } $startTime = microtime(true); try { $event->SetFarmID($farmid); $handledObservers = array(); // Notify class observers foreach (self::$EventObservers as $observer) { $observerStartTime = microtime(true); $observer->SetFarmID($farmid); Logger::getLogger(__CLASS__)->info(sprintf("Event %s. Observer: %s", "On{$event->GetName()}", get_class($observer))); if ($event instanceof CustomEvent) { call_user_func(array($observer, "OnCustomEvent"), $event); } else { call_user_func(array($observer, "On{$event->GetName()}"), $event); } $handledObservers[get_class($observer)] = microtime(true) - $observerStartTime; } } catch (Exception $e) { Logger::getLogger(__CLASS__)->fatal(sprintf("Exception thrown in Scalr::FireEvent(%s:%s, %s:%s): %s", @get_class($observer), $event->GetName(), $e->getFile(), $e->getLine(), $e->getMessage())); throw new Exception($e->getMessage()); } $event->handledObservers = $handledObservers; self::StoreEvent($farmid, $event, microtime(true) - $startTime); }
public static function getEventScriptList(Event $event, DBServer $eventServer, DBServer $targetServer) { $db = \Scalr::getDb(); $accountScripts = $db->GetAll("SELECT * FROM account_scripts WHERE (event_name=? OR event_name='*') AND account_id=?", array($event->GetName(), $eventServer->clientId)); $roleScripts = $db->GetAll("SELECT * FROM role_scripts WHERE (event_name=? OR event_name='*') AND role_id=?", array($event->GetName(), $eventServer->roleId)); $scripts = $db->GetAll("SELECT *, `script_type` as `type` FROM farm_role_scripts WHERE (event_name=? OR event_name='*') AND farmid=?", array($event->GetName(), $eventServer->farmId)); foreach ($accountScripts as $script) { $scripts[] = array("id" => "a{$script['id']}", "type" => $script['script_type'], "scriptid" => $script['script_id'], "params" => $script['params'], "event_name" => $event->GetName(), "target" => $script['target'], "version" => $script['version'], "timeout" => $script['timeout'], "issync" => $script['issync'], "order_index" => $script['order_index'], "scope" => "account", 'script_path' => $script['script_path'], 'run_as' => $script['run_as'], 'script_type' => $script['script_type']); } foreach ($roleScripts as $script) { $params = $db->GetOne("SELECT params FROM farm_role_scripting_params WHERE farm_role_id = ? AND `hash` = ? AND farm_role_script_id = '0' LIMIT 1", array($eventServer->farmRoleId, $script['hash'])); if ($params) { $script['params'] = $params; } $scripts[] = array("id" => "r{$script['id']}", "scriptid" => $script['script_id'], "type" => $script['script_type'], "params" => $script['params'], "event_name" => $event->GetName(), "target" => $script['target'], "version" => $script['version'], "timeout" => $script['timeout'], "issync" => $script['issync'], "order_index" => $script['order_index'], "scope" => "role", 'script_path' => $script['script_path'], 'run_as' => $script['run_as'], 'script_type' => $script['script_type']); } $retval = array(); foreach ($scripts as $scriptSettings) { $scriptSettings['order_index'] = (double) $scriptSettings['order_index']; // If target set to that instance only if ($scriptSettings['target'] == Script::TARGET_INSTANCE && $eventServer->serverId != $targetServer->serverId) { continue; } // If target set to all instances in specific role if ($scriptSettings['target'] == Script::TARGET_ROLE && $eventServer->farmRoleId != $targetServer->farmRoleId) { continue; } if (!$scriptSettings['scope']) { // Validate that event was triggered on the same farmRoleId as script if ($eventServer->farmRoleId != $scriptSettings['farm_roleid']) { continue; } // Validate that target server has the same farmRoleId as event server with target ROLE if ($scriptSettings['target'] == Script::TARGET_ROLE && $targetServer->farmRoleId != $scriptSettings['farm_roleid']) { continue; } } if ($scriptSettings['target'] == Script::TARGET_ROLES || $scriptSettings['target'] == Script::TARGET_BEHAVIORS) { if ($scriptSettings['scope'] != 'role') { $targets = $db->GetAll("SELECT * FROM farm_role_scripting_targets WHERE farm_role_script_id = ?", array($scriptSettings['id'])); } else { $targets = array(); } $execute = false; foreach ($targets as $target) { switch ($target['target_type']) { case "farmrole": if ($targetServer->farmRoleId == $target['target']) { $execute = true; } break; case "behavior": if ($targetServer->GetFarmRoleObject()->GetRoleObject()->hasBehavior($target['target'])) { $execute = true; } break; } } if (!$execute) { continue; } } if ($scriptSettings['target'] == "" || $scriptSettings['id'] == "") { continue; } $script = self::prepareScript($scriptSettings, $targetServer, $event); if ($script) { while (true) { $index = (string) $scriptSettings['order_index']; if (!$retval[$index]) { $retval[$index] = $script; break; } else { $scriptSettings['order_index'] += 0.01; } } } } @ksort($retval); return $retval; }
public static function listServerGlobalVariables(DBServer $dbServer, $includeSystem = false, Event $event = null) { $retval = array(); if ($includeSystem) { $variables = $dbServer->GetScriptingVars(); if ($event) { if ($event->DBServer) { foreach ($event->DBServer->GetScriptingVars() as $k => $v) { $variables["event_{$k}"] = $v; } } foreach ($event->GetScriptingVars() as $k => $v) { $variables[$k] = $event->{$v}; } if (isset($event->params) && is_array($event->params)) { foreach ($event->params as $k => $v) { $variables[$k] = $v; } } $variables['event_name'] = $event->GetName(); } $formats = \Scalr::config("scalr.system.global_variables.format"); foreach ($variables as $name => $value) { $name = "SCALR_" . strtoupper($name); $value = trim($value); if (isset($formats[$name])) { $value = @sprintf($formats[$name], $value); } $private = strpos($name, 'SCALR_EVENT_') === 0 ? 1 : 0; $retval[] = (object) array('name' => $name, 'value' => $value, 'private' => $private, 'system' => 1); } } try { $globalVariables = new Scalr_Scripting_GlobalVariables($dbServer->GetEnvironmentObject()->clientId, $dbServer->envId, Scalr_Scripting_GlobalVariables::SCOPE_SERVER); $vars = $globalVariables->listVariables($dbServer->GetFarmRoleObject()->RoleID, $dbServer->farmId, $dbServer->farmRoleId, $dbServer->serverId); foreach ($vars as $v) { $retval[] = (object) $v; } } catch (Exception $e) { } return $retval; }
public static function getEventScriptList(Event $event, DBServer $eventServer, DBServer $targetServer) { $db = Core::GetDBInstance(); $roleScripts = $db->GetAll("SELECT * FROM role_scripts WHERE event_name=? AND role_id=? ORDER BY order_index ASC", array($event->GetName(), $eventServer->roleId)); $scripts = $db->GetAll("SELECT * FROM farm_role_scripts WHERE event_name=? AND farmid=? ORDER BY order_index ASC", array($event->GetName(), $eventServer->farmId)); foreach ($roleScripts as $script) { $scripts[] = array("id" => "r{$script['id']}", "scriptid" => $script['script_id'], "params" => $script['params'], "event_name" => $script['event_name'], "target" => $script['target'], "version" => $script['version'], "timeout" => $script['timeout'], "issync" => $script['issync'], "order_index" => $script['order_index'], "type" => "role"); } $retval = array(); foreach ($scripts as $scriptSettings) { $scriptSettings['order_index'] = (double) $scriptSettings['order_index']; if ($scriptSettings['target'] == SCRIPTING_TARGET::INSTANCE && $eventServer->serverId != $targetServer->serverId) { continue; } if ($scriptSettings['target'] == SCRIPTING_TARGET::ROLE && $eventServer->farmRoleId != $targetServer->farmRoleId) { continue; } if ($scriptSettings['target'] == SCRIPTING_TARGET::FARM && $eventServer->farmRoleId != $scriptSettings['farm_roleid']) { continue; } if ($scriptSettings['type'] != 'role' && $scriptSettings['target'] != SCRIPTING_TARGET::FARM && $targetServer->farmRoleId != $scriptSettings['farm_roleid']) { continue; } if ($scriptSettings['target'] == "" || $scriptSettings['id'] == "") { continue; } $script = self::prepareScript($scriptSettings, $targetServer, $event); if ($script) { while (true) { $index = (string) $scriptSettings['order_index']; if (!$retval[$index]) { $retval[$index] = $script; break; } else { $scriptSettings['order_index'] += 0.01; } } } } @ksort($retval); return $retval; }