/** * Create tags on instance and it's root EBS volume * @param \DBServer $dbServer */ public static function createServerTags(\DBServer $dbServer) { try { $aws = $dbServer->GetEnvironmentObject()->aws($dbServer); if ($dbServer->farmId != 0) { $ind = $aws->ec2->instance->describe($dbServer->GetProperty(\EC2_SERVER_PROPERTIES::INSTANCE_ID))->get(0)->instancesSet->get(0); $metaTagFound = false; foreach ($ind->tagSet as $tag) { /* @var $tag \Scalr\Service\Aws\Ec2\DataType\ResourceTagSetData */ if ($tag->key == \Scalr_Governance::SCALR_META_TAG_NAME) { $metaTagFound = true; break; } } if ($metaTagFound) { return; } $instanceTags = []; $volumeTags = []; foreach ($dbServer->getAwsTags(true) as $k => $v) { $instanceTags[] = ['key' => $k, 'value' => $v]; if ($k != 'Name') { $volumeTags[] = ['key' => $k, 'value' => $v]; } } $res = $ind->createTags($instanceTags); // We also need to tag root device if ($ind->rootDeviceType == 'ebs') { $filter = array(array('name' => VolumeFilterNameType::attachmentInstanceId(), 'value' => $dbServer->GetCloudServerID()), array('name' => VolumeFilterNameType::attachmentDevice(), 'value' => '/dev/sda1')); $ebs = $aws->ec2->volume->describe(null, $filter); foreach ($ebs as $volume) { /* @var $volume \Scalr\Service\Aws\Ec2\DataType\VolumeData */ $volume->createTags($volumeTags); } } } } catch (\Exception $e) { \Logger::getLogger(\LOG_CATEGORY::FARM)->error(new \FarmLogMessage($dbServer->farmId, sprintf(_("Scalr was unable to add tags to the server/volume '{$dbServer->serverId}': %s"), $e->getMessage()), $dbServer->serverId)); } }
/** * Create tags for different EC2 objects (instance, volume, ami) * @param object $object (DBServer and BundleTask) */ public static function createObjectTags($object) { if ($object instanceof \BundleTask) { // Create tags for AMI try { $env = \Scalr_Environment::init()->loadById($object->envId); $aws = $env->aws($object->cloudLocation); if ($object->farmId != 0) { $dbServer = \DBServer::LoadByID($object->serverId); $objectTags = []; foreach ($dbServer->getAwsTags(true) as $k => $v) { if ($k != 'Name') { $objectTags[] = ['key' => $k, 'value' => $v]; } } $aws->ec2->image->describe($object->snapshotId)->get(0)->createTags($objectTags); $object->Log(sprintf("Added %s tags for AMI (%s)", count($objectTags), $object->snapshotId)); } else { return; } } catch (\Exception $e) { $object->Log(sprintf("Scalr was unable to add tags for AMI (%s): %s", $object->snapshotId, $e->getMessage())); } } elseif ($object instanceof \DBServer) { // Create tags for Instance and root-device volume try { $dbServer = $object; $aws = $dbServer->GetEnvironmentObject()->aws($dbServer); if ($dbServer->farmId != 0) { $ind = $aws->ec2->instance->describe($dbServer->GetProperty(\EC2_SERVER_PROPERTIES::INSTANCE_ID))->get(0)->instancesSet->get(0); $metaTagFound = false; foreach ($ind->tagSet as $tag) { /* @var $tag \Scalr\Service\Aws\Ec2\DataType\ResourceTagSetData */ if ($tag->key == \Scalr_Governance::SCALR_META_TAG_NAME) { $metaTagFound = true; break; } } if ($metaTagFound) { return; } $instanceTags = []; $volumeTags = []; foreach ($dbServer->getAwsTags(true) as $k => $v) { $instanceTags[] = ['key' => $k, 'value' => $v]; if ($k != 'Name') { $volumeTags[] = ['key' => $k, 'value' => $v]; } } $res = $ind->createTags($instanceTags); // We also need to tag root device if ($ind->rootDeviceType == 'ebs') { $filter = array(array('name' => VolumeFilterNameType::attachmentInstanceId(), 'value' => $dbServer->GetCloudServerID()), array('name' => VolumeFilterNameType::attachmentDevice(), 'value' => '/dev/sda1')); $ebs = $aws->ec2->volume->describe(null, $filter); foreach ($ebs as $volume) { /* @var $volume \Scalr\Service\Aws\Ec2\DataType\VolumeData */ $volume->createTags($volumeTags); } } } } catch (\Exception $e) { \Scalr::getContainer()->logger(\LOG_CATEGORY::FARM)->error(new \FarmLogMessage($dbServer->farmId, sprintf(_("Scalr was unable to add tags to the server/volume '{$dbServer->serverId}': %s"), $e->getMessage()), $dbServer->serverId)); } } else { return; } }
/** * List volumes * * @param string $cloudLocation The location of a cloud * @param string $volumeId optional Volume ID * @param int $farmId optional Farm ID * @param int $farmRoleId optional Role ID tied to the farm */ public function xListVolumesAction($cloudLocation, $volumeId = null, $farmId = null, $farmRoleId = null) { $filter = []; $filterFields = ["instanceId", "volumeId", "snapshotId", "availZone", "type"]; $env = $this->getEnvironment(); $aws = $env->aws($cloudLocation); if (!empty($volumeId)) { $filter = [["name" => VolumeFilterNameType::volumeId(), "value" => $volumeId]]; } $filteringDecision = $this->request->getCloudResourceFilteringDecision(Acl::RESOURCE_AWS_VOLUMES, SERVER_PLATFORMS::EC2, !empty($farmId) ? $farmId : null); if ($filteringDecision->emptySet) { //This user hasn't any managed Farm. We should return empty result set. $response = $this->buildResponseFromData([], $filterFields); return $this->response->data($response); } elseif (!empty($filteringDecision->filter)) { $filter = array_merge($filter, $filteringDecision->filter); } // Rows $startTime = microtime(true); $volumeList = $aws->ec2->volume->describe(null, empty($filter) ? null : $filter); $describeTime = round(microtime(true) - $startTime) * 1000; $startTime = microtime(true); $vols = []; $needFilter = !empty($farmId) || !empty($farmRoleId); foreach ($volumeList as $pv) { /* @var $pv VolumeData */ /* @var $att AttachmentSetResponseData */ $att = count($pv->attachmentSet) ? $pv->attachmentSet[0] : null; $tags = []; $scalrMetaTag = null; foreach ($pv->tagSet as $tag) { /* @var $tag ResourceTagSetData */ $tg = "{$tag->key}"; if ($tag->value) { $tg .= "={$tag->value}"; } if ($tag->key == Scalr_Governance::SCALR_META_TAG_NAME) { $scalrMetaTag = $tag->value; } $tags[] = $tg; } if (!$filteringDecision->matchScalrMetaTag($scalrMetaTag)) { continue; } $item = ["volumeId" => $pv->volumeId, "size" => (int) $pv->size, "snapshotId" => $pv->snapshotId, "availZone" => $pv->availabilityZone, "type" => $pv->volumeType, "status" => $pv->status, "attachmentStatus" => $att !== null ? $att->status : null, "device" => $att !== null ? $att->device : null, "instanceId" => $att !== null ? $att->instanceId : null, "tags" => implode(",", $tags), "encrypted" => $pv->encrypted, "kmsKeyId" => $pv->kmsKeyId]; if (!empty($item["instanceId"])) { try { if (isset($this->listCache["instances"][$item["instanceId"]])) { $dbServer = $this->listCache["instances"][$item["instanceId"]]; } else { $dbServer = DBServer::LoadByPropertyValue(EC2_SERVER_PROPERTIES::INSTANCE_ID, $item["instanceId"]); $this->listCache["instances"][$item["instanceId"]] = $dbServer; } if ($dbServer) { $item["farmId"] = $dbServer->farmId; $item["farmRoleId"] = $dbServer->farmRoleId; $item["serverIndex"] = $dbServer->index; $item["serverId"] = $dbServer->serverId; $item["mountStatus"] = false; if (isset($this->listCache["farms"][$item["farmId"]])) { $item["farmName"] = $this->listCache["farms"][$item["farmId"]]; } else { $item["farmName"] = $dbServer->GetFarmObject()->Name; $this->listCache["farms"][$item["farmId"]] = $item["farmName"]; } if (isset($this->listCache["farmRoles"][$item["farmRoleId"]])) { $item["roleName"] = $this->listCache["farmRoles"][$item["farmRoleId"]]; } else { $item["roleName"] = $dbServer->GetFarmRoleObject()->GetRoleObject()->name; $this->listCache["farmRoles"][$item["farmRoleId"]] = $item["roleName"]; } /* Waiting for bugfix on scalarizr side if ($dbServer->IsSupported("2.5.4")) { $item["mounts"] = $dbServer->scalarizr->system->mounts(); } */ } } catch (\Exception $e) { } } if ($needFilter === true) { foreach (["farmId", "farmRoleId"] as $var) { if (!empty(${$var}) && (!isset($item[$var]) || $item[$var] != ${$var})) { continue 2; } } } $vols[] = $item; } $volumesTime = round(microtime(true) - $startTime) * 1000; $startTime = microtime(true); $response = $this->buildResponseFromData($vols, $filterFields); foreach ($response["data"] as &$item) { $item["autoSnaps"] = (bool) $this->db->GetOne("SELECT id FROM autosnap_settings WHERE objectid=? AND object_type=? LIMIT 1", [$item["volumeId"], \AUTOSNAPSHOT_TYPE::EBSSnap]); } $responseTime = round(microtime(true) - $startTime) * 1000; $response["performanceMeasurements"] = ["describe" => $describeTime, "volumes" => $volumesTime, "response" => $responseTime]; $this->response->data($response); }
/** * {@inheritdoc} * @see \Scalr\Modules\PlatformModuleInterface::GetServerExtendedInformation() */ public function GetServerExtendedInformation(DBServer $DBServer, $extended = false) { try { $aws = $DBServer->GetEnvironmentObject()->aws($DBServer); $iid = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID); if (!$iid) { return false; } $iinfo = $aws->ec2->instance->describe($iid)->get(0); $blockStorage = null; if (isset($iinfo->instancesSet)) { if ($extended) { $filter = array(array('name' => VolumeFilterNameType::attachmentInstanceId(), 'value' => $iid)); $ebs = $aws->ec2->volume->describe(null, $filter); foreach ($ebs as $volume) { /* @var $volume \Scalr\Service\Aws\Ec2\DataType\VolumeData */ $blockStorage[] = $volume->attachmentSet->get(0)->device . " - {$volume->size} Gb" . " (<a href='#/tools/aws/ec2/ebs/volumes/" . $volume->volumeId . "/view" . "?cloudLocation=" . $DBServer->GetCloudLocation() . "&platform=ec2'>" . $volume->volumeId . "</a>)"; //array('id' => $volume->volumeId, 'size' => $volume->size, 'device' => $volume->attachmentSet->get(0)->device); } } $instanceData = $iinfo->instancesSet->get(0); if (isset($iinfo->groupSet[0]->groupId)) { $infoGroups = $iinfo->groupSet; } elseif (isset($iinfo->instancesSet[0]->groupSet[0]->groupId)) { $infoGroups = $instanceData->groupSet; } else { $infoGroups = array(); } $groups = array(); foreach ($infoGroups as $sg) { /* @var $sg \Scalr\Service\Aws\Ec2\DataType\SecurityGroupData */ $groups[] = $sg->groupName . " (<a href='#/security/groups/" . $sg->groupId . "/edit" . "?cloudLocation=" . $DBServer->GetProperty(EC2_SERVER_PROPERTIES::REGION) . "&platform=ec2'>" . $sg->groupId . "</a>)"; } $tags = array(); if ($instanceData->tagSet->count() > 0) { foreach ($instanceData->tagSet as $tag) { /* @var $tag \Scalr\Service\Aws\Ec2\DataType\ResourceTagSetData */ if ($tag->value) { $tags[] = "{$tag->key}={$tag->value}"; } else { $tags[] = "{$tag->key}"; } } } //monitoring isn't mandatory data set in the InstanceData $monitoring = isset($instanceData->monitoring->state) ? $instanceData->monitoring->state : null; if ($monitoring == 'disabled') { $monitoring = "Disabled"; } else { $monitoring = "Enabled"; } $retval = array('Cloud Server ID' => $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), 'Owner ID' => $iinfo->ownerId, 'Image ID (AMI)' => $instanceData->imageId, 'Public DNS name' => $instanceData->dnsName, 'Private DNS name' => $instanceData->privateDnsName, 'Public IP' => $instanceData->ipAddress, 'Private IP' => $instanceData->privateIpAddress, 'Key name' => $instanceData->keyName, 'Instance type' => $instanceData->instanceType, 'Launch time' => $instanceData->launchTime->format('Y-m-d\\TH:i:s.000\\Z'), 'Architecture' => $instanceData->architecture, 'IAM Role' => $instanceData->iamInstanceProfile->arn, 'Root device type' => $instanceData->rootDeviceType, 'Instance state' => $instanceData->instanceState->name . " ({$instanceData->instanceState->code})", 'Placement' => isset($instanceData->placement) ? $instanceData->placement->availabilityZone : null, 'Tenancy' => isset($instanceData->placement) ? $instanceData->placement->tenancy : null, 'EBS Optimized' => $instanceData->ebsOptimized ? "Yes" : "No", 'Monitoring (CloudWatch)' => $monitoring, 'Security groups' => implode(', ', $groups), 'Tags' => implode(', ', $tags)); if ($extended) { try { $statusInfo = $aws->ec2->instance->describeStatus($DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID))->get(0); } catch (Exception $e) { } if (!empty($statusInfo)) { if ($statusInfo->systemStatus->status == 'ok') { $systemStatus = '<span style="color:green;">OK</span>'; } else { $txtDetails = ""; if (!empty($statusInfo->systemStatus->details)) { foreach ($statusInfo->systemStatus->details as $d) { /* @var $d \Scalr\Service\Aws\Ec2\DataType\InstanceStatusDetailsSetData */ $txtDetails .= " {$d->name} is {$d->status},"; } } $txtDetails = trim($txtDetails, " ,"); $systemStatus = "<span style='color:red;'>" . $statusInfo->systemStatus->status . "</span> ({$txtDetails})"; } if ($statusInfo->instanceStatus->status == 'ok') { $iStatus = '<span style="color:green;">OK</span>'; } else { $txtDetails = ""; foreach ($statusInfo->instanceStatus->details as $d) { $txtDetails .= " {$d->name} is {$d->status},"; } $txtDetails = trim($txtDetails, " ,"); $iStatus = "<span style='color:red;'>" . $statusInfo->instanceStatus->status . "</span> ({$txtDetails})"; } } else { $systemStatus = "Unknown"; $iStatus = "Unknown"; } $retval['AWS System Status'] = $systemStatus; $retval['AWS Instance Status'] = $iStatus; } if ($blockStorage) { $retval['Block storage'] = implode(', ', $blockStorage); } if ($instanceData->subnetId) { $retval['VPC ID'] = $instanceData->vpcId; $retval['Subnet ID'] = $instanceData->subnetId; $retval['SourceDesk Check'] = $instanceData->sourceDestCheck; $ni = $instanceData->networkInterfaceSet->get(0); if ($ni) { $retval['Network Interface'] = $ni->networkInterfaceId; } } if ($instanceData->reason) { $retval['Reason'] = $instanceData->reason; } return $retval; } } catch (Exception $e) { } return false; }
/** * {@inheritdoc} * @see \Scalr\System\Zmq\Cron\TaskInterface::worker() */ public function worker($request) { $serverId = $request->serverId; $logger = Logger::getLogger(__CLASS__); $this->log("INFO", "Processing messages for %s server", $serverId); try { $dbserver = DBServer::LoadByID($serverId); if ($dbserver->farmId) { if ($dbserver->GetFarmObject()->Status == FARM_STATUS::TERMINATED) { throw new ServerNotFoundException("Farm related to this server has been terminated."); } } } catch (ServerNotFoundException $e) { //By some reason server does not exist $this->db->Execute("\n DELETE m FROM messages m\n WHERE m.server_id = ? AND m.`type` = ? AND m.`status` = ?\n ", [$serverId, "in", MESSAGE_STATUS::PENDING]); return false; } //Warming up static DI cache \Scalr::getContainer()->warmup(); // Reconfigure observers \Scalr::ReconfigureObservers(); $rs = $this->db->Execute("\n SELECT m.* FROM messages m\n WHERE m.server_id = ? AND m.type = ? AND m.status = ?\n ORDER BY m.dtadded ASC\n ", [$serverId, "in", MESSAGE_STATUS::PENDING]); while ($row = $rs->FetchRow()) { try { if ($row["message_format"] == 'xml') { $message = $this->serializer->unserialize($row["message"]); } else { $message = $this->jsonSerializer->unserialize($row["message"]); $dbserver->SetProperty(SERVER_PROPERTIES::SZR_MESSAGE_FORMAT, 'json'); } $message->messageIpAddress = $row['ipaddress']; $event = null; $startTime = microtime(true); // Update scalarizr package version if ($message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION]) { $dbserver->setScalarizrVersion($message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION]); } if ($message->meta[Scalr_Messaging_MsgMeta::SZR_UPD_CLIENT_VERSION]) { $dbserver->SetProperty(SERVER_PROPERTIES::SZR_UPD_CLIENT_VERSION, $message->meta[Scalr_Messaging_MsgMeta::SZR_UPD_CLIENT_VERSION]); } if ($dbserver->GetProperty(SERVER_PROPERTIES::SYSTEM_IGNORE_INBOUND_MESSAGES)) { continue; } if ($message instanceof \Scalr_Messaging_Msg) { $this->log('INFO', "Handling '%s' for '%s' server", $message->getName(), $serverId); } try { if ($message instanceof Scalr_Messaging_Msg_OperationResult) { if ($message->status == 'ok' || $message->status == 'completed') { if ($message->name == 'Grow MySQL/Percona data volume' || $message->name == 'mysql.grow-volume') { $volumeConfig = $message->data ? $message->data : $message->result; $oldVolumeId = $dbserver->GetFarmRoleObject()->GetSetting(Scalr_Db_Msr::VOLUME_ID); $engine = $dbserver->GetFarmRoleObject()->GetSetting(Scalr_Db_Msr::DATA_STORAGE_ENGINE); try { $storageVolume = Scalr_Storage_Volume::init(); try { $storageVolume->loadById($volumeConfig->id); $storageVolume->setConfig($volumeConfig); $storageVolume->save(); } catch (Exception $e) { if (strpos($e->getMessage(), 'not found')) { $storageVolume->loadBy(array('id' => $volumeConfig->id, 'client_id' => $dbserver->clientId, 'env_id' => $dbserver->envId, 'name' => "'{$volumeConfig->tags->service}' data volume", 'type' => $engine, 'platform' => $dbserver->platform, 'size' => $volumeConfig->size, 'fstype' => $volumeConfig->fstype, 'purpose' => $volumeConfig->tags->service, 'farm_roleid' => $dbserver->farmRoleId, 'server_index' => $dbserver->index)); $storageVolume->setConfig($volumeConfig); $storageVolume->save(true); } else { throw $e; } } $dbserver->GetFarmRoleObject()->SetSetting(Scalr_Db_Msr::VOLUME_ID, $volumeConfig->id, DBFarmRole::TYPE_LCL); if ($engine == MYSQL_STORAGE_ENGINE::EBS) { $dbserver->GetFarmRoleObject()->SetSetting(Scalr_Db_Msr::DATA_STORAGE_EBS_SIZE, $volumeConfig->size, DBFarmRole::TYPE_CFG); } elseif ($engine == MYSQL_STORAGE_ENGINE::RAID_EBS) { $dbserver->GetFarmRoleObject()->SetSetting(Scalr_Db_Msr::DATA_STORAGE_RAID_DISK_SIZE, $volumeConfig->size, DBFarmRole::TYPE_CFG); } // Remove old $storageVolume->delete($oldVolumeId); } catch (Exception $e) { Logger::getLogger(__CLASS__)->error(new FarmLogMessage($dbserver->farmId, "Cannot save storage volume: {$e->getMessage()}")); } } } elseif ($message->status == 'error' || $message->status == 'failed') { if ($message->name == 'Initialization' || $message->name == 'system.init') { $dbserver->SetProperty(SERVER_PROPERTIES::SZR_IS_INIT_FAILED, 1); if (is_object($message->error)) { $errorText = $message->error->message; } elseif ($message->error) { $errorText = $message->error; } $dbserver->SetProperty(SERVER_PROPERTIES::SZR_IS_INIT_ERROR_MSG, $errorText); $event = new HostInitFailedEvent($dbserver, $errorText); } } } elseif ($message instanceof Scalr_Messaging_Msg_InitFailed) { $errorText = $message->reason; $dbserver->SetProperty(SERVER_PROPERTIES::SZR_IS_INIT_ERROR_MSG, $errorText); $event = new HostInitFailedEvent($dbserver, $errorText); } elseif ($message instanceof \Scalr_Messaging_Msg_RuntimeError) { $logger->fatal(new FarmLogMessage($dbserver->farmId, "Scalarizr failed to launch on server '{$dbserver->getNameByConvention()}' with runtime error: {$message->message}", $dbserver->serverId)); } elseif ($message instanceof Scalr_Messaging_Msg_UpdateControlPorts) { $apiPort = $message->api; $ctrlPort = $message->messaging; $snmpPort = $message->snmp; // Check API port; $currentApiPort = $dbserver->GetProperty(SERVER_PROPERTIES::SZR_API_PORT); if (!$currentApiPort) { $currentApiPort = 8010; } if ($apiPort && $apiPort != $currentApiPort) { $logger->warn(new FarmLogMessage($dbserver->farmId, "Scalarizr API port was changed from {$currentApiPort} to {$apiPort}", $dbserver->serverId)); $dbserver->SetProperty(SERVER_PROPERTIES::SZR_API_PORT, $apiPort); } // Check Control port $currentCtrlPort = $dbserver->GetProperty(SERVER_PROPERTIES::SZR_CTRL_PORT); if (!$currentCtrlPort) { $currentCtrlPort = 8013; } if ($ctrlPort && $ctrlPort != $currentCtrlPort) { $logger->warn(new FarmLogMessage($dbserver->farmId, "Scalarizr Control port was changed from {$currentCtrlPort} to {$ctrlPort}", $dbserver->serverId)); $dbserver->SetProperty(SERVER_PROPERTIES::SZR_CTRL_PORT, $ctrlPort); } //Check SNMP port $currentSnmpPort = $dbserver->GetProperty(SERVER_PROPERTIES::SZR_SNMP_PORT); if (!$currentSnmpPort) { $currentSnmpPort = 8014; } if ($snmpPort && $snmpPort != $currentSnmpPort) { $logger->warn(new FarmLogMessage($dbserver->farmId, "Scalarizr SNMP port was changed from {$currentSnmpPort} to {$snmpPort}", $dbserver->serverId)); $dbserver->SetProperty(SERVER_PROPERTIES::SZR_SNMP_PORT, $snmpPort); } } elseif ($message instanceof Scalr_Messaging_Msg_Win_HostDown) { $status = PlatformFactory::NewPlatform($dbserver->platform)->GetServerRealStatus($dbserver); if ($status->isRunning()) { $event = new RebootBeginEvent($dbserver); } else { if ($dbserver->platform == SERVER_PLATFORMS::EC2) { if (!$status->isTerminated()) { //Stopping $logger->error(new FarmLogMessage($dbserver->farmId, "Server is in '{$status->getName()}' state. Ignoring HostDown event.", $dbserver->serverId)); $isStopping = true; } } if ($isStopping) { $dbserver->SetProperties([SERVER_PROPERTIES::REBOOTING => 0, SERVER_PROPERTIES::RESUMING => 0]); $dbserver->remoteIp = ""; $dbserver->localIp = ""; $dbserver->status = SERVER_STATUS::SUSPENDED; $dbserver->Save(); } $event = new HostDownEvent($dbserver); $event->isSuspended = true; } } elseif ($message instanceof Scalr_Messaging_Msg_Win_PrepareBundleResult) { try { $bundleTask = BundleTask::LoadById($message->bundleTaskId); } catch (Exception $e) { } if ($bundleTask) { if ($bundleTask->status == SERVER_SNAPSHOT_CREATION_STATUS::PREPARING) { if ($message->status == 'ok') { $metaData = array('szr_version' => $message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION], 'os' => $message->os, 'software' => $message->software); $bundleTask->setMetaData($metaData); $bundleTask->Save(); PlatformFactory::NewPlatform($bundleTask->platform)->CreateServerSnapshot($bundleTask); } else { $bundleTask->SnapshotCreationFailed("PrepareBundle procedure failed: {$message->lastError}"); } } } } elseif ($message instanceof Scalr_Messaging_Msg_DeployResult) { try { $deploymentTask = Scalr_Model::init(Scalr_Model::DM_DEPLOYMENT_TASK)->loadById($message->deployTaskId); } catch (Exception $e) { } if ($deploymentTask) { if ($message->status == 'error') { $deploymentTask->status = Scalr_Dm_DeploymentTask::STATUS_FAILED; $deploymentTask->lastError = $message->lastError; } else { $deploymentTask->status = Scalr_Dm_DeploymentTask::STATUS_DEPLOYED; $deploymentTask->dtDeployed = date("Y-m-d H:i:s"); } $deploymentTask->save(); } } elseif ($message instanceof Scalr_Messaging_Msg_Hello) { $event = $this->onHello($message, $dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_FireEvent) { //Validate event $isEventExist = $this->db->GetOne("\n SELECT id FROM event_definitions\n WHERE name = ? AND ((env_id = ? AND account_id = ?) OR (env_id IS NULL AND account_id = ?) OR (env_id IS NULL AND account_id IS NULL))\n LIMIT 1\n ", array($message->eventName, $dbserver->envId, $dbserver->clientId, $dbserver->clientId)); if ($isEventExist) { $event = new CustomEvent($dbserver, $message->eventName, (array) $message->params); } } elseif ($message instanceof Scalr_Messaging_Msg_HostUpdate) { try { $dbFarmRole = $dbserver->GetFarmRoleObject(); } catch (Exception $e) { } if ($dbFarmRole instanceof DBFarmRole) { foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->handleMessage($message, $dbserver); } } } elseif ($message instanceof Scalr_Messaging_Msg_MongoDb) { /********* MONGODB *********/ try { $dbFarmRole = $dbserver->GetFarmRoleObject(); } catch (Exception $e) { } if ($dbFarmRole instanceof DBFarmRole) { foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->handleMessage($message, $dbserver); } } } elseif ($message instanceof Scalr_Messaging_Msg_DbMsr) { /********* DBMSR *********/ try { $dbFarmRole = $dbserver->GetFarmRoleObject(); } catch (Exception $e) { } if ($dbFarmRole instanceof DBFarmRole) { foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->handleMessage($message, $dbserver); } } } elseif ($message instanceof Scalr_Messaging_Msg_HostInit) { $event = $this->onHostInit($message, $dbserver); try { $dbserver->updateTimelog('ts_hi', $message->secondsSinceBoot, $message->secondsSinceStart); } catch (Exception $e) { } if (!$event) { continue; } } elseif ($message instanceof Scalr_Messaging_Msg_HostUp) { $event = $this->onHostUp($message, $dbserver); try { $dbserver->updateTimelog('ts_hu'); } catch (Exception $e) { } } elseif ($message instanceof Scalr_Messaging_Msg_HostDown) { $ignoreHostDown = false; $p = PlatformFactory::NewPlatform($dbserver->platform); $status = $p->GetServerRealStatus($dbserver); if ($dbserver->isOpenstack()) { if (stristr($status->getName(), 'REBOOT') || stristr($status->getName(), 'HARD_REBOOT')) { $logger->error(new FarmLogMessage($dbserver->farmId, "Rackspace server is in " . $status->getName() . " state. Ignoring HostDown message.", $dbserver->serverId)); $isRebooting = true; } } elseif ($dbserver->platform == \SERVER_PLATFORMS::GCE) { if ($status->getName() == 'STOPPING') { // We don't know is this shutdown or stop so let's ignore HostDown // and wait for status change $doNotProcessMessage = true; $ignoreHostDown = true; } elseif ($status->getName() == 'RUNNING') { $isRebooting = true; } elseif ($status->isSuspended() && $dbserver->status != \SERVER_STATUS::PENDING_TERMINATE) { $isStopping = true; } } else { if ($p->getResumeStrategy() == 'init') { //TODO: Check is is stopping or shutting-down procedure. if (!$status->isTerminated()) { $isStopping = true; } } } if ($isStopping) { $dbserver->SetProperties([SERVER_PROPERTIES::REBOOTING => 0, SERVER_PROPERTIES::RESUMING => 0]); $dbserver->remoteIp = ""; $dbserver->localIp = ""; $dbserver->status = SERVER_STATUS::SUSPENDED; $dbserver->Save(); $event = new HostDownEvent($dbserver); $event->isSuspended = true; } elseif ($isRebooting) { $event = new RebootBeginEvent($dbserver); } elseif (!$ignoreHostDown) { if ($dbserver->farmId) { $wasHostDownFired = $this->db->GetOne("SELECT id FROM events WHERE event_server_id = ? AND type = ? AND is_suspend = '0'", array($dbserver->serverId, 'HostDown')); if (!$wasHostDownFired) { $event = new HostDownEvent($dbserver); } } } } elseif ($message instanceof Scalr_Messaging_Msg_RebootStart) { $event = new RebootBeginEvent($dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_RebootFinish) { if (!$dbserver->localIp && $message->localIp) { $dbserver->localIp = $message->localIp; $dbserver->Save(); } $event = new RebootCompleteEvent($dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_BeforeHostUp) { $event = new BeforeHostUpEvent($dbserver); try { $dbserver->updateTimelog('ts_bhu'); } catch (Exception $e) { } } elseif ($message instanceof Scalr_Messaging_Msg_BlockDeviceAttached) { if ($dbserver->platform == SERVER_PLATFORMS::EC2) { $aws = $dbserver->GetEnvironmentObject()->aws($dbserver->GetProperty(EC2_SERVER_PROPERTIES::REGION)); $instanceId = $dbserver->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID); //The main goal of using filters there is to considerably decrease the size of the response. $volumes = $aws->ec2->volume->describe(null, array(array('name' => VolumeFilterNameType::attachmentInstanceId(), 'value' => (string) $instanceId), array('name' => VolumeFilterNameType::attachmentDevice(), 'value' => (string) $message->deviceName), array('name' => VolumeFilterNameType::status(), 'value' => AMAZON_EBS_STATE::IN_USE))); foreach ($volumes as $volume) { /* @var $volume Scalr\Service\Aws\Ec2\DataType\VolumeData */ if ($volume->status == AMAZON_EBS_STATE::IN_USE && count($volume->attachmentSet) && $volume->attachmentSet[0]->instanceId == $instanceId && $volume->attachmentSet[0]->device == $message->deviceName) { $message->volumeId = $volume->volumeId; } } //Releases memory unset($volumes); $dbserver->GetEnvironmentObject()->getContainer()->release('aws'); unset($aws); } $event = new EBSVolumeAttachedEvent($dbserver, $message->deviceName, $message->volumeId); } elseif ($message instanceof Scalr_Messaging_Msg_BlockDeviceMounted) { // Single volume $ebsinfo = $this->db->GetRow("\n SELECT * FROM ec2_ebs WHERE volume_id=? LIMIT 1\n ", array($message->volumeId)); if ($ebsinfo) { $this->db->Execute("\n UPDATE ec2_ebs\n SET mount_status=?, isfsexist='1'\n WHERE id=?\n ", array(EC2_EBS_MOUNT_STATUS::MOUNTED, $ebsinfo['id'])); } $event = new EBSVolumeMountedEvent($dbserver, $message->mountpoint, $message->volumeId, $message->deviceName); } elseif ($message instanceof Scalr_Messaging_Msg_RebundleResult) { if ($message->status == Scalr_Messaging_Msg_RebundleResult::STATUS_OK) { $metaData = array('szr_version' => $message->meta[Scalr_Messaging_MsgMeta::SZR_VERSION], 'dist' => $message->dist, 'os' => $message->os, 'software' => $message->software); if ($dbserver->platform == SERVER_PLATFORMS::EC2) { if ($message->aws) { if ($message->aws->rootDeviceType == 'ebs') { $tags[] = ROLE_TAGS::EC2_EBS; } if ($message->aws->virtualizationType == 'hvm') { $tags[] = ROLE_TAGS::EC2_HVM; } } else { $aws = $dbserver->GetEnvironmentObject()->aws($dbserver); try { $info = $aws->ec2->image->describe($dbserver->GetProperty(EC2_SERVER_PROPERTIES::AMIID))->get(0); if ($info->rootDeviceType == 'ebs') { $tags[] = ROLE_TAGS::EC2_EBS; } else { try { $bundleTask = BundleTask::LoadById($message->bundleTaskId); if ($bundleTask->bundleType == SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS) { $tags[] = ROLE_TAGS::EC2_EBS; } } catch (Exception $e) { } } if ($info->virtualizationType == 'hvm') { $tags[] = ROLE_TAGS::EC2_HVM; } unset($info); } catch (Exception $e) { $metaData['tagsError'] = $e->getMessage(); try { $bundleTask = BundleTask::LoadById($message->bundleTaskId); if ($bundleTask->bundleType == SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS) { $tags[] = ROLE_TAGS::EC2_EBS; } } catch (Exception $e) { } } //Releases memory $dbserver->GetEnvironmentObject()->getContainer()->release('aws'); unset($aws); } } $metaData['tags'] = $tags; $event = new RebundleCompleteEvent($dbserver, $message->snapshotId, $message->bundleTaskId, $metaData); } else { if ($message->status == Scalr_Messaging_Msg_RebundleResult::STATUS_FAILED) { $event = new RebundleFailedEvent($dbserver, $message->bundleTaskId, $message->lastError); } } } elseif ($message instanceof Scalr_Messaging_Msg_Mysql_CreateDataBundleResult) { if ($message->status == "ok") { $event = new MysqlBackupCompleteEvent($dbserver, MYSQL_BACKUP_TYPE::BUNDLE, array('snapshotConfig' => $message->snapshotConfig, 'logFile' => $message->logFile, 'logPos' => $message->logPos, 'dataBundleSize' => $message->dataBundleSize, 'snapshotId' => $message->snapshotId)); } else { $event = new MysqlBackupFailEvent($dbserver, MYSQL_BACKUP_TYPE::BUNDLE); $event->lastError = $message->lastError; } } elseif ($message instanceof Scalr_Messaging_Msg_Mysql_CreateBackupResult) { if ($message->status == "ok") { $event = new MysqlBackupCompleteEvent($dbserver, MYSQL_BACKUP_TYPE::DUMP, array()); $event->backupParts = $message->backupParts; } else { $event = new MysqlBackupFailEvent($dbserver, MYSQL_BACKUP_TYPE::DUMP); $event->lastError = $message->lastError; } } elseif ($message instanceof Scalr_Messaging_Msg_Mysql_PromoteToMasterResult) { $event = $this->onMysql_PromoteToMasterResult($message, $dbserver); } elseif ($message instanceof Scalr_Messaging_Msg_Mysql_CreatePmaUserResult) { $farmRole = DBFarmRole::LoadByID($message->farmRoleId); if ($message->status == "ok") { $farmRole->SetSetting(DBFarmRole::SETTING_MYSQL_PMA_USER, $message->pmaUser, DBFarmRole::TYPE_LCL); $farmRole->SetSetting(DBFarmRole::SETTING_MYSQL_PMA_PASS, $message->pmaPassword, DBFarmRole::TYPE_LCL); } else { $farmRole->SetSetting(DBFarmRole::SETTING_MYSQL_PMA_REQUEST_TIME, "", DBFarmRole::TYPE_LCL); $farmRole->SetSetting(DBFarmRole::SETTING_MYSQL_PMA_REQUEST_ERROR, $message->lastError, DBFarmRole::TYPE_LCL); } } elseif ($message instanceof Scalr_Messaging_Msg_RabbitMq_SetupControlPanelResult) { $farmRole = $dbserver->GetFarmRoleObject(); if ($message->status == "ok") { $mgmtHost = $dbserver->getSzrHost(); if ($message->port) { $mgmtURL = "http://{$mgmtHost}:{$message->port}/mgmt"; } elseif ($message->cpanelUrl) { $info = parse_url($message->cpanelUrl); $mgmtURL = "http://{$mgmtHost}:{$info['port']}/mgmt"; } $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_SERVER_ID, $dbserver->serverId, DBFarmRole::TYPE_LCL); $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_URL, $mgmtURL, DBFarmRole::TYPE_LCL); $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_REQUEST_TIME, "", DBFarmRole::TYPE_LCL); } else { $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_SERVER_ID, "", DBFarmRole::TYPE_LCL); $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_REQUEST_TIME, "", DBFarmRole::TYPE_LCL); $farmRole->SetSetting(Scalr_Role_Behavior_RabbitMQ::ROLE_CP_ERROR_MSG, $message->lastError, DBFarmRole::TYPE_LCL); } } elseif ($message instanceof Scalr_Messaging_Msg_AmiScriptsMigrationResult) { try { //Open security group: if ($dbserver->platform == SERVER_PLATFORMS::EC2) { $info = PlatformFactory::NewPlatform($dbserver->platform)->GetServerExtendedInformation($dbserver); $sg = explode(", ", $info['Security groups']); foreach ($sg as $sgroup) { if ($sgroup != 'default') { // For Scalarizr $group_rules = array(array('rule' => 'tcp:8013:8013:0.0.0.0/0'), array('rule' => 'udp:8014:8014:0.0.0.0/0')); $aws = $dbserver->GetEnvironmentObject()->aws($dbserver); $ipPermissions = new \Scalr\Service\Aws\Ec2\DataType\IpPermissionList(); foreach ($group_rules as $rule) { $group_rule = explode(":", $rule["rule"]); $ipPermissions->append(new \Scalr\Service\Aws\Ec2\DataType\IpPermissionData($group_rule[0], $group_rule[1], $group_rule[2], new \Scalr\Service\Aws\Ec2\DataType\IpRangeData($group_rule[3]))); } $aws->ec2->securityGroup->authorizeIngress($ipPermissions, null, $sgroup); $dbserver->GetEnvironmentObject()->getContainer()->release('aws'); unset($aws); unset($ipPermissions); break; } } } } catch (Exception $e) { $logger->fatal($e->getMessage()); } $dbserver->SetProperty(SERVER_PROPERTIES::SZR_SNMP_PORT, 8014); $dbserver->SetProperty(SERVER_PROPERTIES::SZR_VESION, "0.7.217"); if ($message->mysql) { $event = $this->onHostUp($message, $dbserver, true); } } $handle_status = MESSAGE_STATUS::HANDLED; } catch (Exception $e) { $handle_status = MESSAGE_STATUS::FAILED; $logger->error(sprintf("Cannot handle message '%s' (message_id: %s) " . "from server '%s' (server_id: %s). %s", $message->getName(), $message->messageId, $dbserver->remoteIp ? $dbserver->remoteIp : '*no-ip*', $dbserver->serverId, $e->getMessage() . "({$e->getFile()}:{$e->getLine()})")); } if (!$doNotProcessMessage) { $totalTime = microtime(true) - $startTime; $this->db->Execute("\n UPDATE messages\n SET status = ?, processing_time = ?, dtlasthandleattempt = NOW()\n WHERE messageid = ?\n ", array($handle_status, $totalTime, $message->messageId)); } else { $logger->info(sprintf("Handle message '%s' (message_id: %s) " . "from server '%s' (server_id: %s) is postponed due to status transition", $message->getName(), $message->messageId, $dbserver->remoteIp ? $dbserver->remoteIp : '*no-ip*', $dbserver->serverId)); } if ($event) { \Scalr::FireEvent($dbserver->farmId, $event); } } catch (Exception $e) { $logger->error($e->getMessage()); } } return $request; }
public function xListVolumesAction() { $aws = $this->getEnvironment()->aws($this->getParam('cloudLocation')); $this->request->defineParams(array('sort' => array('type' => 'json', 'default' => array('property' => 'volumeId', 'direction' => 'DESC')), 'volumeId')); if ($this->getParam('volumeId')) { $filter = array(array('name' => VolumeFilterNameType::volumeId(), 'value' => $this->getParam('volumeId'))); } else { $filter = null; } // Rows $volumeList = $aws->ec2->volume->describe(null, $filter); $vols = array(); /* @var $pv VolumeData */ foreach ($volumeList as $pv) { /* @var $att AttachmentSetResponseData */ if (count($pv->attachmentSet)) { $att = $pv->attachmentSet[0]; } else { $att = null; } $item = array('volumeId' => $pv->volumeId, 'size' => (int) $pv->size, 'snapshotId' => $pv->snapshotId, 'availZone' => $pv->availabilityZone, 'type' => $pv->volumeType, 'status' => $pv->status, 'attachmentStatus' => $att !== null ? $att->status : null, 'device' => $att !== null ? $att->device : null, 'instanceId' => $att !== null ? $att->instanceId : null); $item['autoSnaps'] = $this->db->GetOne("SELECT id FROM autosnap_settings WHERE objectid=? AND object_type=? LIMIT 1", array($pv->volumeId, AUTOSNAPSHOT_TYPE::EBSSnap)) ? true : false; $dbEbsVolume = false; try { $dbEbsVolume = DBEBSVolume::loadByVolumeId($pv->volumeId); $item['farmId'] = $dbEbsVolume->farmId; $item['farmRoleId'] = $dbEbsVolume->farmRoleId; $item['serverIndex'] = $dbEbsVolume->serverIndex; $item['serverId'] = $dbEbsVolume->serverId; $item['mountStatus'] = $dbEbsVolume->mountStatus; $item['farmName'] = DBFarm::LoadByID($dbEbsVolume->farmId)->Name; $item['roleName'] = DBFarmRole::LoadByID($dbEbsVolume->farmRoleId)->GetRoleObject()->name; $item['autoAttach'] = true; } catch (\Exception $e) { } if (!$dbEbsVolume && !empty($item['instanceId'])) { try { $dbServer = DBServer::LoadByPropertyValue(EC2_SERVER_PROPERTIES::INSTANCE_ID, $item['instanceId']); $item['farmId'] = $dbServer->farmId; $item['farmRoleId'] = $dbServer->farmRoleId; $item['serverIndex'] = $dbServer->index; $item['serverId'] = $dbServer->serverId; $item['farmName'] = $dbServer->GetFarmObject()->Name; $item['mountStatus'] = false; $item['roleName'] = $dbServer->GetFarmRoleObject()->GetRoleObject()->name; } catch (\Exception $e) { } } $vols[] = $item; } $response = $this->buildResponseFromData($vols, array('instanceId', 'volumeId', 'snapshotId', 'farmId', 'farmRoleId', 'availZone', 'type')); $this->response->data($response); }
public function xListVolumesAction() { $aws = $this->getEnvironment()->aws($this->getParam('cloudLocation')); $this->request->defineParams(array('sort' => array('type' => 'json', 'default' => array('property' => 'volumeId', 'direction' => 'DESC')), 'volumeId')); if ($this->getParam('volumeId')) { $filter = array(array('name' => VolumeFilterNameType::volumeId(), 'value' => $this->getParam('volumeId'))); } else { $filter = null; } // Rows $volumeList = $aws->ec2->volume->describe(null, $filter); $vols = array(); /* @var $pv VolumeData */ foreach ($volumeList as $pv) { /* @var $att AttachmentSetResponseData */ if (count($pv->attachmentSet)) { $att = $pv->attachmentSet[0]; } else { $att = null; } $tags = array(); foreach ($pv->tagSet as $tag) { /* @var $tag ResourceTagSetData */ $tg = "{$tag->key}"; if ($tag->value) { $tg .= "={$tag->value}"; } $tags[] = $tg; } $item = array('volumeId' => $pv->volumeId, 'size' => (int) $pv->size, 'snapshotId' => $pv->snapshotId, 'availZone' => $pv->availabilityZone, 'type' => $pv->volumeType, 'status' => $pv->status, 'attachmentStatus' => $att !== null ? $att->status : null, 'device' => $att !== null ? $att->device : null, 'instanceId' => $att !== null ? $att->instanceId : null, 'tags' => implode(',', $tags)); $item['autoSnaps'] = $this->db->GetOne("SELECT id FROM autosnap_settings WHERE objectid=? AND object_type=? LIMIT 1", array($pv->volumeId, AUTOSNAPSHOT_TYPE::EBSSnap)) ? true : false; if (!empty($item['instanceId'])) { try { $dbServer = DBServer::LoadByPropertyValue(EC2_SERVER_PROPERTIES::INSTANCE_ID, $item['instanceId']); if ($dbServer) { $item['farmId'] = $dbServer->farmId; $item['farmRoleId'] = $dbServer->farmRoleId; $item['serverIndex'] = $dbServer->index; $item['serverId'] = $dbServer->serverId; $item['farmName'] = $dbServer->GetFarmObject()->Name; $item['mountStatus'] = false; $item['roleName'] = $dbServer->GetFarmRoleObject()->GetRoleObject()->name; /* Waiting for bugfix on scalarizr side if ($dbServer->IsSupported('2.5.4')) { $item['mounts'] = $dbServer->scalarizr->system->mounts(); } */ } } catch (\Exception $e) { } } $vols[] = $item; } $response = $this->buildResponseFromData($vols, array('instanceId', 'volumeId', 'snapshotId', 'farmId', 'farmRoleId', 'availZone', 'type')); $this->response->data($response); }