public function OnHostDown(\HostDownEvent $event) { $dbServer = $event->DBServer; if ($dbServer->farmRoleId != 0) { try { $dbFarmRole = $dbServer->GetFarmRoleObject(); } catch (\Exception $e) { return false; } foreach (\Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $bObj) { $bObj->onHostDown($dbServer, $event); } //Storage if (!$event->isSuspended) { try { $storage = new FarmRoleStorage($dbFarmRole); $storageConfigs = $storage->getConfigs(); if (empty($storageConfigs)) { return true; } foreach ($storageConfigs as $config) { //Check for existing volume $dbVolume = FarmRoleStorageDevice::getByConfigIdAndIndex($config->id, $dbServer->index); if ($dbVolume && !$config->reUse) { $dbVolume->status = FarmRoleStorageDevice::STATUS_ZOMBY; $dbVolume->save(); } } } catch (\Exception $e) { $this->logger->error(new \FarmLogMessage($dbServer, "Marking storage for disposal failed: {$e->getMessage()}")); } } } }
public function OnFarmTerminated(FarmTerminatedEvent $event) { $dbFarm = DBFarm::LoadByID($this->FarmID); foreach ($dbFarm->GetFarmRoles() as $dbFarmRole) { foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $bObj) { $bObj->onFarmTerminated($dbFarmRole); } } }
public function extendMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { $message = parent::extendMessage($message, $dbServer); switch (get_class($message)) { case "Scalr_Messaging_Msg_HostInitResponse": $message->router = $this->getConfiguration($dbServer); } return $message; }
public function extendMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { $message = parent::extendMessage($message, $dbServer); switch (get_class($message)) { case "Scalr_Messaging_Msg_HostInitResponse": $message->cfCloudController = new stdClass(); $message->cfCloudController->volumeConfig = $this->getVolumeConfig($dbServer->GetFarmRoleObject(), $dbServer); break; } return $message; }
public function OnHostDown(HostDownEvent $event) { $dbServer = $event->DBServer; if ($dbServer->farmRoleId != 0) { try { $dbFarmRole = $dbServer->GetFarmRoleObject(); } catch (Exception $e) { return false; } foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $bObj) { $bObj->onHostDown($dbServer); } } }
public function extendMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { $message = parent::extendMessage($message); switch (get_class($message)) { case "Scalr_Messaging_Msg_HostInitResponse": $message->rabbitmq = new stdClass(); $message->rabbitmq->cookie = $dbServer->GetFarmRoleObject()->GetSetting(self::ROLE_COOKIE_NAME); $message->rabbitmq->volumeConfig = $this->getVolumeConfig($dbServer->GetFarmRoleObject(), $dbServer); $message->rabbitmq->nodeType = $this->getNodeType($dbServer->GetFarmRoleObject(), $dbServer); $message->rabbitmq->password = $dbServer->GetFarmRoleObject()->GetSetting(self::ROLE_PASSWORD); $dbServer->SetProperty(self::SERVER_NODE_TYPE, $message->rabbitmq->nodeType); break; } return $message; }
public function ListFarmRoleParamsJson() { $farmRoleId = $this->GetArg("farm-role-id"); if (!$farmRoleId) { throw new Exception("'farm-role-id' required"); } $dbFarmRole = DBFarmRole::LoadByID($farmRoleId); if ($dbFarmRole->FarmID != $this->DBServer->farmId) { throw new Exception("You can request this information ONLY for roles within server farm"); } $result = new stdClass(); // Base configuration if ($this->DBServer->farmRoleId == $farmRoleId) { $data = Scalr_Role_Behavior::loadByName(ROLE_BEHAVIORS::BASE)->getBaseConfiguration($this->DBServer); foreach ((array) $data as $k => $v) { $result->{$k} = $v; } } $role = $dbFarmRole->GetRoleObject(); $behaviors = $role->getBehaviors(); foreach ($behaviors as $behavior) { $data = null; if ($behavior == ROLE_BEHAVIORS::MONGODB || $behavior == ROLE_BEHAVIORS::CHEF || $behavior == ROLE_BEHAVIORS::HAPROXY || $behavior == ROLE_BEHAVIORS::NGINX || $behavior == ROLE_BEHAVIORS::RABBITMQ || $behavior == ROLE_BEHAVIORS::APACHE || $behavior == ROLE_BEHAVIORS::VPC_ROUTER) { $data = Scalr_Role_Behavior::loadByName($behavior)->getConfiguration($this->DBServer); } if ($data === null) { if ($behavior == ROLE_BEHAVIORS::MYSQL) { $data = new stdClass(); $data->logFile = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_LOG_FILE); $data->logPos = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_LOG_POS); $data->rootPassword = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_ROOT_PASSWORD); $data->replPassword = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_REPL_PASSWORD); $data->statPassword = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_STAT_PASSWORD); $data->replicationMaster = (int) $this->DBServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER); } else { try { $dbMsrInfo = Scalr_Db_Msr_Info::init($dbFarmRole, $this->DBServer, $behavior); $data = $dbMsrInfo->getMessageProperties(); } catch (Exception $e) { } } } if ($data) { $result->{$behavior} = $data; } } return $result; }
public function xTroubleshootAction() { $this->request->defineParams(array('serverId')); $dbServer = DBServer::LoadByID($this->getParam('serverId')); $this->user->getPermissions()->validate($dbServer); $dbServer->status = SERVER_STATUS::TROUBLESHOOTING; $dbServer->Save(); // Send before host terminate to the server to detach all used volumes. $msg = new Scalr_Messaging_Msg_BeforeHostTerminate($dbServer); if ($dbServer->farmRoleId != 0) { foreach (Scalr_Role_Behavior::getListForFarmRole($dbServer->GetFarmRoleObject()) as $behavior) { $msg = $behavior->extendMessage($msg, $dbServer); } } $dbServer->SendMessage($msg); Scalr::FireEvent($dbServer->farmId, new HostDownEvent($dbServer)); $this->response->success(); }
public function extendMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { $message = parent::extendMessage($message); try { $dbFarmRole = $dbServer->GetFarmRoleObject(); } catch (Exception $e) { } switch (get_class($message)) { case "Scalr_Messaging_Msg_HostInitResponse": $dbMsrInfo = Scalr_Db_Msr_Info::init($dbFarmRole, $dbServer, $this->behavior); $message->addDbMsrInfo($dbMsrInfo); break; case "Scalr_Messaging_Msg_DbMsr_PromoteToMaster": $dbMsrInfo = Scalr_Db_Msr_Info::init($dbFarmRole, $dbServer, $this->behavior); $message->addDbMsrInfo($dbMsrInfo); break; case "Scalr_Messaging_Msg_DbMsr_NewMasterUp": $dbMsrInfo = Scalr_Db_Msr_Info::init($dbFarmRole, $dbServer, $this->behavior); $message->addDbMsrInfo($dbMsrInfo); break; } return $message; }
/** * * @return Scalr_Scaling_Decision */ function makeScalingDecition() { /* Base Scaling */ foreach (Scalr_Role_Behavior::getListForFarmRole($this->dbFarmRole) as $behavior) { $result = $behavior->makeUpscaleDecision($this->dbFarmRole); if ($result === false) { continue; } else { return $result; } } $farm_pending_instances = $this->db->GetOne("SELECT COUNT(*) FROM servers WHERE farm_id=? AND status IN (?,?,?)", array($this->dbFarmRole->FarmID, SERVER_STATUS::PENDING, SERVER_STATUS::INIT, SERVER_STATUS::PENDING_LAUNCH)); if ($this->dbFarmRole->GetFarmObject()->RolesLaunchOrder == 1 && $farm_pending_instances > 0) { if ($this->dbFarmRole->GetRunningInstancesCount() == 0) { $this->logger->info("{$farm_pending_instances} instances in pending state. Launch roles one-by-one. Waiting..."); return Scalr_Scaling_Decision::STOP_SCALING; } } /* Metrics scaling */ foreach ($this->getFarmRoleMetrics() as $farmRoleMetric) { $scalingMetricDecision = $farmRoleMetric->getScalingDecision(); $this->logger->info(sprintf(_("Metric: %s. Decision: %s. Last value: %s"), $farmRoleMetric->getMetric()->name, $scalingMetricDecision, $farmRoleMetric->lastValue)); $scalingMetricName = $farmRoleMetric->getMetric()->name; $scalingMetricInstancesCount = null; if ($scalingMetricName == 'DateAndTime') { $scalingMetricInstancesCount = $farmRoleMetric->instancesNumber; } $this->decisonInfo = '1'; if ($scalingMetricDecision == Scalr_Scaling_Decision::NOOP) { continue; } Logger::getLogger(LOG_CATEGORY::FARM)->info(new FarmLogMessage($this->dbFarmRole->FarmID, sprintf("%s: Role '%s' on farm '%s'. Metric name: %s. Last metric value: %s.", $scalingMetricDecision, $this->dbFarmRole->Alias ? $this->dbFarmRole->Alias : $this->dbFarmRole->GetRoleObject()->name, $this->dbFarmRole->GetFarmObject()->Name, $farmRoleMetric->getMetric()->name, $farmRoleMetric->lastValue))); if ($scalingMetricDecision != Scalr_Scaling_Decision::NOOP) { break; } } $isDbMsr = $this->dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL) || $this->dbFarmRole->GetRoleObject()->getDbMsrBehavior(); $needOneByOneLaunch = $this->dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::RABBITMQ) || $this->dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MONGODB); // Check do we need upscale to min instances count $roleTotalInstances = $this->dbFarmRole->GetRunningInstancesCount() + $this->dbFarmRole->GetPendingInstancesCount(); $maxInstances = $this->dbFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_MAX_INSTANCES); $minInstances = $this->dbFarmRole->GetSetting(DBFarmRole::SETTING_SCALING_MIN_INSTANCES); if ($roleTotalInstances < $minInstances) { if ($needOneByOneLaunch) { $pendingTerminateInstances = count($this->dbFarmRole->GetServersByFilter(array('status' => SERVER_STATUS::PENDING_TERMINATE))); // If we launching DbMSR instances. Master should be running. if ($this->dbFarmRole->GetPendingInstancesCount() == 0 && !$pendingTerminateInstances) { $this->logger->info(_("Increasing number of running instances to fit min instances setting")); $this->decisonInfo = '2'; return Scalr_Scaling_Decision::UPSCALE; } else { $this->logger->info(_("Found servers in Pending or PendingTerminate state. Waiting...")); return Scalr_Scaling_Decision::NOOP; } } elseif ($isDbMsr) { // If we launching DbMSR instances. Master should be running. if ($this->dbFarmRole->GetRunningInstancesCount() > 0 || $this->dbFarmRole->GetPendingInstancesCount() == 0) { $this->logger->info(_("Increasing number of running instances to fit min instances setting")); $this->decisonInfo = '3'; return Scalr_Scaling_Decision::UPSCALE; } else { $this->logger->info(_("Waiting for running master")); return Scalr_Scaling_Decision::NOOP; } } else { $this->logger->info(_("Increasing number of running instances to fit min instances setting")); $this->decisonInfo = '4'; return Scalr_Scaling_Decision::UPSCALE; } } elseif ($maxInstances && $this->dbFarmRole->GetRunningInstancesCount() > $maxInstances) { // Need to check Date&Time based scaling. Otherwise Scalr downscale role every time. if ($scalingMetricInstancesCount) { if ($this->dbFarmRole->GetRunningInstancesCount() > $scalingMetricInstancesCount) { $this->logger->info(_("Decreasing number of running instances to fit DateAndTime scaling settings ({$scalingMetricInstancesCount})")); $this->decisonInfo = '5'; return Scalr_Scaling_Decision::DOWNSCALE; } } else { $this->logger->info(_("Decreasing number of running instances to fit max instances setting ({$scalingMetricInstancesCount})")); $this->decisonInfo = '6'; return Scalr_Scaling_Decision::DOWNSCALE; } } return $scalingMetricDecision ? $scalingMetricDecision : Scalr_Scaling_Decision::NOOP; }
private function getBehaviorsRecords(DBServer $dbServer) { $records = array(); if ($dbServer->farmRoleId != 0) { foreach (Scalr_Role_Behavior::getListForFarmRole($dbServer->GetFarmRoleObject()) as $behavior) { $records = array_merge($records, (array) $behavior->getDnsRecords($dbServer)); } } return $records; }
public function extendMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { $message = parent::extendMessage($message, $dbServer); switch (get_class($message)) { case "Scalr_Messaging_Msg_HostInitResponse": $config = $this->getConfiguration($dbServer); if ($config->serverUrl || $config->cookbookUrl) { $message->chef = $config; } break; } return $message; }
public function extendMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { $message = parent::extendMessage($message, $dbServer); switch (get_class($message)) { case "Scalr_Messaging_Msg_HostInitResponse": $message->router = new stdClass(); // Set scalr address $message->router->scalrAddr = \Scalr::config('scalr.endpoint.scheme') . "://" . \Scalr::config('scalr.endpoint.host'); // Set scalr IPs whitelist $message->router->whitelist = \Scalr::config('scalr.aws.ip_pool'); // Set CIDR $message->router->cidr = '10.0.0.0/8'; } return $message; }
public function extendMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { $message = parent::extendMessage($message, $dbServer); switch (get_class($message)) { case "Scalr_Messaging_Msg_HostInitResponse": $message->mongodb = $this->getConfiguration($dbServer); break; case "Scalr_Messaging_Msg_HostDown": case "Scalr_Messaging_Msg_HostUp": case "Scalr_Messaging_Msg_HostInit": case "Scalr_Messaging_Msg_BeforeHostTerminate": $message->mongodb = new stdClass(); $message->mongodb->replicaSetIndex = $dbServer->GetProperty(self::SERVER_REPLICA_SET_INDEX); $message->mongodb->shardIndex = $dbServer->GetProperty(self::SERVER_SHARD_INDEX); break; } return $message; }
/** * Gets the list of the security groups for the specified db server. * * If server does not have required security groups this method will create them. * * @param DBServer $DBServer The DB Server instance * @param \Scalr\Service\Aws\Ec2 $ec2 Ec2 Client instance * @param string $vpcId optional The ID of VPC * @param \Scalr_Governance $governance Governance * @param string $osFamily optional OS family of the instance * @return array Returns array looks like array(groupid-1, groupid-2, ..., groupid-N) */ private function GetServerSecurityGroupsList(DBServer $DBServer, \Scalr\Service\Aws\Ec2 $ec2, $vpcId = "", \Scalr_Governance $governance = null, $osFamily = null) { $retval = array(); $checkGroups = array(); $wildCardSgs = []; $sgGovernance = false; $allowAdditionalSgs = true; $roleBuilderSgName = \Scalr::config('scalr.aws.security_group_name') . "-rb"; if ($governance && $DBServer->farmRoleId) { $sgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS); if ($osFamily == 'windows' && $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'windows')) { $sgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'windows'); } if ($sgs !== null) { $governanceSecurityGroups = @explode(",", $sgs); if (!empty($governanceSecurityGroups)) { foreach ($governanceSecurityGroups as $sg) { if ($sg != '') { array_push($checkGroups, trim($sg)); if (strpos($sg, '*') !== false) { array_push($wildCardSgs, trim($sg)); } } } } if (!empty($checkGroups)) { $sgGovernance = true; } $allowAdditionalSgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'allow_additional_sec_groups'); } } if (!$sgGovernance || $allowAdditionalSgs) { if ($DBServer->farmRoleId != 0) { $dbFarmRole = $DBServer->GetFarmRoleObject(); if ($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SECURITY_GROUPS_LIST) !== null) { // New SG management $sgs = @json_decode($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SECURITY_GROUPS_LIST)); if (!empty($sgs)) { foreach ($sgs as $sg) { if (stripos($sg, 'sg-') === 0) { array_push($retval, $sg); } else { array_push($checkGroups, $sg); } } } } else { // Old SG management array_push($checkGroups, 'default'); array_push($checkGroups, \Scalr::config('scalr.aws.security_group_name')); if (!$vpcId) { array_push($checkGroups, "scalr-farm.{$DBServer->farmId}"); array_push($checkGroups, "scalr-role.{$DBServer->farmRoleId}"); } $additionalSgs = trim($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SG_LIST)); if ($additionalSgs) { $sgs = explode(",", $additionalSgs); if (!empty($sgs)) { foreach ($sgs as $sg) { $sg = trim($sg); if (stripos($sg, 'sg-') === 0) { array_push($retval, $sg); } else { array_push($checkGroups, $sg); } } } } } } else { array_push($checkGroups, $roleBuilderSgName); } } // No name based security groups, return only SG ids. if (empty($checkGroups)) { return $retval; } // Filter groups $filter = array(array('name' => SecurityGroupFilterNameType::groupName(), 'value' => $checkGroups)); // If instance run in VPC, add VPC filter if ($vpcId != '') { $filter[] = array('name' => SecurityGroupFilterNameType::vpcId(), 'value' => $vpcId); } // Get filtered list of SG required by scalr; try { $list = $ec2->securityGroup->describe(null, null, $filter); $sgList = array(); foreach ($list as $sg) { /* @var $sg \Scalr\Service\Aws\Ec2\DataType\SecurityGroupData */ if ($vpcId == '' && !$sg->vpcId || $vpcId && $sg->vpcId == $vpcId) { $sgList[$sg->groupName] = $sg->groupId; } } unset($list); } catch (Exception $e) { throw new Exception("Cannot get list of security groups (1): {$e->getMessage()}"); } foreach ($checkGroups as $groupName) { // Check default SG if ($groupName == 'default') { array_push($retval, $sgList[$groupName]); // Check Roles builder SG } elseif ($groupName == $roleBuilderSgName) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($roleBuilderSgName, "Security group for Roles Builder", $vpcId); $ipRangeList = new IpRangeList(); foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) { $ipRangeList->append(new IpRangeData($ip)); } sleep(2); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 22, 22, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList)), $securityGroupId); $sgList[$roleBuilderSgName] = $securityGroupId; } catch (Exception $e) { throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $roleBuilderSgName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); //Check scalr-farm.* security group } elseif (stripos($groupName, 'scalr-farm.') === 0) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmID N%s", $DBServer->farmId), $vpcId); sleep(2); $userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->keychain(SERVER_PLATFORMS::EC2)->properties[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID], null, $groupName)); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)), $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (Exception $e) { throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); //Check scalr-role.* security group } elseif (stripos($groupName, 'scalr-role.') === 0) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmRoleID N%s on FarmID N%s", $DBServer->GetFarmRoleObject()->ID, $DBServer->farmId), $vpcId); sleep(2); // DB rules $dbRules = $DBServer->GetFarmRoleObject()->GetRoleObject()->getSecurityRules(); $groupRules = array(); foreach ($dbRules as $rule) { $groupRules[CryptoTool::hash($rule['rule'])] = $rule; } // Behavior rules foreach (\Scalr_Role_Behavior::getListForFarmRole($DBServer->GetFarmRoleObject()) as $bObj) { $bRules = $bObj->getSecurityRules(); foreach ($bRules as $r) { if ($r) { $groupRules[CryptoTool::hash($r)] = array('rule' => $r); } } } // Default rules $userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->keychain(SERVER_PLATFORMS::EC2)->properties[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID], null, $groupName)); $rules = array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)); foreach ($groupRules as $rule) { $group_rule = explode(":", $rule["rule"]); $rules[] = new IpPermissionData($group_rule[0], $group_rule[1], $group_rule[2], new IpRangeData($group_rule[3])); } $ec2->securityGroup->authorizeIngress($rules, $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (Exception $e) { throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); } elseif ($groupName == \Scalr::config('scalr.aws.security_group_name')) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, "Security rules needed by Scalr", $vpcId); $ipRangeList = new IpRangeList(); foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) { $ipRangeList->append(new IpRangeData($ip)); } // TODO: Open only FOR VPC ranges $ipRangeList->append(new IpRangeData('10.0.0.0/8')); sleep(2); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 3306, 3306, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList), new IpPermissionData('udp', 8014, 8014, $ipRangeList)), $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (Exception $e) { throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); } else { if (!isset($sgList[$groupName])) { if (!in_array($groupName, $wildCardSgs)) { throw new Exception(sprintf(_("Security group '%s' is not found"), $groupName)); } else { $wildCardMatchedSgs = []; $groupNamePattern = \Scalr_Governance::convertAsteriskPatternToRegexp($groupName); foreach ($sgList as $sgGroupName => $sgGroupId) { if (preg_match($groupNamePattern, $sgGroupName) === 1) { array_push($wildCardMatchedSgs, $sgGroupId); } } if (empty($wildCardMatchedSgs)) { throw new Exception(sprintf(_("Security group matched to pattern '%s' is not found."), $groupName)); } else { if (count($wildCardMatchedSgs) > 1) { throw new Exception(sprintf(_("There are more than one Security group matched to pattern '%s' found."), $groupName)); } else { array_push($retval, $wildCardMatchedSgs[0]); } } } } else { array_push($retval, $sgList[$groupName]); } } } return $retval; }
/** * Makes a decision to scale farm * * @return Scalr_Scaling_Decision */ function makeScalingDecision() { /** * Base Scaling */ foreach (Scalr_Role_Behavior::getListForFarmRole($this->dbFarmRole) as $behavior) { $result = $behavior->makeUpscaleDecision($this->dbFarmRole); if ($result === false) { continue; } else { return $result; } } $farmPendingInstances = $this->db->GetOne("SELECT COUNT(*) FROM servers WHERE farm_id=? AND status IN (?,?,?)", array($this->dbFarmRole->FarmID, SERVER_STATUS::PENDING, SERVER_STATUS::INIT, SERVER_STATUS::PENDING_LAUNCH)); if ($this->dbFarmRole->GetFarmObject()->RolesLaunchOrder == 1 && $farmPendingInstances > 0) { if ($this->dbFarmRole->GetRunningInstancesCount() == 0) { $this->logger->info("{$farmPendingInstances} instances in pending state. Launch roles one-by-one. Waiting..."); return Scalr_Scaling_Decision::STOP_SCALING; } } $scalingMetricDecision = null; $scalingMetricInstancesCount = null; $this->logger->info(sprintf(_("%s scaling rules configured"), count($this->farmRoleMetrics))); if (isset($this->farmRoleMetrics[Entity\ScalingMetric::METRIC_DATE_AND_TIME_ID])) { $dateAndTimeMetric = $this->farmRoleMetrics[Entity\ScalingMetric::METRIC_DATE_AND_TIME_ID]; try { $scalingMetricDecision = $dateAndTimeMetric->getScalingDecision(); } catch (Exception $e) { $this->logger->error("Scaling error in deciding metric '{$dateAndTimeMetric->getMetric()->name}' for farm role '{$this->dbFarmRole->FarmID}:{$this->dbFarmRole->Alias}': {$e->getMessage()}"); } $scalingMetricName = $dateAndTimeMetric->getMetric()->name; $scalingMetricInstancesCount = $dateAndTimeMetric->instancesNumber; $this->decisonInfo = '1'; if ($scalingMetricDecision !== Scalr_Scaling_Decision::NOOP) { $this->logDecisionInfo($scalingMetricDecision, $scalingMetricName, $dateAndTimeMetric->lastValue); return $scalingMetricDecision; } } /** * Metrics scaling */ $farmRoleMetrics = array_diff_key($this->farmRoleMetrics, [Entity\ScalingMetric::METRIC_DATE_AND_TIME_ID => null]); if (!empty($farmRoleMetrics)) { $checkAllMetrics = $this->dbFarmRole->GetSetting(Entity\FarmRoleSetting::SCALING_DOWN_ONLY_IF_ALL_METRICS_TRUE); $variousDecisions = false; /* @var $farmRoleMetric Scalr_Scaling_FarmRoleMetric */ foreach ($farmRoleMetrics as $farmRoleMetric) { try { $newDecision = $farmRoleMetric->getScalingDecision(); } catch (Exception $e) { $this->logger->error("Scaling error in deciding metric '{$farmRoleMetric->getMetric()->name}' for farm role '{$this->dbFarmRole->FarmID}:{$this->dbFarmRole->Alias}': {$e->getMessage()}"); continue; } if (isset($scalingMetricDecision)) { if ($newDecision != $scalingMetricDecision) { $variousDecisions = true; } } $scalingMetricDecision = $newDecision; $scalingMetricName = $farmRoleMetric->getMetric()->name; $this->decisonInfo = '1'; switch ($scalingMetricDecision) { case Scalr_Scaling_Decision::NOOP: continue; case Scalr_Scaling_Decision::DOWNSCALE: if (!$checkAllMetrics) { break 2; } continue; case Scalr_Scaling_Decision::UPSCALE: break 2; } } if (isset($scalingMetricDecision) && !($scalingMetricDecision == Scalr_Scaling_Decision::DOWNSCALE && $checkAllMetrics && $variousDecisions)) { $this->logDecisionInfo($scalingMetricDecision, $scalingMetricName, isset($farmRoleMetric) ? $farmRoleMetric->lastValue : null); } else { $scalingMetricDecision = Scalr_Scaling_Decision::NOOP; } } return $this->getFinalDecision($scalingMetricDecision, $scalingMetricInstancesCount); }
public function xAddReplicaSetAction() { $dbFarmRole = $this->getFarmRole(); if ($dbFarmRole->GetSetting(Scalr_Role_Behavior_MongoDB::ROLE_CLUSTER_STATUS) != Scalr_Role_Behavior_MongoDB::STATUS_ACTIVE) { throw new Exception("You cannot add replica set from non-active cluster"); } $replicasCount = $dbFarmRole->GetSetting(Scalr_Role_Behavior_MongoDB::ROLE_REPLICAS_COUNT); $dbFarmRole->SetSetting(Scalr_Role_Behavior_MongoDB::ROLE_REPLICAS_COUNT, $replicasCount + 1); Scalr_Role_Behavior::loadByName(ROLE_BEHAVIORS::MONGODB)->log($dbFarmRole, sprintf("Requested new replica set. Adding #%s replica set to the cluster", $replicasCount + 1)); $this->response->success('Replica successfully added. It may take a few minutes before it becomes available.'); }
public function statusAction() { $this->request->defineParams(array('farmId' => array('type' => 'int'), 'farmRoleId' => array('type' => 'int'), 'type')); $dbFarm = DBFarm::LoadByID($this->getParam('farmId')); $this->user->getPermissions()->validate($dbFarm); if ($this->getParam('farmRoleId')) { $dbFarmRole = DBFarmRole::LoadByID($this->getParam('farmRoleId')); if ($dbFarmRole->FarmID != $dbFarm->ID) { throw new Exception("Role not found"); } } elseif ($this->getParam('type')) { foreach ($dbFarm->GetFarmRoles() as $sDbFarmRole) { if ($sDbFarmRole->GetRoleObject()->hasBehavior($this->getParam('type'))) { $dbFarmRole = $sDbFarmRole; break; } } if (!$dbFarmRole) { throw new Exception("Role not found"); } } else { throw new Scalr_UI_Exception_NotFound(); } $data = array('farmRoleId' => $dbFarmRole->ID, 'farmHash' => $dbFarm->Hash, 'pmaAccessConfigured' => false, 'staticDnsSupported' => \Scalr::config('scalr.dns.static.enabled')); $data['backupsNotSupported'] = in_array($dbFarmRole->Platform, array(SERVER_PLATFORMS::CLOUDSTACK, SERVER_PLATFORMS::IDCF)); if ($dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_PMA_USER)) { $data['pmaAccessConfigured'] = true; } else { $errmsg = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_PMA_REQUEST_ERROR); if (!$errmsg) { $time = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_PMA_REQUEST_TIME); if ($time) { if ($time + 3600 < time()) { $data['pmaAccessError'] = _("Scalr didn't receive auth info from MySQL instance. Please check that MySQL running and Scalr has access to it."); } else { $data['pmaAccessSetupInProgress'] = true; } } } else { $data['pmaAccessError'] = $errmsg; } } //TODO: Legacy code. Move to DB_MSR if ($dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL)) { $data['dbType'] = Scalr_Db_Msr::DB_TYPE_MYSQL; $data['dtLastBundle'] = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_LAST_BUNDLE_TS) ? Scalr_Util_DateTime::convertTz((int) $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_LAST_BUNDLE_TS), 'd M Y \\a\\t H:i:s') : 'Never'; $data['dtLastBackup'] = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_LAST_BCP_TS) ? Scalr_Util_DateTime::convertTz((int) $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_LAST_BCP_TS), 'd M Y \\a\\t H:i:s') : 'Never'; $data['additionalInfo']['MasterUsername'] = '******'; $data['additionalInfo']['MasterPassword'] = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_ROOT_PASSWORD); $slaveNumber = 0; foreach ($dbFarmRole->GetServersByFilter() as $dbServer) { if ($dbServer->status != SERVER_STATUS::RUNNING) { //TODO: continue; } if ($dbServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) == 1) { $data['isBundleRunning'] = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_IS_BUNDLE_RUNNING); $data['bundleServerId'] = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_BUNDLE_SERVER_ID); } $data['isBackupRunning'] = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_IS_BCP_RUNNING); $data['backupServerId'] = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_BCP_SERVER_ID); try { $isCloudstack = in_array($dbFarmRole->Platform, array(SERVER_PLATFORMS::CLOUDSTACK, SERVER_PLATFORMS::IDCF)); $isMaster = $dbServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) == 1; if (!$isCloudstack) { $rStatus = $this->getMySqlReplicationStatus($isMaster ? 'MASTER' : 'SLAVE', $dbServer->remoteIp, 'scalr_stat', $dbFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_STAT_PASSWORD)); } if ($isMaster) { $MasterPosition = $rStatus['Position']; $master_ip = $dbServer->remoteIp; $master_iid = $dbServer->serverId; } else { $num = ++$slaveNumber; $SlavePosition = $rStatus['Exec_Master_Log_Pos']; } $d = array("serverId" => $dbServer->serverId, "localIp" => $dbServer->localIp, "remoteIp" => $dbServer->remoteIp, "replicationRole" => $isMaster ? 'Master' : "Slave #{$num}"); if (!$isCloudstack) { $d['data'] = $rStatus; $d['masterPosition'] = $MasterPosition; $d['slavePosition'] = $SlavePosition; } $data["replicationStatus"][] = $d; } catch (Exception $e) { $data["replicationStatus"][] = array("serverId" => $dbServer->serverId, "localIp" => $dbServer->localIp, "remoteIp" => $dbServer->remoteIp, "error" => $e->msg ? $e->msg : $e->getMessage(), "replicationRole" => $isMaster ? 'Master' : 'Slave'); } } } else { $data['dbType'] = $dbFarmRole->GetRoleObject()->getDbMsrBehavior(); if (!$data['dbType']) { $this->response->failure("Unknown db type"); } $behavior = Scalr_Role_Behavior::loadByName($data['dbType']); $masterServer = $behavior->getMasterServer($dbFarmRole); // Get Stoarge usage $size = array('total' => -1, 'used' => -1, 'free' => -1); if ($masterServer) { try { $port = $masterServer->GetProperty(SERVER_PROPERTIES::SZR_API_PORT); if (!$port) { $port = 8010; } if ($data['dbType'] == ROLE_BEHAVIORS::REDIS) { $mpoint = '/mnt/redisstorage'; } elseif ($data['dbType'] == ROLE_BEHAVIORS::POSTGRESQL) { $mpoint = '/mnt/pgstorage'; } else { $mpoint = '/mnt/dbstorage'; } $usage = (array) $masterServer->scalarizr->system->statvfs(array($mpoint)); $size = (array) $usage[$mpoint]; if ($size['total']) { $size['used'] = $size['total'] - $size['free']; // Convert KB to GB foreach ($size as $k => $v) { $size[$k] = round($v / 1024 / 1024, 2); } } } catch (Exception $e) { $this->response->debugException($e); } } $data['storage'] = array('engine' => $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_ENGINE), 'id' => $dbFarmRole->GetSetting(Scalr_Db_Msr::VOLUME_ID) ? $dbFarmRole->GetSetting(Scalr_Db_Msr::VOLUME_ID) : '', 'fs' => $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_FSTYPE), 'size' => $size); switch ($data['storage']['engine']) { case MYSQL_STORAGE_ENGINE::EBS: $data['storage']['engineName'] = 'Single EBS volume'; break; case MYSQL_STORAGE_ENGINE::RAID_EBS: $data['storage']['engineName'] = sprintf('RAID %s on %s EBS volumes', $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_RAID_LEVEL), $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_RAID_DISKS_COUNT)); break; case MYSQL_STORAGE_ENGINE::LVM: $data['storage']['engineName'] = 'LVM on ephemeral device(s)'; break; case MYSQL_STORAGE_ENGINE::EPH: $data['storage']['engineName'] = 'Ephemeral device'; break; case MYSQL_STORAGE_ENGINE::CSVOL: $data['storage']['engineName'] = 'Single Cloudstack volume'; break; default: $data['storage']['engineName'] = $data['storage']['engine']; break; } $data['additionalInfo']['MasterUsername'] = '******'; if ($dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::POSTGRESQL)) { $data['additionalInfo']['MasterPassword'] = $dbFarmRole->GetSetting(Scalr_Db_Msr_Postgresql::ROOT_PASSWORD); $name = 'PostgreSQL'; } elseif ($dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::REDIS)) { $ports = @json_decode($dbFarmRole->GetSetting(Scalr_Db_Msr_Redis::PORTS_ARRAY)); $passwords = @json_decode($dbFarmRole->GetSetting(Scalr_Db_Msr_Redis::PASSWD_ARRAY)); if (!$ports && !$passwords) { $data['additionalInfo']['MasterPassword'] = $dbFarmRole->GetSetting(Scalr_Db_Msr_Redis::MASTER_PASSWORD); } else { $data['additionalInfo']['MasterPassword'] = ""; foreach ($ports as $i => $port) { $data['additionalInfo']['MasterPassword'] .= "Port {$port}: {$passwords[$i]}<br>"; } } $name = 'Redis'; } elseif ($dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL2)) { $data['additionalInfo']['MasterPassword'] = $dbFarmRole->GetSetting(Scalr_Db_Msr_Mysql2::ROOT_PASSWORD); $name = 'MySQL'; } elseif ($dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::PERCONA)) { $data['additionalInfo']['MasterPassword'] = $dbFarmRole->GetSetting(Scalr_Db_Msr_Percona::ROOT_PASSWORD); $name = 'Percona Server'; } elseif ($dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MARIADB)) { $data['additionalInfo']['MasterPassword'] = $dbFarmRole->GetSetting(Scalr_Db_Msr_Mariadb::ROOT_PASSWORD); $name = 'MariaDB'; } if (!$data['additionalInfo']['MasterPassword']) { $data['additionalInfo']['MasterPassword'] = ""; } $data['name'] = $name; if ($dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_ENGINE) == 'lvm') { $data['noDataBundleForSlaves'] = $dbFarmRole->GetSetting(Scalr_Role_DbMsrBehavior::ROLE_NO_DATA_BUNDLE_FOR_SLAVES) ? true : false; } $data['dtLastBackup'] = $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_BACKUP_LAST_TS) ? Scalr_Util_DateTime::convertTz((int) $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_BACKUP_LAST_TS), 'd M Y \\a\\t H:i:s') : 'Never'; $data['dtLastBundle'] = $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_BUNDLE_LAST_TS) ? Scalr_Util_DateTime::convertTz((int) $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_BUNDLE_LAST_TS), 'd M Y \\a\\t H:i:s') : 'Never'; $slaveNumber = 0; foreach ($dbFarmRole->GetServersByFilter() as $dbServer) { if ($dbServer->status != SERVER_STATUS::RUNNING) { //TODO: continue; } if ($dbServer->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER) == 1) { $data['isBundleRunning'] = $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_BUNDLE_IS_RUNNING); $data['bundleServerId'] = $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_BUNDLE_SERVER_ID); } $data['isBackupRunning'] = $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_BACKUP_IS_RUNNING); $data['backupServerId'] = $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_BACKUP_SERVER_ID); try { $isCloudstack = in_array($dbFarmRole->Platform, array(SERVER_PLATFORMS::CLOUDSTACK, SERVER_PLATFORMS::IDCF)); $isMaster = $dbServer->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER) == 1; if (!$isCloudstack && in_array($this->getParam('type'), array(ROLE_BEHAVIORS::MYSQL2, ROLE_BEHAVIORS::PERCONA, ROLE_BEHAVIORS::MARIADB))) { $password = $dbFarmRole->GetSetting(Scalr_Db_Msr_Mysql2::STAT_PASSWORD); $rStatus = $this->getMySqlReplicationStatus($isMaster ? 'MASTER' : 'SLAVE', $dbServer->remoteIp, 'scalr_stat', $password); } if ($isMaster) { $MasterPosition = $rStatus['Position']; $master_ip = $dbServer->remoteIp; $master_iid = $dbServer->serverId; } else { $num = ++$slaveNumber; $SlavePosition = $rStatus['Exec_Master_Log_Pos']; } $d = array("serverId" => $dbServer->serverId, "localIp" => $dbServer->localIp, "remoteIp" => $dbServer->remoteIp, "replicationRole" => $isMaster ? 'Master' : "Slave #{$num}"); if (!$isCloudstack) { $d['data'] = $rStatus; $d['masterPosition'] = $MasterPosition; $d['slavePosition'] = $SlavePosition; } $data["replicationStatus"][] = $d; } catch (Exception $e) { $data["replicationStatus"][] = array("serverId" => $dbServer->serverId, "localIp" => $dbServer->localIp, "remoteIp" => $dbServer->remoteIp, "error" => $e->msg ? $e->msg : $e->getMessage(), "replicationRole" => $isMaster ? 'Master' : 'Slave'); } } } $this->response->page('ui/dbmsr/status.js', $data); }
/** * Gets the list of the security groups for the specified db server. * * If server does not have required security groups this method will create them. * * @param DBServer $DBServer The DB Server instance * @param \Scalr\Service\Aws\Ec2 $ec2 Ec2 Client instance * @param string $vpcId optional The ID of VPC * @return array Returns array looks like array(groupid-1, groupid-2, ..., groupid-N) */ private function GetServerSecurityGroupsList(DBServer $DBServer, \Scalr\Service\Aws\Ec2 $ec2, $vpcId = "", \Scalr_Governance $governance = null) { $retval = array(); $checkGroups = array(); $sgGovernance = true; $allowAdditionalSgs = true; $vpcId = null; if ($governance) { $sgs = $governance->getValue(\SERVER_PLATFORMS::EUCALYPTUS, \Scalr_Governance::EUCALYPTUS_SECURITY_GROUPS); if ($sgs !== null) { $governanceSecurityGroups = @explode(",", $sgs); if (!empty($governanceSecurityGroups)) { foreach ($governanceSecurityGroups as $sg) { if ($sg != '') { array_push($checkGroups, trim($sg)); } } } $sgGovernance = false; $allowAdditionalSgs = $governance->getValue(\SERVER_PLATFORMS::EUCALYPTUS, \Scalr_Governance::EUCALYPTUS_SECURITY_GROUPS, 'allow_additional_sec_groups'); } } if (!$sgGovernance || $allowAdditionalSgs) { if ($DBServer->farmRoleId != 0) { $dbFarmRole = $DBServer->GetFarmRoleObject(); if ($dbFarmRole->GetSetting(DBFarmRole::SETTING_EUCA_SECURITY_GROUPS_LIST) !== null) { // New SG management $sgs = @json_decode($dbFarmRole->GetSetting(DBFarmRole::SETTING_EUCA_SECURITY_GROUPS_LIST)); if (!empty($sgs)) { foreach ($sgs as $sg) { if (stripos($sg, 'sg-') === 0) { array_push($retval, $sg); } else { array_push($checkGroups, $sg); } } } } } else { array_push($checkGroups, 'scalr-rb-system'); } } // No name based security groups, return only SG ids. if (empty($checkGroups)) { return $retval; } // Filter groups $filter = array(array('name' => SecurityGroupFilterNameType::groupName(), 'value' => $checkGroups)); // Get filtered list of SG required by scalr; try { $list = $ec2->securityGroup->describe(null, null, $filter); $sgList = array(); foreach ($list as $sg) { /* @var $sg \Scalr\Service\Aws\Ec2\DataType\SecurityGroupData */ if ($vpcId == '' && !$sg->vpcId || $vpcId && $sg->vpcId == $vpcId) { $sgList[$sg->groupName] = $sg->groupId; } } unset($list); } catch (\Exception $e) { throw new \Exception("Cannot get list of security groups (1): {$e->getMessage()}"); } foreach ($checkGroups as $groupName) { // Check default SG if ($groupName == 'default') { array_push($retval, $sgList[$groupName]); // Check Roles builder SG } elseif ($groupName == 'scalr-rb-system') { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create('scalr-rb-system', "Security group for Roles Builder", $vpcId); $ipRangeList = new IpRangeList(); foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) { $ipRangeList->append(new IpRangeData($ip)); } sleep(2); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 22, 22, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList)), $securityGroupId); $sgList['scalr-rb-system'] = $securityGroupId; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot create security group '%s': %s"), 'scalr-rb-system', $e->getMessage())); } } array_push($retval, $sgList[$groupName]); //Check scalr-farm.* security group } elseif (stripos($groupName, 'scalr-farm.') === 0) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmID N%s", $DBServer->farmId), $vpcId); sleep(2); $userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->getPlatformConfigValue(self::ACCOUNT_ID), null, $groupName)); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)), $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); //Check scalr-role.* security group } elseif (stripos($groupName, 'scalr-role.') === 0) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmRoleID N%s on FarmID N%s", $DBServer->GetFarmRoleObject()->ID, $DBServer->farmId), $vpcId); sleep(2); // DB rules $dbRules = $DBServer->GetFarmRoleObject()->GetRoleObject()->getSecurityRules(); $groupRules = array(); foreach ($dbRules as $rule) { $groupRules[\Scalr_Util_CryptoTool::hash($rule['rule'])] = $rule; } // Behavior rules foreach (\Scalr_Role_Behavior::getListForFarmRole($DBServer->GetFarmRoleObject()) as $bObj) { $bRules = $bObj->getSecurityRules(); foreach ($bRules as $r) { if ($r) { $groupRules[\Scalr_Util_CryptoTool::hash($r)] = array('rule' => $r); } } } // Default rules $userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->getPlatformConfigValue(self::ACCOUNT_ID), null, $groupName)); $rules = array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)); foreach ($groupRules as $rule) { $group_rule = explode(":", $rule["rule"]); $rules[] = new IpPermissionData($group_rule[0], $group_rule[1], $group_rule[2], new IpRangeData($group_rule[3])); } $ec2->securityGroup->authorizeIngress($rules, $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); } elseif ($groupName == \Scalr::config('scalr.aws.security_group_name')) { if (!isset($sgList[$groupName])) { try { $securityGroupId = $ec2->securityGroup->create($groupName, "Security rules needed by Scalr", $vpcId); $ipRangeList = new IpRangeList(); foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) { $ipRangeList->append(new IpRangeData($ip)); } // TODO: Open only FOR VPC ranges $ipRangeList->append(new IpRangeData('10.0.0.0/8')); sleep(2); $ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 3306, 3306, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList), new IpPermissionData('udp', 8014, 8014, $ipRangeList)), $securityGroupId); $sgList[$groupName] = $securityGroupId; } catch (\Exception $e) { throw new \Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage())); } } array_push($retval, $sgList[$groupName]); } else { if (!isset($sgList[$groupName])) { throw new \Exception(sprintf(_("Security group '%s' is not found"), $groupName)); } else { array_push($retval, $sgList[$groupName]); } } } return $retval; }
public function ListFarmRoleParams() { $farmRoleId = $this->GetArg("farm-role-id"); if (!$farmRoleId) { throw new Exception("'farm-role-id' required"); } $dbFarmRole = DBFarmRole::LoadByID($farmRoleId); if ($dbFarmRole->FarmID != $this->DBServer->farmId) { throw new Exception("You can request this information ONLY for roles within server farm"); } $ResponseDOMDocument = $this->CreateResponse(); // Add volumes information try { if ($this->DBServer->farmRoleId == $farmRoleId) { $storage = new FarmRoleStorage($dbFarmRole); $vols = $storage->getVolumesConfigs($this->DBServer->index); $volumes = array(); foreach ($vols as $i => $volume) { if ($volume->id) { $volumes[] = $volume; } } $bodyEl = $this->serialize($volumes, 'volumes', $ResponseDOMDocument); $ResponseDOMDocument->documentElement->appendChild($bodyEl); } } catch (Exception $e) { $this->Logger->fatal("ListFarmRoleParams::Storage: {$e->getMessage()}"); } $role = $dbFarmRole->GetRoleObject(); $behaviors = $role->getBehaviors(); foreach ($behaviors as $behavior) { $data = null; if ($behavior == ROLE_BEHAVIORS::MONGODB) { $data = Scalr_Role_Behavior::loadByName($behavior)->getConfiguration($this->DBServer); } if ($behavior == ROLE_BEHAVIORS::CHEF) { $data = Scalr_Role_Behavior::loadByName($behavior)->getConfiguration($this->DBServer); } if ($behavior == ROLE_BEHAVIORS::HAPROXY) { $data = Scalr_Role_Behavior::loadByName($behavior)->getConfiguration($this->DBServer); } if ($behavior == ROLE_BEHAVIORS::NGINX) { $data = Scalr_Role_Behavior::loadByName($behavior)->getConfiguration($this->DBServer); } if ($behavior == ROLE_BEHAVIORS::RABBITMQ) { $data = Scalr_Role_Behavior::loadByName($behavior)->getConfiguration($this->DBServer); } if ($behavior == ROLE_BEHAVIORS::APACHE) { $data = Scalr_Role_Behavior::loadByName($behavior)->getConfiguration($this->DBServer); } if ($data === null) { if ($behavior == ROLE_BEHAVIORS::CF_CLOUD_CONTROLLER) { $data = new stdClass(); $data->version = $dbFarmRole->GetSetting(Scalr_Role_Behavior_CfCloudController::ROLE_VERSION); } else { if ($behavior == ROLE_BEHAVIORS::MYSQL) { $data = new stdClass(); $data->logFile = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_LOG_FILE); $data->logPos = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_LOG_POS); $data->rootPassword = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_ROOT_PASSWORD); $data->replPassword = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_REPL_PASSWORD); $data->statPassword = $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_STAT_PASSWORD); $data->replicationMaster = (int) $this->DBServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER); //TODO: Storage } else { try { $dbMsrInfo = Scalr_Db_Msr_Info::init($dbFarmRole, $this->DBServer, $behavior); $data = $dbMsrInfo->getMessageProperties(); } catch (Exception $e) { } } } } if ($data) { $bodyEl = $this->serialize($data, $behavior, $ResponseDOMDocument); $ResponseDOMDocument->documentElement->appendChild($bodyEl); } } return $ResponseDOMDocument; }
public function __construct($behaviorName) { parent::__construct($behaviorName); }
public function FarmAddRole($Alias, $FarmID, $RoleID, $Platform, $CloudLocation, array $Configuration = array()) { try { $dbFarm = DBFarm::LoadByID($FarmID); if ($dbFarm->EnvID != $this->Environment->id) { throw new Exception("N"); } } catch (Exception $e) { throw new Exception(sprintf("Farm #%s not found", $FarmID)); } $this->user->getPermissions()->validate($dbFarm); $this->restrictFarmAccess($dbFarm, Acl::PERM_FARMS_MANAGE); $dbFarm->isLocked(true); $governance = new Scalr_Governance($this->Environment->id); $dbRole = DBRole::loadById($RoleID); if ($dbRole->envId != 0) { $this->user->getPermissions()->validate($dbRole); } foreach ($dbRole->getBehaviors() as $behavior) { if ($behavior != ROLE_BEHAVIORS::BASE && $behavior != ROLE_BEHAVIORS::CHEF) { throw new Exception("Only base roles supported to be added to farm via API"); } } $config = array('scaling.enabled' => 0, 'scaling.min_instances' => 1, 'scaling.max_instances' => 1, 'scaling.polling_interval' => 2, 'system.timeouts.launch' => 9600, 'system.timeouts.reboot' => 9600); if (PlatformFactory::isOpenstack($Platform)) { //TODO: } if ($Platform == SERVER_PLATFORMS::EC2) { $config['aws.security_groups.list'] = json_encode(array('default', \Scalr::config('scalr.aws.security_group_name'))); $vpcId = $dbFarm->GetSetting(DBFarm::SETTING_EC2_VPC_ID); if ($vpcId) { if (!$Configuration['aws.vpc_subnet_id']) { throw new Exception("Farm configured to run inside VPC. 'aws.vpc_subnet_id' is required"); } $vpcRegion = $dbFarm->GetSetting(DBFarm::SETTING_EC2_VPC_REGION); if ($CloudLocation != $vpcRegion) { throw new Exception(sprintf("Farm configured to run inside VPC in %s region. Only roles in this region are allowed.", $vpcRegion)); } $vpcGovernance = $governance->getValue('ec2', 'aws.vpc'); $vpcGovernanceIds = $governance->getValue('ec2', 'aws.vpc', 'ids'); $subnets = json_decode($Configuration['aws.vpc_subnet_id'], true); if (count($subnets) == 0) { throw new Exception("Subnets list is empty or json is incorrect"); } $type = false; foreach ($subnets as $subnetId) { $platform = PlatformFactory::NewPlatform(SERVER_PLATFORMS::EC2); $info = $platform->listSubnets($this->Environment, $CloudLocation, $vpcId, true, $subnetId); if (substr($info['availability_zone'], 0, -1) != $vpcRegion) { throw new Exception(sprintf("Only subnets from %s region are allowed according to VPC settings", $vpcRegion)); } if ($vpcGovernance == 1) { // Check valid subnets if ($vpcGovernanceIds[$vpcId] && is_array($vpcGovernanceIds[$vpcId]) && !in_array($subnetId, $vpcGovernanceIds[$vpcId])) { throw new Exception(sprintf("Only %s subnet(s) allowed by governance settings", implode(', ', $vpcGovernanceIds[$vpcId]))); } // Check if subnets types if ($vpcGovernanceIds[$vpcId] == "outbound-only") { if ($info['type'] != 'private') { throw new Exception("Only private subnets allowed by governance settings"); } } if ($vpcGovernanceIds[$vpcId] == "full") { if ($info['type'] != 'public') { throw new Exception("Only public subnets allowed by governance settings"); } } } if (!$type) { $type = $info['type']; } else { if ($type != $info['type']) { throw new Exception("Mix of public and private subnets are not allowed. Please specify only public or only private subnets."); } } } } } if (PlatformFactory::isCloudstack($Platform)) { $config['cloudstack.security_groups.list'] = json_encode(array('default', \Scalr::config('scalr.aws.security_group_name'))); } if ($Platform == SERVER_PLATFORMS::GCE) { $config['gce.network'] = 'default'; $config['gce.on-host-maintenance'] = 'MIGRATE'; } if ($Configuration[Scalr_Role_Behavior_Chef::ROLE_CHEF_BOOTSTRAP] == 1 && !$Configuration[Scalr_Role_Behavior_Chef::ROLE_CHEF_ENVIRONMENT]) { $config[Scalr_Role_Behavior_Chef::ROLE_CHEF_ENVIRONMENT] = '_default'; } $config = array_merge($config, $Configuration); $this->validateFarmRoleConfiguration($config); if ($Platform == SERVER_PLATFORMS::GCE) { $config['gce.cloud-location'] = $CloudLocation; $config['gce.region'] = substr($CloudLocation, 0, -1); } $Alias = $this->stripValue($Alias); if (strlen($Alias) < 4) { throw new Exception("Role Alias should be longer than 4 characters"); } if (!preg_match("/^[A-Za-z0-9]+[A-Za-z0-9-]*[A-Za-z0-9]+\$/si", $Alias)) { throw new Exception("Alias should start and end with letter or number and contain only letters, numbers and dashes."); } if (!$this->Environment->isPlatformEnabled($Platform)) { throw new Exception("'{$Platform}' cloud is not configured in your environment"); } $images = $dbRole->__getNewRoleObject()->fetchImagesArray(); $locations = isset($images[$Platform]) ? array_keys($images[$Platform]) : []; if (!in_array($CloudLocation, $locations) && $Platform != SERVER_PLATFORMS::GCE) { throw new Exception(sprintf("Role '%s' doesn't have an image configured for cloud location '%s'", $dbRole->name, $CloudLocation)); } if ($Alias) { foreach ($dbFarm->GetFarmRoles() as $farmRole) { if ($farmRole->Alias == $Alias) { throw new Exception("Selected alias is already used by another role in selected farm"); } } } $dbFarmRole = $dbFarm->AddRole($dbRole, $Platform, $CloudLocation, 1); $dbFarmRole->Alias = $Alias ? $Alias : $dbRole->name; foreach ($config as $k => $v) { $dbFarmRole->SetSetting($k, trim($v), DBFarmRole::TYPE_CFG); } foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->onFarmSave($dbFarm, $dbFarmRole); } $dbFarmRole->Save(); $response = $this->CreateInitialResponse(); $response->FarmRoleID = $dbFarmRole->ID; return $response; }
public function FarmAddRole($Alias, $FarmID, $RoleID, $Platform, $CloudLocation, array $Configuration = array()) { $this->restrictAccess(Acl::RESOURCE_FARMS, Acl::PERM_FARMS_MANAGE); try { $dbFarm = DBFarm::LoadByID($FarmID); if ($dbFarm->EnvID != $this->Environment->id) { throw new Exception("N"); } } catch (Exception $e) { throw new Exception(sprintf("Farm #%s not found", $FarmID)); } $this->user->getPermissions()->validate($dbFarm); $dbFarm->isLocked(true); $dbRole = DBRole::loadById($RoleID); if ($dbRole->envId != 0) { $this->user->getPermissions()->validate($dbRole); } foreach ($dbRole->getBehaviors() as $behavior) { if ($behavior != ROLE_BEHAVIORS::BASE && $behavior != ROLE_BEHAVIORS::CHEF) { throw new Exception("Only base roles supported to be added to farm via API"); } } $config = array('scaling.enabled' => 0, 'scaling.min_instances' => 1, 'scaling.max_instances' => 1, 'scaling.polling_interval' => 2, 'system.timeouts.launch' => 9600, 'system.timeouts.reboot' => 9600); if (PlatformFactory::isOpenstack($Platform)) { //TODO: } if ($Platform == SERVER_PLATFORMS::EC2) { $config['aws.security_groups.list'] = json_encode(array('default', \Scalr::config('scalr.aws.security_group_name'))); } if ($Configuration[Scalr_Role_Behavior_Chef::ROLE_CHEF_BOOTSTRAP] == 1 && !$Configuration[Scalr_Role_Behavior_Chef::ROLE_CHEF_ENVIRONMENT]) { $config[Scalr_Role_Behavior_Chef::ROLE_CHEF_ENVIRONMENT] = '_default'; } $config = array_merge($config, $Configuration); $this->validateFarmRoleConfiguration($config); $Alias = $this->stripValue($Alias); if (strlen($Alias) < 4) { throw new Exception("Role Alias should be longer than 4 characters"); } if (preg_match("/^[^A-Za-z0-9_-]+\$/", $Alias)) { throw new Exception("Role Alias should has only 'A-Za-z0-9-_' characters"); } if (!PlatformFactory::isOpenstack($Platform) && $Platform != SERVER_PLATFORMS::EC2) { throw new Exception("Only EC2 and Openstack roles are supported by this method"); } if (!$this->Environment->isPlatformEnabled($Platform)) { throw new Exception("'{$Platform}' cloud is not configured in your environment"); } $locations = $dbRole->getCloudLocations($Platform); if (!in_array($CloudLocation, $locations)) { throw new Exception(sprintf("Role '%s' doesn't have image configured for cloud location '%s'", $dbRole->name, $CloudLocation)); } if ($Alias) { foreach ($dbFarm->GetFarmRoles() as $farmRole) { if ($farmRole->Alias == $Alias) { throw new Exception("Selected alias is already used by another role in selected farm"); } } } $dbFarmRole = $dbFarm->AddRole($dbRole, $Platform, $CloudLocation, 1); $dbFarmRole->Alias = $Alias ? $Alias : $dbRole->name; foreach ($config as $k => $v) { $dbFarmRole->SetSetting($k, $v, DBFarmRole::TYPE_CFG); } foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->onFarmSave($dbFarm, $dbFarmRole); } $dbFarmRole->Save(); $response = $this->CreateInitialResponse(); $response->FarmRoleID = $dbFarmRole->ID; return $response; }
if ($dbInfoId) { $dbRole = DBRole::loadById($dbInfoId); } else { $dbRole = new DBRole(0); $dbRole->generation = 2; $dbRole->origin = ROLE_TYPE::SHARED; $dbRole->envId = 0; $dbRole->clientId = 0; $dbRole->catId = $info['catId']; $dbRole->name = $info['name']; $dbRole->os = $info['os']; $dbRole->osFamily = $info['osFamily']; $dbRole->osGeneration = $info['osGeneration']; $dbRole->osVersion = $info['osVersion']; foreach ($info['behaviors'] as $behavior) { foreach (Scalr_Role_Behavior::loadByName($behavior)->getSecurityRules() as $rr) { $rules[] = array('rule' => $rr); } } } $dbRole->setBehaviors(array_values($info['behaviors'])); $dbRole->description = $info['description']; $dbRole = $dbRole->save(); $db->Execute("DELETE FROM role_security_rules WHERE role_id = ?", array($dbRole->id)); foreach ($rules as $rule) { $db->Execute("INSERT INTO role_security_rules SET `role_id`=?, `rule`=?", array($dbRole->id, $rule['rule'])); if ($rule['comment']) { $db->Execute("REPLACE INTO `comments` SET `env_id` = ?, `comment` = ?, `sg_name` = ?, `rule` = ?", array(0, $rule['comment'], "role:{$dbRole->id}", $rule['rule'])); } } foreach ($info['images'] as $image) {
public function extendMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { $message = parent::extendMessage($message); $dbFarmRole = $dbServer->GetFarmRoleObject(); $chefServerId = $dbFarmRole->GetSetting(self::ROLE_CHEF_SERVER_ID); $runListId = $dbFarmRole->GetSetting(self::ROLE_CHEF_RUNLIST_ID); if (!$chefServerId || !$runListId) { return $message; } $chefRunListInfo = $this->db->GetRow("SELECT * FROM services_chef_runlists WHERE id=?", array($runListId)); $chefServerInfo = $this->db->GetRow("SELECT * FROM services_chef_servers WHERE id=?", array($chefRunListInfo['chef_server_id'])); $chefServerInfo['v_auth_key'] = trim($this->getCrypto()->decrypt($chefServerInfo['v_auth_key'], $this->cryptoKey)); switch (get_class($message)) { case "Scalr_Messaging_Msg_HostInitResponse": $message->chef = new stdClass(); $message->chef->serverUrl = $chefServerInfo['url']; $message->chef->role = $dbFarmRole->GetSetting(self::ROLE_CHEF_ROLE_NAME); $message->chef->validatorName = $chefServerInfo['v_username']; $message->chef->validatorKey = $chefServerInfo['v_auth_key']; $message->chef->environment = $chefRunListInfo['chef_environment']; break; } return $message; }
public function xCreateBackupAction() { $this->request->defineParams(array('farmId' => array('type' => 'int'), 'farmRoleId' => array('type' => 'int'))); $dbFarm = DBFarm::LoadByID($this->getParam('farmId')); $this->user->getPermissions()->validate($dbFarm); $dbFarmRole = DBFarmRole::LoadByID($this->getParam('farmRoleId')); if ($dbFarmRole->FarmID != $dbFarm->ID) { throw new Exception("Role not found"); } $behavior = Scalr_Role_Behavior::loadByName($dbFarmRole->GetRoleObject()->getDbMsrBehavior()); $behavior->createBackup($dbFarmRole); $this->response->success('Backup successfully initiated'); }
public function handleMessage(Scalr_Messaging_Msg $message, DBServer $dbServer) { parent::handleMessage($message, $dbServer); try { $dbFarmRole = $dbServer->GetFarmRoleObject(); $storageType = $dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_ENGINE); $storageGeneration = $storageType == 'lvm' ? 2 : 1; } catch (Exception $e) { } switch (get_class($message)) { case "Scalr_Messaging_Msg_HostUp": if ($message->dbType && in_array($message->dbType, array(ROLE_BEHAVIORS::REDIS, ROLE_BEHAVIORS::POSTGRESQL, ROLE_BEHAVIORS::MYSQL2, ROLE_BEHAVIORS::PERCONA, ROLE_BEHAVIORS::MARIADB))) { $dbMsrInfo = Scalr_Db_Msr_Info::init($dbFarmRole, $dbServer, $message->dbType); $dbMsrInfo->setMsrSettings($message->{$message->dbType}); if ($message->{$message->dbType}->snapshotConfig) { $dbFarmRole->SetSetting(self::ROLE_NO_DATA_BUNDLE_FOR_SLAVES, 0, DBFarmRole::TYPE_LCL); } if ($message->{$message->dbType}->restore) { $this->db->Execute("INSERT INTO storage_restore_configs SET farm_roleid = ?, dtadded=NOW(), manifest = ?", array($dbFarmRole->ID, $message->{$message->dbType}->restore->cloudfsSource)); $dbFarmRole->SetSetting(self::ROLE_NO_DATA_BUNDLE_FOR_SLAVES, 0, DBFarmRole::TYPE_LCL); $dbFarmRole->SetSetting(Scalr_Db_Msr::DATA_BUNDLE_LAST_TS, time(), DBFarmRole::TYPE_LCL); $dbFarmRole->SetSetting(Scalr_Db_Msr::DATA_BUNDLE_IS_RUNNING, 0, DBFarmRole::TYPE_LCL); } if ($message->{$message->dbType}->masterPassword) { $dbFarmRole->SetSetting(self::ROLE_MASTER_PASSWORD, $message->{$message->dbType}->masterPassword, DBFarmRole::TYPE_LCL); } } break; case "Scalr_Messaging_Msg_DbMsr_PromoteToMasterResult": if ($message->{$message->dbType}->restore) { $this->db->Execute("INSERT INTO storage_restore_configs SET farm_roleid = ?, dtadded=NOW(), manifest = ?", array($dbFarmRole->ID, $message->{$message->dbType}->restore->cloudfsSource)); $dbFarmRole->SetSetting(self::ROLE_NO_DATA_BUNDLE_FOR_SLAVES, 0, DBFarmRole::TYPE_LCL); } if (Scalr_Db_Msr::onPromoteToMasterResult($message, $dbServer)) { if ($message->{$this->behavior}->snapshotConfig) { $dbFarmRole->SetSetting(self::ROLE_NO_DATA_BUNDLE_FOR_SLAVES, 0, DBFarmRole::TYPE_LCL); } Scalr::FireEvent($dbServer->farmId, new NewDbMsrMasterUpEvent($dbServer)); } break; case "Scalr_Messaging_Msg_DbMsr_CreateDataBundleResult": if ($message->status == "ok") { if (isset($message->{$message->dbType}->restore) && isset($message->{$message->dbType}->restore->backupType)) { $t = $message->{$message->dbType}->restore; if ($t->backupType == 'incremental') { $parentManifest = $this->db->GetOne("\n SELECT manifest FROM storage_restore_configs WHERE farm_roleid = ? ORDER BY id DESC LIMIT 1\n ", array($dbFarmRole->ID)); } $this->db->Execute("\n INSERT INTO storage_restore_configs SET farm_roleid = ?, dtadded=NOW(), manifest = ?, type = ?, parent_manifest = ?\n ", array($dbFarmRole->ID, $t->cloudfsSource, $t->backupType, $parentManifest)); unset($t); } $dbFarmRole->SetSetting(self::ROLE_NO_DATA_BUNDLE_FOR_SLAVES, 0, DBFarmRole::TYPE_LCL); Scalr_Db_Msr::onCreateDataBundleResult($message, $dbServer); } else { $dbFarmRole->SetSetting(Scalr_Db_Msr::DATA_BUNDLE_IS_RUNNING, 0, DBFarmRole::TYPE_LCL); // TODO: store last error } $this->updateBackupHistory($dbServer, 'bundle', $message->status, $message->lastError); break; case "Scalr_Messaging_Msg_DbMsr_CreateBackupResult": if ($message->status == "ok") { Scalr_Db_Msr::onCreateBackupResult($message, $dbServer); } else { $dbFarmRole->SetSetting(Scalr_Db_Msr::DATA_BACKUP_IS_RUNNING, 0, DBFarmRole::TYPE_LCL); } $this->updateBackupHistory($dbServer, 'backup', $message->status, $message->lastError); break; } }
private function performDbMsrAction($action, DBFarmRole $dbFarmRole, $tz) { $timeouted = false; if ($dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_ENABLED")) && $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_EVERY")) != 0) { if ($dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_IS_RUNNING")) == 1) { // Wait for timeout time * 2 (Example: NIVs problem with big mysql snapshots) // We must wait for running bundle process. $timeout = $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_EVERY")) * (3600 * 2); $lastTs = $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_RUNNING_TS")); if ($lastTs + $timeout < time()) { $timeouted = true; } if ($timeouted) { $dbFarmRole->SetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_IS_RUNNING"), 0, DBFarmRole::TYPE_LCL); } } else { /* * Check bundle window */ $period = $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_EVERY")); $timeout = $period * 3600; $lastActionTime = $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_LAST_TS")); $performAction = false; if ($period % 24 == 0) { if ($lastActionTime) { $days = $period / 24; $dateTime = new DateTime(null, new DateTimeZone($tz)); $currentDate = (int) $dateTime->format("Ymd"); $dateTime->setTimestamp(strtotime("+{$days} day", $lastActionTime)); $nextDate = (int) $dateTime->format("Ymd"); if ($nextDate > $currentDate) { return; } } $pbwFrom = (int) ($dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_TIMEFRAME_START_HH")) . $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_TIMEFRAME_START_MM"))); $pbwTo = (int) ($dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_TIMEFRAME_END_HH")) . $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_TIMEFRAME_END_MM"))); if ($pbwFrom && $pbwTo) { $dateTime = new DateTime(null, new DateTimeZone($tz)); $currentTime = (int) $dateTime->format("Hi"); //$current_time = (int)date("Hi"); //BUG HERE: 22:00 - 6:00 - doesn't work if ($pbwFrom <= $currentTime && $pbwTo >= $currentTime) { $performAction = true; } } else { $performAction = true; } } else { //Check timeout if ($lastActionTime + $timeout < time()) { $performAction = true; } } if ($performAction) { $behavior = Scalr_Role_Behavior::loadByName($dbFarmRole->GetRoleObject()->getDbMsrBehavior()); if ($action == 'BUNDLE') { $behavior->createDataBundle($dbFarmRole, array('compressor' => $dbFarmRole->GetSetting(Scalr_Role_DbMsrBehavior::ROLE_DATA_BUNDLE_COMPRESSION), 'useSlave' => $dbFarmRole->GetSetting(Scalr_Role_DbMsrBehavior::ROLE_DATA_BUNDLE_USE_SLAVE))); } if ($action == 'BACKUP') { $behavior->createBackup($dbFarmRole); } } } } }
public function OnHostDown(HostDownEvent $event) { if ($event->DBServer->IsRebooting() == 1) { $event->exit = 'reboot'; return; } if (!$this->FarmID) { $event->exit = 'no-farm'; return; } $dbFarm = DBFarm::LoadByID($this->FarmID); $servers = $dbFarm->GetServersByFilter(array('status' => array(SERVER_STATUS::RUNNING))); try { $DBFarmRole = $event->DBServer->GetFarmRoleObject(); $is_synchronize = $DBFarmRole->NewRoleID ? true : false; } catch (Exception $e) { $is_synchronize = false; } try { $DBRole = DBRole::loadById($event->DBServer->roleId); } catch (Exception $e) { } //HUGE BUG HERE! $first_in_role_handled = false; $first_in_role_server = null; $event->msgExpected = count($servers); foreach ($servers as $DBServer) { if (!$DBServer instanceof DBServer) { continue; } $isfirstinrole = '0'; $eventServerIsMaster = $event->DBServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) || $event->DBServer->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER); if ($eventServerIsMaster && !$first_in_role_handled) { if (!$is_synchronize && $DBServer->farmRoleId == $event->DBServer->farmRoleId) { if (DBRole::loadById($DBServer->roleId)->hasBehavior(ROLE_BEHAVIORS::MYSQL) || DBRole::loadById($DBServer->roleId)->getDbMsrBehavior()) { $first_in_role_handled = true; $first_in_role_server = $DBServer; $isfirstinrole = '1'; } } } $msg = new Scalr_Messaging_Msg_HostDown(); //TODO: $msg->behaviour = $DBRole ? $DBRole->getBehaviors() : '*Unknown*'; $msg->roleName = $DBRole ? $DBRole->name : '*Unknown*'; $msg->localIp = $event->DBServer->localIp; $msg->remoteIp = $event->DBServer->remoteIp; $msg->isFirstInRole = $isfirstinrole; $msg->serverIndex = $event->DBServer->index; $msg->farmRoleId = $event->DBServer->farmRoleId; $msg->serverId = $event->DBServer->serverId; $msg->cloudLocation = $event->DBServer->GetCloudLocation(); // If FarmRole was removed from farm, no configuration left if ($DBFarmRole) { $msg = Scalr_Scripting_Manager::extendMessage($msg, $event, $event->DBServer, $DBServer); if ($event->DBServer->farmRoleId != 0) { foreach (Scalr_Role_Behavior::getListForRole(DBRole::loadById($event->DBServer->roleId)) as $behavior) { $msg = $behavior->extendMessage($msg, $event->DBServer); } } } $msg = $DBServer->SendMessage($msg, false, true); if ($msg->dbMessageId) { $event->msgCreated++; } $loopServerIsMaster = $DBServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) || $DBServer->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER); if ($loopServerIsMaster && $DBServer->status == SERVER_STATUS::RUNNING) { $doNotPromoteSlave2Master = true; } } if (!$DBFarmRole) { return; } if ($DBFarmRole->GetRoleObject()->getDbMsrBehavior() && !$doNotPromoteSlave2Master && !$DBFarmRole->GetSetting(Scalr_Db_Msr::SLAVE_TO_MASTER)) { $this->sendPromoteToMasterMessage($event); } //LEGACY MYSQL CODE: if ($DBFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL)) { // If EC2 master down if ($event->DBServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) && $DBFarmRole) { $master = $dbFarm->GetMySQLInstances(true); if ($master[0]) { return; } $msg = new Scalr_Messaging_Msg_Mysql_PromoteToMaster($DBFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_ROOT_PASSWORD), $DBFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_REPL_PASSWORD), $DBFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_STAT_PASSWORD)); if ($event->DBServer->IsSupported("0.7")) { 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($DBFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_SCALR_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()}")); } } } elseif ($event->DBServer->platform == SERVER_PLATFORMS::EC2) { $msg->volumeId = $DBFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_MASTER_EBS_VOLUME_ID); } // 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); } foreach ($servers as $DBServer) { if ($DBServer->serverId == $event->DBServer->serverId) { continue; } if ($platform == SERVER_PLATFORMS::EC2 && $DBServer->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE) == $availZone || $platform != SERVER_PLATFORMS::EC2) { if (DBRole::loadById($DBServer->roleId)->hasBehavior(ROLE_BEHAVIORS::MYSQL)) { $DBFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_SLAVE_TO_MASTER, 1); $DBServer->SetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER, 1); $DBServer->SendMessage($msg, false, true); return; } } } if ($first_in_role_server) { $DBFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_SLAVE_TO_MASTER, 1); $first_in_role_server->SetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER, 1); $first_in_role_server->SendMessage($msg, false, true); } } } }
/** * @param Scalr_Messaging_Msg $message * @param DBServer $dbserver */ private function onHostUp($message, $dbserver, $skipStatusCheck = false) { if ($dbserver->status == SERVER_STATUS::INIT || $skipStatusCheck) { $event = new HostUpEvent($dbserver, ""); $dbFarmRole = $dbserver->GetFarmRoleObject(); foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->handleMessage($message, $dbserver); } //TODO: Move MySQL to MSR /****** MOVE TO MSR ******/ //TODO: Legacy MySQL code if ($dbFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL)) { if (!$message->mysql) { $this->logger->error(sprintf("Strange situation. HostUp message from MySQL behavior doesn't contains `mysql` property. Server %s (%s)", $dbserver->serverId, $dbserver->remoteIp)); return; } $mysqlData = $message->mysql; if ($dbserver->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER)) { if ($mysqlData->rootPassword) { $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_REPL_PASSWORD, $mysqlData->replPassword); $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_ROOT_PASSWORD, $mysqlData->rootPassword); $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_STAT_PASSWORD, $mysqlData->statPassword); } $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_LOG_FILE, $mysqlData->logFile); $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_LOG_POS, $mysqlData->logPos); if ($dbserver->IsSupported("0.7")) { //$dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_SNAPSHOT_ID, $mysqlData->snapshotConfig); //$dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_SNAPSHOT_ID, $mysqlData->volumeConfig); if ($mysqlData->volumeConfig) { try { $storageVolume = Scalr_Storage_Volume::init(); try { $storageVolume->loadById($mysqlData->volumeConfig->id); $storageVolume->setConfig($mysqlData->volumeConfig); $storageVolume->save(); } catch (Exception $e) { if (strpos($e->getMessage(), 'not found')) { $storageVolume->loadBy(array('id' => $mysqlData->volumeConfig->id, 'client_id' => $dbserver->clientId, 'env_id' => $dbserver->envId, 'name' => "MySQL data volume", 'type' => $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_DATA_STORAGE_ENGINE), 'platform' => $dbserver->platform, 'size' => $mysqlData->volumeConfig->size, 'fstype' => $mysqlData->volumeConfig->fstype, 'purpose' => ROLE_BEHAVIORS::MYSQL, 'farm_roleid' => $dbserver->farmRoleId, 'server_index' => $dbserver->index)); $storageVolume->setConfig($mysqlData->volumeConfig); $storageVolume->save(true); } else { throw $e; } } $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_SCALR_VOLUME_ID, $storageVolume->id); } catch (Exception $e) { $this->logger->error(new FarmLogMessage($event->DBServer->farmId, "Cannot save storage volume: {$e->getMessage()}")); } } if ($mysqlData->snapshotConfig) { try { $storageSnapshot = Scalr_Storage_Snapshot::init(); try { $storageSnapshot->loadById($mysqlData->snapshotConfig->id); $storageSnapshot->setConfig($mysqlData->snapshotConfig); $storageSnapshot->save(); } catch (Exception $e) { if (strpos($e->getMessage(), 'not found')) { $storageSnapshot->loadBy(array('id' => $mysqlData->snapshotConfig->id, 'client_id' => $dbserver->clientId, 'farm_id' => $dbserver->farmId, 'farm_roleid' => $dbserver->farmRoleId, 'env_id' => $dbserver->envId, 'name' => sprintf(_("MySQL data bundle #%s"), $mysqlData->snapshotConfig->id), 'type' => $dbFarmRole->GetSetting(DBFarmRole::SETTING_MYSQL_DATA_STORAGE_ENGINE), 'platform' => $dbserver->platform, 'description' => sprintf(_("MySQL data bundle created on Farm '%s' -> Role '%s'"), $dbFarmRole->GetFarmObject()->Name, $dbFarmRole->GetRoleObject()->name), 'ismysql' => true, 'service' => ROLE_BEHAVIORS::MYSQL)); $storageSnapshot->setConfig($mysqlData->snapshotConfig); $storageSnapshot->save(true); } else { throw $e; } } $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_SCALR_SNAPSHOT_ID, $storageSnapshot->id); } catch (Exception $e) { $this->logger->error(new FarmLogMessage($event->DBServer->farmId, "Cannot save storage snapshot: {$e->getMessage()}")); } } } else { /** * @deprecated */ $dbFarmRole->SetSetting(DBFarmRole::SETTING_MYSQL_SNAPSHOT_ID, $mysqlData->snapshotId); } } } return $event; } else { $this->logger->error("Strange situation. Received HostUp message" . " from server '{$dbserver->serverId}' ('{$message->remoteIp})" . " with state {$dbserver->status}!"); } }