Example #1
0
 /**
  * Gets the User Entity for the current request
  *
  * @return  User|null Returns the User entity for the current Request
  */
 public function getUser()
 {
     if (empty($this->_user) && $this->user->getId()) {
         $this->_user = User::findPk($this->user->getId());
     }
     return $this->_user;
 }
Example #2
0
 public function xRequestResultAction()
 {
     $this->request->defineParams(array('requests' => array('type' => 'json'), 'decision'));
     if (!in_array($this->getParam('decision'), array(FarmLease::STATUS_APPROVE, FarmLease::STATUS_DECLINE))) {
         throw new Scalr_Exception_Core('Wrong status');
     }
     foreach ($this->getParam('requests') as $id) {
         $req = $this->db->GetRow('SELECT * FROM farm_lease_requests WHERE id = ? LIMIT 1', array($id));
         if ($req) {
             $dbFarm = DBFarm::LoadByID($req['farm_id']);
             $this->user->getPermissions()->validate($dbFarm);
             $this->db->Execute('UPDATE farm_lease_requests SET status = ?, answer_comment = ?, answer_user_id = ? WHERE id = ?', array($this->getParam('decision'), $this->getParam('comment'), $this->user->getId(), $id));
             try {
                 $mailer = Scalr::getContainer()->mailer;
                 if ($dbFarm->ownerId) {
                     $user = Entity\Account\User::findPk($dbFarm->ownerId);
                     if (\Scalr::config('scalr.auth_mode') == 'ldap') {
                         $email = $user->getSetting(Entity\Account\User\UserSetting::NAME_LDAP_EMAIL);
                         if (!$email) {
                             $email = $user->email;
                         }
                     } else {
                         $email = $user->email;
                     }
                     $mailer->addTo($email);
                 } else {
                     $mailer = null;
                 }
             } catch (Exception $e) {
                 $mailer = null;
             }
             if ($this->getParam('decision') == FarmLease::STATUS_APPROVE) {
                 if ($req['request_days'] > 0) {
                     $dt = $dbFarm->GetSetting(Entity\FarmSetting::LEASE_TERMINATE_DATE);
                     $dt = new DateTime($dt);
                     $dt->add(new DateInterval('P' . $req['request_days'] . 'D'));
                     $dbFarm->SetSetting(Entity\FarmSetting::LEASE_TERMINATE_DATE, $dt->format('Y-m-d H:i:s'));
                     $dbFarm->SetSetting(Entity\FarmSetting::LEASE_NOTIFICATION_SEND, null);
                     if ($mailer) {
                         $mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/farm_lease_non_standard_approve.eml', array('{{farm_name}}' => $dbFarm->Name, '{{user_name}}' => $this->user->getEmail(), '{{comment}}' => $this->getParam('comment'), '{{date}}' => $dt->format('M j, Y'), '{{envName}}' => $dbFarm->GetEnvironmentObject()->name, '{{envId}}' => $dbFarm->GetEnvironmentObject()->id));
                     }
                 } else {
                     $dbFarm->SetSetting(Entity\FarmSetting::LEASE_STATUS, '');
                     $dbFarm->SetSetting(Entity\FarmSetting::LEASE_TERMINATE_DATE, '');
                     $dbFarm->SetSetting(Entity\FarmSetting::LEASE_NOTIFICATION_SEND, '');
                     if ($mailer) {
                         $mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/farm_lease_non_standard_forever.eml', array('{{farm_name}}' => $dbFarm->Name, '{{user_name}}' => $this->user->getEmail(), '{{comment}}' => $this->getParam('comment'), '{{envName}}' => $dbFarm->GetEnvironmentObject()->name, '{{envId}}' => $dbFarm->GetEnvironmentObject()->id));
                     }
                 }
             } else {
                 $dt = new DateTime($dbFarm->GetSetting(Entity\FarmSetting::LEASE_TERMINATE_DATE));
                 SettingEntity::increase(SettingEntity::LEASE_DECLINED_REQUEST);
                 if ($mailer) {
                     $mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/farm_lease_non_standard_decline.eml', array('{{farm_name}}' => $dbFarm->Name, '{{user_name}}' => $this->user->getEmail(), '{{date}}' => $dt->format('M j, Y'), '{{comment}}' => $this->getParam('comment'), '{{envName}}' => $dbFarm->GetEnvironmentObject()->name, '{{envId}}' => $dbFarm->GetEnvironmentObject()->id));
                 }
             }
         }
     }
     $this->response->success();
 }
Example #3
0
 /**
  * LockedException
  *
  * @param   int       $lockedBy          Id of User that add a lock to the object
  * @param   mixed     $object   optional Locked object
  * @param   string    $comment  optional Lock comment
  * @param   int       $code     optional The Exception code
  * @param   Exception $previous optional The previous exception used for the exception chaining
  */
 public function __construct($lockedBy, $object = null, $comment = '', $code = 0, Exception $previous = null)
 {
     $this->lockedBy = $lockedBy;
     $this->object = $object;
     /* @var  $user User */
     $user = User::findPk($lockedBy);
     $userName = empty($user) ? $lockedBy : $user->email;
     if (!empty($comment)) {
         $comment = " with comment: '{$comment}'";
     }
     if (is_object($object)) {
         $object = array_pop(preg_split('\\', get_class($object)));
     }
     parent::__construct((empty($object) ? "Locked" : "{$object} locked") . " by {$userName}{$comment}", $code, $previous);
 }
Example #4
0
 /**
  * LockedException
  *
  * @param   int       $lockedBy          Id of User that add a lock to the object
  * @param   mixed     $object   optional Locked object
  * @param   string    $comment  optional Lock comment
  * @param   int       $code     optional The Exception code
  * @param   Exception $previous optional The previous exception used for the exception chaining
  */
 public function __construct($lockedBy, $object = null, $comment = '', $code = 0, Exception $previous = null)
 {
     if (is_array($object)) {
         throw new InvalidArgumentException("Second argument can not be an array");
     }
     $this->lockedBy = $lockedBy;
     $this->object = $object;
     /* @var  $user User */
     $user = User::findPk($lockedBy);
     $userName = empty($user) ? $lockedBy : $user->email;
     if (!empty($comment)) {
         $comment = " with comment: '{$comment}'";
     }
     if (is_object($object)) {
         $nameParts = explode('\\', get_class($object));
         $object = array_pop($nameParts);
     }
     parent::__construct((empty($object) ? "Locked" : "{$object} locked") . " by {$userName}{$comment}", $code, $previous);
 }
Example #5
0
 /**
  * Generate data for ApiTestCaseV2
  *
  * @param string $fixtures patch to fixtures directory
  * @return array
  * @throws \Scalr\System\Config\Exception\YamlException
  */
 public static function dataFixtures($fixtures)
 {
     // set config
     static::$testUserId = \Scalr::config('scalr.phpunit.userid');
     static::$user = User::findPk(static::$testUserId);
     static::$testEnvId = \Scalr::config('scalr.phpunit.envid');
     static::$env = Environment::findPk(static::$testEnvId);
     $data = [];
     foreach (new DirectoryIterator($fixtures) as $fileInfo) {
         if ($fileInfo->isFile()) {
             $class = __NAMESPACE__ . '\\' . ucfirst($fileInfo->getBasename('.yaml'));
             if (class_exists($class)) {
                 /* @var $object TestDataFixtures */
                 $object = new $class(Yaml::load($fileInfo->getPathname())->toArray());
                 $object->prepareTestData();
                 $data = array_merge($data, $object->preparePathInfo());
             }
         }
     }
     return $data;
 }
Example #6
0
 /**
  * {@inheritdoc}
  * @see \Scalr\System\Zmq\Cron\TaskInterface::worker()
  */
 public function worker($request)
 {
     //Warming up static DI cache
     \Scalr::getContainer()->warmup();
     // Reconfigure observers
     \Scalr::ReconfigureObservers();
     try {
         $dbFarm = DBFarm::LoadByID($request->farmId);
         $curDate = new DateTime();
         $tdValue = $dbFarm->GetSetting(Entity\FarmSetting::LEASE_TERMINATE_DATE);
         if ($tdValue) {
             $td = new DateTime($tdValue);
             if ($td < $curDate) {
                 //Terminates farm
                 SettingEntity::increase(SettingEntity::LEASE_TERMINATE_FARM);
                 //Ajdusts both account & environment for the audit log
                 \Scalr::getContainer()->auditlogger->setAccountId($dbFarm->ClientID)->setAccountId($dbFarm->EnvID);
                 \Scalr::FireEvent($request->farmId, new FarmTerminatedEvent(0, 1, false, 1, true, null));
                 $this->log('INFO', sprintf('Farm: %s [ID: %d] was terminated by lease manager', $dbFarm->Name, $dbFarm->ID));
             } else {
                 // only inform user
                 $days = $td->diff($curDate)->days;
                 $notifications = json_decode($dbFarm->GetSetting(Entity\FarmSetting::LEASE_NOTIFICATION_SEND), true);
                 $governance = new Scalr_Governance($dbFarm->EnvID);
                 $settings = $governance->getValue(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_LEASE, 'notifications');
                 if (is_array($settings)) {
                     foreach ($settings as $n) {
                         if (!$notifications[$n['key']] && $n['period'] >= $days) {
                             $mailer = \Scalr::getContainer()->mailer;
                             $tdHuman = Scalr_Util_DateTime::convertDateTime($td, $dbFarm->GetSetting(Entity\FarmSetting::TIMEZONE), 'M j, Y');
                             /* @var $user Entity\Account\User */
                             if ($n['to'] == 'owner') {
                                 if ($dbFarm->ownerId) {
                                     $user = Entity\Account\User::findPk($dbFarm->ownerId);
                                 } else {
                                     $user = Entity\Account\User::findOne([['accountId' => $dbFarm->ClientID], ['type' => Entity\Account\User::TYPE_ACCOUNT_OWNER]]);
                                 }
                                 if (\Scalr::config('scalr.auth_mode') == 'ldap') {
                                     $email = $user->getSetting(Entity\Account\User\UserSetting::NAME_LDAP_EMAIL);
                                     if (!$email) {
                                         $email = $user->email;
                                     }
                                 } else {
                                     $email = $user->email;
                                 }
                                 $mailer->addTo($email);
                             } else {
                                 foreach (explode(',', $n['emails']) as $email) {
                                     $mailer->addTo(trim($email));
                                 }
                             }
                             $mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/farm_lease_terminate.eml.php', array('terminateDate' => $tdHuman, 'farm' => $dbFarm->Name, 'envName' => $dbFarm->GetEnvironmentObject()->name, 'envId' => $dbFarm->GetEnvironmentObject()->id, 'showOwnerWarning' => !$dbFarm->ownerId));
                             $notifications[$n['key']] = 1;
                             $dbFarm->SetSetting(Entity\FarmSetting::LEASE_NOTIFICATION_SEND, json_encode($notifications));
                             $this->log('INFO', "Notification was sent by key: %s about farm: %s [ID: %d] by lease manager", $n['key'], $dbFarm->Name, $dbFarm->ID);
                         }
                     }
                 }
             }
         }
     } catch (Exception $e) {
         throw $e;
     }
     return $request;
 }
Example #7
0
 /**
  * Setups test user, environment and API key
  *
  * @beforeClass
  *
  * @throws \Scalr\Exception\ModelException
  */
 public static function setUpBeforeClass()
 {
     static::$testUserId = \Scalr::config('scalr.phpunit.userid');
     static::$user = User::findPk(static::$testUserId);
     static::$testEnvId = \Scalr::config('scalr.phpunit.envid');
     static::$env = Environment::findPk(static::$testEnvId);
     $apiKeyName = static::getTestName();
     $apiKeyEntity = ApiKeyEntity::findOne([['name' => $apiKeyName], ['userId' => static::$testUserId]]);
     if (empty($apiKeyEntity)) {
         $apiKeyEntity = new ApiKeyEntity(static::$testUserId);
         $apiKeyEntity->name = $apiKeyName;
         $apiKeyEntity->save();
     }
     static::$apiKeyEntity = $apiKeyEntity;
 }
Example #8
0
 /**
  * Check whether the user has either READ or WRITE access to the specified object
  *
  *
  * @param     object $object
  *            The object to check
  *
  * @param     Entity\Account\User|int $user
  *            Either the User Entity or its identifier
  *
  * @param     Entity\Account\Environment|int $enviroment optional
  *            Either the Environment Entity or its identifier
  *
  * @param     bool $modify optional
  *            Whether it should check MODIFY permission. By default it checks READ permission.
  *
  * @return    bool Returns TRUE if the user has access to the specified object
  * @throws    \InvalidArgumentException
  * @throws    NotYetImplementedException
  */
 public function hasAccessTo($object, $user, $enviroment = null, $modify = null)
 {
     $modify = $modify ?: false;
     if (is_int($user)) {
         $user = Entity\Account\User::findPk($user);
     }
     if ($enviroment !== null && is_int($enviroment)) {
         $enviroment = Entity\Account\Environment::findPk($enviroment);
         if (!$enviroment) {
             throw new \InvalidArgumentException(sprintf("Could not find the Environment by id: %d", func_get_arg(2)));
         }
     }
     if (!$user instanceof Entity\Account\User) {
         throw new \InvalidArgumentException(sprintf('Second argument should be instance of \\Scalr\\Model\\Entity\\Account\\User class.'));
     }
     if ($enviroment !== null && !$enviroment instanceof Entity\Account\Environment) {
         throw new \InvalidArgumentException(sprintf('Third argument should be instance of \\Scalr\\Model\\Entity\\Account\\Environment class.'));
     }
     if (!is_object($object)) {
         throw new \InvalidArgumentException(sprintf("The first argument must be an object."));
     }
     if ($object instanceof AccessPermissionsInterface) {
         return $object->hasAccessPermissions($user, $enviroment, $modify);
     }
     throw new NotYetImplementedException(sprintf("%s nothing knows about %s class", __METHOD__, get_class($object)));
 }
Example #9
0
 /**
  * Transform entity of type MESSAGE for client-side (view, edit)
  *
  * @param  Announcement $announcement
  * @return array  Contains keys  `id`, `accountId`, `added`, `title`, `msg`, `user`.
  */
 private function prepareDataForList(Announcement $announcement)
 {
     $obj = ['id' => $announcement->id, 'accountId' => $announcement->accountId, 'added' => Scalr_Util_DateTime::convertTz($announcement->added, 'M d, Y G:i'), 'title' => $announcement->title, 'msg' => $announcement->msg];
     /* @var $user Scalr\Model\Entity\Account\User */
     $user = User::findPk($announcement->createdById);
     if ($user) {
         $obj['user'] = ['name' => $user->fullName, 'email' => $user->email];
     } else {
         $obj['user'] = ['name' => '#' . $announcement->createdById, 'email' => $announcement->createdByEmail];
     }
     return $obj;
 }
Example #10
0
 /**
  * Add test environment, test Acl, setups test user, environment and API key
  */
 public static function setUpBeforeClass()
 {
     if (!Scalr::getContainer()->config->defined('scalr.phpunit.apiv2')) {
         static::markTestIncomplete('phpunit apiv2 configurations is invalid');
     }
     if (Scalr::getContainer()->config->defined('scalr.phpunit.apiv2.params.max_results')) {
         static::$maxResults = Scalr::config('scalr.phpunit.apiv2.params.max_results');
     }
     static::$testUserId = Scalr::config('scalr.phpunit.apiv2.userid');
     static::$user = User::findPk(static::$testUserId);
     static::$testUserType = static::$user->type;
     static::$testEnvId = Scalr::config('scalr.phpunit.apiv2.envid');
     static::$env = Environment::findPk(static::$testEnvId);
     if (empty(static::$user) || empty(static::$env)) {
         static::markTestIncomplete('Either test environment or user is invalid.');
     }
     $apiKeyName = static::getTestName();
     $apiKeyEntity = ApiKeyEntity::findOne([['name' => $apiKeyName], ['userId' => static::$testUserId]]);
     if (empty($apiKeyEntity)) {
         $apiKeyEntity = new ApiKeyEntity(static::$testUserId);
         $apiKeyEntity->name = $apiKeyName;
         $apiKeyEntity->save();
     }
     static::$apiKeyEntity = $apiKeyEntity;
     static::$defaultAcl = Scalr::getContainer()->acl;
     static::$data = [static::$testEnvId => []];
     if (empty(static::$fullAccessAcl)) {
         static::$fullAccessAcl = new ApiTestAcl();
         static::$fullAccessAcl->setDb(Scalr::getContainer()->adodb);
         static::$fullAccessAcl->createTestAccountRole(static::$user->getAccountId(), static::getTestName(ApiFixture::ACL_FULL_ACCESS), ApiTestAcl::ROLE_ID_FULL_ACCESS);
         static::$fullAccessAcl->aclType = ApiFixture::ACL_FULL_ACCESS;
     }
     if (empty(static::$readOnlyAccessAcl)) {
         static::$readOnlyAccessAcl = new ApiTestAcl();
         static::$readOnlyAccessAcl->setDb(Scalr::getContainer()->adodb);
         static::$readOnlyAccessAcl->createTestAccountRole(static::$user->getAccountId(), static::getTestName(ApiFixture::ACL_READ_ONLY_ACCESS), ApiTestAcl::ROLE_ID_READ_ONLY_ACCESS);
         static::$readOnlyAccessAcl->aclType = ApiFixture::ACL_READ_ONLY_ACCESS;
     }
 }
Example #11
0
 /**
  * Launches server
  *
  * @param   \ServerCreateInfo       $ServerCreateInfo optional The server create info
  * @param   \DBServer               $DBServer         optional The DBServer object
  * @param   bool                    $delayed          optional
  * @param   integer|array            $reason           optional
  * @param   \Scalr_Account_User|int $user             optional The Scalr_Account_User object or its unique identifier
  * @return  DBServer|null           Returns the DBServer object on cussess or null otherwise
  */
 public static function LaunchServer(ServerCreateInfo $ServerCreateInfo = null, DBServer $DBServer = null, $delayed = false, $reason = 0, $user = null)
 {
     $db = self::getDb();
     $farm = null;
     //Ensures handling identifier of the user instead of the object
     if ($user !== null && !$user instanceof \Scalr_Account_User) {
         try {
             $user = Scalr_Account_User::init()->loadById(intval($user));
         } catch (\Exception $e) {
         }
     }
     if (!$DBServer && $ServerCreateInfo) {
         $ServerCreateInfo->SetProperties(array(SERVER_PROPERTIES::SZR_KEY => self::GenerateRandomKey(40), SERVER_PROPERTIES::SZR_KEY_TYPE => SZR_KEY_TYPE::ONE_TIME));
         $DBServer = DBServer::Create($ServerCreateInfo, false, true);
     } elseif (!$DBServer && !$ServerCreateInfo) {
         // incorrect arguments
         self::getContainer()->logger(LOG_CATEGORY::FARM)->error(sprintf("Cannot create server"));
         return null;
     } else {
         if ($DBServer && empty($DBServer->cloudLocation)) {
             trigger_error('Cloud location is missing in DBServer', E_USER_WARNING);
         }
     }
     $propsToSet = array();
     if ($user instanceof \Scalr_Account_User) {
         $propsToSet[SERVER_PROPERTIES::LAUNCHED_BY_ID] = $user->id;
         $propsToSet[SERVER_PROPERTIES::LAUNCHED_BY_EMAIL] = $user->getEmail();
     }
     //We should keep role_id and farm_role_id in server properties to use in cost analytics
     if (!empty($DBServer->farmRoleId)) {
         $propsToSet[SERVER_PROPERTIES::FARM_ROLE_ID] = $DBServer->farmRoleId;
         $propsToSet[SERVER_PROPERTIES::ROLE_ID] = $DBServer->farmRoleId ? $DBServer->GetFarmRoleObject()->RoleID : 0;
     }
     try {
         // Ensures the farm object will be fetched as correctly as possible
         $farm = $DBServer->farmId ? $DBServer->GetFarmObject() : null;
         $farmRole = $DBServer->farmRoleId ? $DBServer->GetFarmRoleObject() : null;
         if (!$farmRole instanceof DBFarmRole) {
             $farmRole = null;
         } else {
             if (!$farm instanceof DBFarm) {
                 // Gets farm through FarmRole object in this case
                 $farm = $farmRole->GetFarmObject();
             }
         }
         if ($farm instanceof DBFarm) {
             $propsToSet[SERVER_PROPERTIES::FARM_CREATED_BY_ID] = $farm->ownerId ?: $farm->GetSetting(Entity\FarmSetting::CREATED_BY_ID);
             $propsToSet[SERVER_PROPERTIES::FARM_CREATED_BY_EMAIL] = $farm->ownerId ? Entity\Account\User::findPk($farm->ownerId)->email : $farm->GetSetting(Entity\FarmSetting::CREATED_BY_EMAIL);
             $projectId = $farm->GetSetting(Entity\FarmSetting::PROJECT_ID);
             if (!empty($projectId)) {
                 try {
                     $projectEntity = ProjectEntity::findPk($projectId);
                     if ($projectEntity instanceof ProjectEntity) {
                         /* @var $projectEntity ProjectEntity */
                         $ccId = $projectEntity->ccId;
                     } else {
                         $projectId = null;
                     }
                 } catch (Exception $e) {
                     $projectId = null;
                 }
             }
             $propsToSet[SERVER_PROPERTIES::FARM_PROJECT_ID] = $projectId;
         }
         if ($farmRole instanceof DBFarmRole) {
             $role = $farmRole->GetRoleObject();
             $DBServer->isScalarized = $role->isScalarized;
             if (!$DBServer->isScalarized) {
                 $propsToSet[SERVER_PROPERTIES::SZR_VESION] = '';
             }
             $DBServer->Save();
         }
         if (!empty($ccId)) {
             $propsToSet[SERVER_PROPERTIES::ENV_CC_ID] = $ccId;
         } elseif ($DBServer->envId && ($environment = $DBServer->GetEnvironmentObject()) instanceof Scalr_Environment) {
             $propsToSet[SERVER_PROPERTIES::ENV_CC_ID] = $environment->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID);
         }
     } catch (Exception $e) {
         self::getContainer()->logger(LOG_CATEGORY::FARM)->error(sprintf("Could not load related object for recently created server %s. It says: %s", $DBServer->serverId, $e->getMessage()));
     }
     if (!empty($propsToSet)) {
         $DBServer->SetProperties($propsToSet);
     }
     $fnGetReason = function ($reasonId) {
         $args = func_get_args();
         $args[0] = DBServer::getLaunchReason($reasonId);
         return [call_user_func_array('sprintf', $args), $reasonId];
     };
     if ($reason) {
         list($reasonMsg, $reasonId) = is_array($reason) ? call_user_func_array($fnGetReason, $reason) : $fnGetReason($reason);
         $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_REASON => $reasonMsg, SERVER_PROPERTIES::LAUNCH_REASON_ID => $reasonId]);
     } else {
         $reasonMsg = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_REASON);
         $reasonId = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_REASON_ID);
     }
     if ($delayed) {
         $DBServer->updateStatus(SERVER_STATUS::PENDING_LAUNCH);
         return $DBServer;
     }
     if ($ServerCreateInfo && $ServerCreateInfo->roleId) {
         $dbRole = DBRole::loadById($ServerCreateInfo->roleId);
         if ($dbRole->generation == 1) {
             $DBServer->updateStatus(SERVER_STATUS::PENDING_LAUNCH);
             $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ERROR => "ami-scripts servers no longer supported", SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
             return $DBServer;
         }
     }
     // Limit amount of pending servers
     if ($DBServer->isOpenstack()) {
         $config = self::getContainer()->config;
         if ($config->defined("scalr.{$DBServer->platform}.pending_servers_limit")) {
             $pendingServersLimit = $config->get("scalr.{$DBServer->platform}.pending_servers_limit");
             $pendingServers = $db->GetOne("SELECT COUNT(*) FROM servers WHERE platform=? AND status=? AND server_id != ?", array($DBServer->platform, SERVER_STATUS::PENDING, $DBServer->serverId));
             if ($pendingServers >= $pendingServersLimit) {
                 self::getContainer()->logger("SERVER_LAUNCH")->warn("{$pendingServers} servers in PENDING state on {$DBServer->platform}. Limit is: {$pendingServersLimit}. Waiting.");
                 $DBServer->updateStatus(SERVER_STATUS::PENDING_LAUNCH);
                 $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
                 return $DBServer;
             } else {
                 self::getContainer()->logger("SERVER_LAUNCH")->warn("{$pendingServers} servers in PENDING state on {$DBServer->platform}. Limit is: {$pendingServersLimit}. Launching server.");
             }
         }
     }
     try {
         $account = Scalr_Account::init()->loadById($DBServer->clientId);
         $account->validateLimit(Scalr_Limits::ACCOUNT_SERVERS, 1);
         PlatformFactory::NewPlatform($DBServer->platform)->LaunchServer($DBServer);
         $DBServer->status = SERVER_STATUS::PENDING;
         $DBServer->Save();
         try {
             $DBServer->getServerHistory()->markAsLaunched($reasonMsg, $reasonId);
             $DBServer->updateTimelog('ts_launched');
             if ($DBServer->imageId) {
                 //Update Image last used date
                 /* @var $server Entity\Server */
                 $server = Entity\Server::findPk($DBServer->serverId);
                 $image = $server->getImage();
                 if ($image) {
                     $image->update(['dtLastUsed' => new DateTime()]);
                 }
                 if ($server->farmRoleId && empty($server->getFarmRole())) {
                     trigger_error(sprintf("Call to a member function getRole() on null. Server: %s, FarmRole: %d", $server->serverId, $server->farmRoleId), E_USER_WARNING);
                 }
                 if ($server->farmRoleId && !empty($server->getFarmRole()->getRole())) {
                     //Update Role last used date
                     $server->getFarmRole()->getRole()->update(['lastUsed' => new DateTime()]);
                 }
             }
         } catch (Exception $e) {
             self::getContainer()->logger('SERVER_HISTORY')->error(sprintf("Cannot update servers history: {$e->getMessage()}"));
         }
     } catch (Exception $e) {
         self::getContainer()->logger(LOG_CATEGORY::FARM)->error(new FarmLogMessage($DBServer, sprintf("Cannot launch server on '%s' platform: %s", !empty($DBServer->platform) ? $DBServer->platform : null, $e->getMessage())));
         $existingLaunchError = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ERROR);
         $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ERROR => $e->getMessage(), SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
         $DBServer->updateStatus(SERVER_STATUS::PENDING_LAUNCH);
         if ($DBServer->farmId && !$existingLaunchError) {
             self::FireEvent($DBServer->farmId, new InstanceLaunchFailedEvent($DBServer, $e->getMessage()));
         }
     }
     if ($DBServer->status == SERVER_STATUS::PENDING) {
         self::FireEvent($DBServer->farmId, new BeforeInstanceLaunchEvent($DBServer));
         $DBServer->SetProperty(SERVER_PROPERTIES::LAUNCH_ERROR, "");
     }
     return $DBServer;
 }
Example #12
0
 /**
  * Setups test user, environment and API key
  *
  * @throws \Scalr\Exception\ModelException
  */
 public static function setUpBeforeClass()
 {
     static::$testUserId = \Scalr::config('scalr.phpunit.userid');
     static::$user = User::findPk(static::$testUserId);
     static::$testEnvId = \Scalr::config('scalr.phpunit.envid');
     static::$env = Environment::findPk(static::$testEnvId);
     if (empty(static::$user) || empty(static::$env)) {
         static::markTestIncomplete('Either test environment or user is invalid.');
     }
     $apiKeyName = static::getTestName();
     $apiKeyEntity = ApiKeyEntity::findOne([['name' => $apiKeyName], ['userId' => static::$testUserId]]);
     if (empty($apiKeyEntity)) {
         $apiKeyEntity = new ApiKeyEntity(static::$testUserId);
         $apiKeyEntity->name = $apiKeyName;
         $apiKeyEntity->save();
     }
     static::$apiKeyEntity = $apiKeyEntity;
     static::changeLoggerConfiguration();
 }
Example #13
0
 /**
  * @param   JsonData    $ids
  * @param   string      $action
  * @param   int         $ownerId
  */
 public function xGroupActionHandlerAction(JsonData $ids, $action, $ownerId = null)
 {
     $processed = array();
     $errors = array();
     $needUpdateFarmOwner = false;
     $actionMsg = '';
     $ids = (array) $ids;
     if ($ownerId && !User::findOne([['id' => $ownerId], ['accountId' => $this->user->getAccountId()]])) {
         $ownerId = null;
     }
     foreach ($ids as $userId) {
         try {
             $user = Scalr_Account_User::init();
             $user->loadById($userId);
             switch ($action) {
                 case 'delete':
                     $actionMsg = 'removed';
                     if ($this->user->canRemoveUser($user)) {
                         $ownedFarms = Farm::findByOwnerId($user->id);
                         if ($ownedFarms->count() > 0) {
                             if ($ownerId) {
                                 /* @var $newOwner User */
                                 $newOwner = User::findPk($ownerId);
                                 /* @var $u User */
                                 $u = User::findPk($this->user->getId());
                                 foreach ($ownedFarms as $farm) {
                                     /* @var $farm Farm */
                                     FarmSetting::addOwnerHistory($farm, $newOwner, $u);
                                     $farm->ownerId = $ownerId;
                                     $farm->save();
                                 }
                             } else {
                                 $needUpdateFarmOwner = true;
                                 throw new Exception("You can't delete owner of the Farm");
                             }
                         }
                         $user->delete();
                         $processed[] = $user->getId();
                     } else {
                         throw new Exception('Insufficient permissions to remove user');
                     }
                     break;
                 case 'activate':
                     $actionMsg = 'activated';
                     if ($this->user->getId() !== $user->getId() && $this->user->canEditUser($user)) {
                         if ($user->status == Scalr_Account_User::STATUS_ACTIVE) {
                             throw new Scalr_Exception_Core('User(s) has already been activated');
                         }
                         $user->status = Scalr_Account_User::STATUS_ACTIVE;
                         $user->save();
                         $processed[] = $user->getId();
                     } else {
                         throw new Scalr_Exception_Core('Insufficient permissions to activate user');
                     }
                     break;
                 case 'deactivate':
                     $actionMsg = 'deactivated';
                     if ($this->user->getId() !== $user->getId() && $this->user->canEditUser($user)) {
                         if ($user->status == Scalr_Account_User::STATUS_INACTIVE) {
                             throw new Scalr_Exception_Core('User(s) has already been suspended');
                         }
                         $user->status = Scalr_Account_User::STATUS_INACTIVE;
                         $user->save();
                         $processed[] = $user->getId();
                     } else {
                         throw new Scalr_Exception_Core('Insufficient permissions to deactivate user');
                     }
                     break;
             }
         } catch (Exception $e) {
             $errors[] = $e->getMessage();
         }
     }
     $num = count($ids);
     if (count($processed) == $num) {
         $this->response->success("Selected user(s) successfully {$actionMsg}");
     } else {
         array_walk($errors, function (&$item) {
             $item = '- ' . $item;
         });
         $this->response->warning(sprintf("Successfully {$actionMsg} only %d from %d users. \nFollowing errors occurred:\n%s", count($processed), $num, join(array_unique($errors), "\n")));
     }
     $this->response->data(['processed' => $processed]);
     if ($needUpdateFarmOwner) {
         $users = [];
         foreach (User::findByAccountId($this->user->getAccountId()) as $user) {
             /* @var $user User */
             if (in_array($user->id, $ids)) {
                 continue;
             }
             $users[] = ['id' => $user->id, 'email' => $user->email];
         }
         $this->response->data(['needUpdateFarmOwner' => $needUpdateFarmOwner, 'usersList' => $users]);
     }
 }
Example #14
0
 /**
  * {@inheritdoc}
  * @see \Scalr\System\Zmq\Cron\TaskInterface::worker()
  */
 public function worker($request)
 {
     $db = \Scalr::getDb();
     //Warming up static DI cache
     \Scalr::getContainer()->warmup();
     // Reconfigure observers
     \Scalr::ReconfigureObservers();
     $bundleTask = BundleTask::LoadById($request->bundleTaskId);
     if (!$bundleTask instanceof BundleTask) {
         $this->getLogger()->fatal("Could not load bundle task id: %s", $request->bundleTaskId);
         return false;
     } else {
         $this->bundleTask = $bundleTask;
         $this->getLogger()->info("Processing bundle task id: %d status: %s serverid: %s", $bundleTask->id, $bundleTask->status, $bundleTask->serverId);
     }
     try {
         $dbServer = DBServer::LoadByID($bundleTask->serverId);
     } catch (\Scalr\Exception\ServerNotFoundException $e) {
         if (!$bundleTask->snapshotId && $bundleTask->bundleType != \SERVER_SNAPSHOT_CREATION_TYPE::GCE_WINDOWS) {
             $bundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::FAILED;
             $bundleTask->setDate('finished');
             $bundleTask->failureReason = sprintf(_("Server '%s' was terminated during snapshot creation process"), $bundleTask->serverId);
             $bundleTask->Save();
             return;
         }
         $this->getLogger()->warn("Could not load server: %s. %s says: %s", $bundleTask->serverId, get_class($e), $e->getMessage());
     } catch (Exception $e) {
         $this->getLogger()->warn("Could not load server: %s. %s says: %s", $bundleTask->serverId, get_class($e), $e->getMessage());
     }
     switch ($bundleTask->status) {
         case SERVER_SNAPSHOT_CREATION_STATUS::ESTABLISHING_COMMUNICATION:
             $conn = @fsockopen($dbServer->getSzrHost(), $dbServer->getPort(DBServer::PORT_CTRL), $errno, $errstr, 10);
             if ($conn) {
                 $dbServer->SetProperty(SERVER_PROPERTIES::SZR_IMPORTING_OUT_CONNECTION, 1);
                 $this->bundleTaskLog("Outbound connection successfully established. Awaiting user action: prebuild automation selection");
                 $bundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::AWAITING_USER_ACTION;
                 $this->bundleTaskLog(sprintf(_("Bundle task status: %s"), $bundleTask->status));
                 $bundleTask->Save();
             } else {
                 $errstr = sprintf("Unable to establish outbound (Scalr -> Scalarizr) communication (%s:%s): %s.", $dbServer->getSzrHost(), $dbServer->getPort(DBServer::PORT_CTRL), $errstr);
                 $errMsg = $dbServer->GetProperty(SERVER_PROPERTIES::SZR_IMPORTING_OUT_CONNECTION_ERROR);
                 if (!$errMsg || $errstr != $errMsg) {
                     $dbServer->SetProperty(SERVER_PROPERTIES::SZR_IMPORTING_OUT_CONNECTION_ERROR, $errstr);
                     $this->bundleTaskLog("{$errstr} Will try again in a few minutes.");
                 }
             }
             return false;
         case SERVER_SNAPSHOT_CREATION_STATUS::AWAITING_USER_ACTION:
             //nothing to do;
             return false;
         case SERVER_SNAPSHOT_CREATION_STATUS::STARING_SERVER:
             $bundleTask->setDate('started');
         case SERVER_SNAPSHOT_CREATION_STATUS::PREPARING_ENV:
         case SERVER_SNAPSHOT_CREATION_STATUS::INTALLING_SOFTWARE:
             if (!PlatformFactory::NewPlatform($dbServer->platform)->GetServerID($dbServer)) {
                 $this->bundleTaskLog(sprintf(_("Waiting for temporary server")));
                 return false;
             }
             $status = PlatformFactory::NewPlatform($dbServer->platform)->GetServerRealStatus($dbServer);
             if ($status->isPending()) {
                 //Server is in pensing state
                 $this->bundleTaskLog(sprintf(_("Server status: %s"), $status->getName()));
                 $this->bundleTaskLog(sprintf(_("Waiting for running state."), $status->getName()));
                 return false;
             } elseif ($status->isTerminated()) {
                 $this->bundleTaskLog(sprintf(_("Server status: %s"), $status->getName()));
                 $dbServer->status = SERVER_STATUS::TERMINATED;
                 $dbServer->save();
                 $bundleTask->SnapshotCreationFailed("Server was terminated and no longer available in cloud.");
                 return false;
             }
             break;
     }
     $this->getLogger()->info("Continue bundle task id:%d status:%s", $bundleTask->id, $bundleTask->status);
     switch ($bundleTask->status) {
         case SERVER_SNAPSHOT_CREATION_STATUS::STARING_SERVER:
             $ips = PlatformFactory::NewPlatform($dbServer->platform)->GetServerIPAddresses($dbServer);
             $dbServer->remoteIp = $ips['remoteIp'];
             $dbServer->localIp = $ips['localIp'];
             $dbServer->save();
             $bundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::PREPARING_ENV;
             $bundleTask->save();
             $this->bundleTaskLog(sprintf(_("Bundle task status: %s"), $bundleTask->status));
             break;
         case SERVER_SNAPSHOT_CREATION_STATUS::PREPARING_ENV:
             $this->bundleTaskLog(sprintf(_("Initializing SSH2 session to the server")));
             if ($dbServer->platform == SERVER_PLATFORMS::IDCF && !$dbServer->remoteIp) {
                 try {
                     $this->bundleTaskLog("Creating port forwarding rules to be able to connect to the server by SSH");
                     $environment = $dbServer->GetEnvironmentObject();
                     $cloudLocation = $dbServer->GetCloudLocation();
                     $platform = PlatformFactory::NewPlatform($dbServer->platform);
                     $ccProps = $environment->keychain($dbServer->platform)->properties;
                     $sharedIpId = $ccProps[CloudCredentialsProperty::CLOUDSTACK_SHARED_IP_ID . ".{$cloudLocation}"];
                     $sharedIp = $ccProps[CloudCredentialsProperty::CLOUDSTACK_SHARED_IP . ".{$cloudLocation}"];
                     $this->bundleTaskLog("Shared IP: {$sharedIp}");
                     $cs = $environment->cloudstack($dbServer->platform);
                     // Create port forwarding rules for scalarizr
                     $port = $ccProps[CloudCredentialsProperty::CLOUDSTACK_SZR_PORT_COUNTER . ".{$cloudLocation}.{$sharedIpId}"];
                     if (!$port) {
                         $port1 = 30000;
                         $port2 = 30001;
                         $port3 = 30002;
                         $port4 = 30003;
                     } else {
                         $port1 = $port + 1;
                         $port2 = $port1 + 1;
                         $port3 = $port2 + 1;
                         $port4 = $port3 + 1;
                     }
                     $virtualmachineid = $dbServer->GetProperty(CLOUDSTACK_SERVER_PROPERTIES::SERVER_ID);
                     $result2 = $cs->firewall->createPortForwardingRule(array('ipaddressid' => $sharedIpId, 'privateport' => 8014, 'protocol' => "udp", 'publicport' => $port1, 'virtualmachineid' => $virtualmachineid));
                     $result1 = $cs->firewall->createPortForwardingRule(array('ipaddressid' => $sharedIpId, 'privateport' => 8013, 'protocol' => "tcp", 'publicport' => $port1, 'virtualmachineid' => $virtualmachineid));
                     $result3 = $cs->firewall->createPortForwardingRule(array('ipaddressid' => $sharedIpId, 'privateport' => 8010, 'protocol' => "tcp", 'publicport' => $port3, 'virtualmachineid' => $virtualmachineid));
                     $result4 = $cs->firewall->createPortForwardingRule(array('ipaddressid' => $sharedIpId, 'privateport' => 8008, 'protocol' => "tcp", 'publicport' => $port2, 'virtualmachineid' => $virtualmachineid));
                     $result5 = $cs->firewall->createPortForwardingRule(array('ipaddressid' => $sharedIpId, 'privateport' => 22, 'protocol' => "tcp", 'publicport' => $port4, 'virtualmachineid' => $virtualmachineid));
                     $dbServer->SetProperties(array(SERVER_PROPERTIES::SZR_CTRL_PORT => $port1, SERVER_PROPERTIES::SZR_SNMP_PORT => $port1, SERVER_PROPERTIES::SZR_API_PORT => $port3, SERVER_PROPERTIES::SZR_UPDC_PORT => $port2, SERVER_PROPERTIES::CUSTOM_SSH_PORT => $port4));
                     $dbServer->remoteIp = $sharedIp;
                     $dbServer->Save();
                     $ccProps->saveSettings([CloudCredentialsProperty::CLOUDSTACK_SZR_PORT_COUNTER . ".{$cloudLocation}.{$sharedIpId}" => $port4]);
                 } catch (Exception $e) {
                     $this->bundleTaskLog("Unable to create port-forwarding rules: {$e->getMessage()}");
                 }
                 return false;
             }
             try {
                 $ssh2Client = $dbServer->GetSsh2Client();
                 $ssh2Client->connect($dbServer->remoteIp, $dbServer->getPort(DBServer::PORT_SSH));
             } catch (Exception $e) {
                 $this->bundleTaskLog(sprintf(_("Scalr unable to establish SSH connection with server on %:%. Error: %s"), $dbServer->remoteIp, $dbServer->getPort(DBServer::PORT_SSH), $e->getMessage()));
                 //TODO: Set status of bundle log to failed
                 return false;
             }
             $this->bundleTaskLog(sprintf(_("Created SSH session. Username: %s"), $ssh2Client->getLogin()));
             //Prepare script
             $this->bundleTaskLog(sprintf(_("Uploading builder scripts...")));
             $behaviors = $dbServer->GetProperty(SERVER_PROPERTIES::SZR_IMPORTING_BEHAVIOR);
             try {
                 if ($dbServer->isOpenstack()) {
                     $platform = SERVER_PLATFORMS::OPENSTACK;
                 } else {
                     $platform = $dbServer->platform;
                 }
                 $baseUrl = rtrim(\Scalr::config('scalr.endpoint.scheme') . "://" . \Scalr::config('scalr.endpoint.host'), '/');
                 $options = array('server-id' => $dbServer->serverId, 'role-name' => $bundleTask->roleName, 'crypto-key' => $dbServer->GetProperty(SERVER_PROPERTIES::SZR_KEY), 'platform' => $platform, 'queryenv-url' => $baseUrl . "/query-env", 'messaging-p2p.producer-url' => $baseUrl . "/messaging", 'behaviour' => trim(trim(str_replace("base", "", $behaviors), ",")), 'env-id' => $dbServer->envId, 'region' => $dbServer->GetCloudLocation(), 'scalr-id' => SCALR_ID);
                 $command = 'scalarizr --import -y';
                 foreach ($options as $k => $v) {
                     $command .= sprintf(' -o %s=%s', $k, $v);
                 }
                 if ($dbServer->GetProperty(SERVER_PROPERTIES::SZR_IMPORTING_MYSQL_SERVER_TYPE) == 'percona') {
                     $recipes = 'mysql=percona';
                 } else {
                     $recipes = '';
                 }
                 $scalarizrBranch = $dbServer->GetProperty(SERVER_PROPERTIES::SZR_DEV_SCALARIZR_BRANCH);
                 $scriptContents = @file_get_contents(APPPATH . "/templates/services/role_builder/chef_import.tpl");
                 /*
                 %CHEF_SERVER_URL%
                 %CHEF_VALIDATOR_NAME%
                 %CHEF_VALIDATOR_KEY%
                 %CHEF_ENVIRONMENT%
                 %CHEF_ROLE_NAME%
                 */
                 $chefServerId = $dbServer->GetProperty(SERVER_PROPERTIES::SZR_IMPORTING_CHEF_SERVER_ID);
                 if ($chefServerId) {
                     $chefServerInfo = $db->GetRow("SELECT * FROM services_chef_servers WHERE id=?", array($chefServerId));
                     $chefServerInfo['v_auth_key'] = \Scalr::getContainer()->crypto->decrypt($chefServerInfo['v_auth_key']);
                 }
                 $scriptContents = str_replace(array("%PLATFORM%", "%BEHAVIOURS%", "%SZR_IMPORT_STRING%", "%DEV%", "%SCALARIZR_BRANCH%", "%RECIPES%", "%BUILD_ONLY%", "%CHEF_SERVER_URL%", "%CHEF_VALIDATOR_NAME%", "%CHEF_VALIDATOR_KEY%", "%CHEF_ENVIRONMENT%", "%CHEF_ROLE%", "%CHEF_ROLE_NAME%", "%CHEF_NODE_NAME%", "\r\n"), array($platform, trim(str_replace("base", "", str_replace(",", " ", $behaviors))), $command, $scalarizrBranch ? '1' : '0', $scalarizrBranch, $recipes, '0', $chefServerInfo['url'], $chefServerInfo['v_username'], $chefServerInfo['v_auth_key'], $dbServer->GetProperty(SERVER_PROPERTIES::SZR_IMPORTING_CHEF_ENVIRONMENT), $dbServer->GetProperty(SERVER_PROPERTIES::SZR_IMPORTING_CHEF_ROLE_NAME), $dbServer->GetProperty(SERVER_PROPERTIES::SZR_IMPORTING_CHEF_ROLE_NAME), '', "\n"), $scriptContents);
                 if (!$ssh2Client->sendFile('/tmp/scalr-builder.sh', $scriptContents, "w+", false)) {
                     throw new Exception("Cannot upload script");
                 }
                 /*
                 $this->bundleTaskLog(sprintf(_("Uploading chef recipes...")));
                 if (!$ssh2Client->sendFile('/tmp/recipes.tar.gz', APPPATH . '/www/storage/chef/recipes.tar.gz')) {
                     throw new Exception("Cannot upload chef recipes");
                 }
                 */
             } catch (Exception $e) {
                 $this->bundleTaskLog(sprintf(_("Scripts upload failed: %s"), $e->getMessage()));
                 //TODO: Set status of bundle log to failed
                 return false;
             }
             $this->bundleTaskLog("Launching role builder routines on server");
             $ssh2Client->exec("chmod 0777 /tmp/scalr-builder.sh");
             // For CGE we need to use sudo
             if ($bundleTask->platform == SERVER_PLATFORMS::GCE || $bundleTask->osFamily == 'amazon') {
                 $shell = $ssh2Client->getShell();
                 @stream_set_blocking($shell, true);
                 @stream_set_timeout($shell, 5);
                 @fwrite($shell, "sudo touch /var/log/role-builder-output.log 2>&1" . PHP_EOL);
                 $output = @fgets($shell, 4096);
                 $this->bundleTaskLog("Verbose 1: {$output}");
                 @fwrite($shell, "sudo chmod 0666 /var/log/role-builder-output.log 2>&1" . PHP_EOL);
                 $output2 = @fgets($shell, 4096);
                 $this->bundleTaskLog("Verbose 2: {$output2}");
                 @fwrite($shell, "sudo setsid /tmp/scalr-builder.sh > /var/log/role-builder-output.log 2>&1 &" . PHP_EOL);
                 $output3 = @fgets($shell, 4096);
                 $this->bundleTaskLog("Verbose 3: {$output3}");
                 sleep(5);
                 $meta = stream_get_meta_data($shell);
                 $this->bundleTaskLog(sprintf("Verbose (Meta): %s", json_encode($meta)));
                 $i = 4;
                 if ($meta['eof'] == false && $meta['unread_bytes'] != 0) {
                     $output4 = @fread($shell, $meta['unread_bytes']);
                     $this->bundleTaskLog("Verbose {$i}: {$output4}");
                     $meta = stream_get_meta_data($shell);
                     $this->bundleTaskLog(sprintf("Verbose (Meta): %s", json_encode($meta)));
                 }
                 @fclose($shell);
                 /*
                 $r1 = $ssh2Client->exec("sudo touch /var/log/role-builder-output.log");
                 $this->bundleTaskLog("1: {$r1} ({$ssh2Client->stdErr})");
                 $r2 = $ssh2Client->exec("sudo chmod 0666 /var/log/role-builder-output.log");
                 $this->bundleTaskLog("2: {$r2} ({$ssh2Client->stdErr})");
                 $r3 = $ssh2Client->exec("sudo setsid /tmp/scalr-builder.sh > /var/log/role-builder-output.log 2>&1 &");
                 $this->bundleTaskLog("3: {$r3} ({$ssh2Client->stdErr})");
                 */
             } else {
                 $ssh2Client->exec("setsid /tmp/scalr-builder.sh > /var/log/role-builder-output.log 2>&1 &");
             }
             $bundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::INTALLING_SOFTWARE;
             $bundleTask->save();
             break;
         case SERVER_SNAPSHOT_CREATION_STATUS::INTALLING_SOFTWARE:
             try {
                 $ssh2Client = $dbServer->GetSsh2Client();
                 $ssh2Client->connect($dbServer->remoteIp, $dbServer->getPort(DBServer::PORT_SSH));
             } catch (Exception $e) {
                 $this->bundleTaskLog(sprintf(_("Scalr unable to establish SSH connection with server on %:%. Error: %s"), $dbServer->remoteIp, $dbServer->getPort(DBServer::PORT_SSH), $e->getMessage()));
                 //TODO: Set status of bundle log to failed
                 return false;
             }
             $log = $ssh2Client->getFile('/var/log/role-builder-output.log');
             $log_lines = explode("\r\n", $log);
             $last_msg = $dbServer->GetProperty(SERVER_PROPERTIES::SZR_IMPORTING_LAST_LOG_MESSAGE);
             while ($msg = trim(array_shift($log_lines))) {
                 if (substr($msg, -1, 1) != ']') {
                     continue;
                 }
                 if ($last_msg) {
                     if ($msg != $last_msg) {
                         continue;
                     } elseif ($msg == $last_msg) {
                         $last_msg = null;
                         continue;
                     }
                 }
                 if (stristr($msg, '[ Failed ]')) {
                     $stepLog = $ssh2Client->getFile('/var/log/role-builder-step.log');
                     $this->bundleTaskLog(sprintf("role-builder-step.log: %s", $stepLog));
                     $bundleTask->SnapshotCreationFailed($msg);
                 } else {
                     $this->bundleTaskLog($msg);
                     $dbServer->SetProperty(SERVER_PROPERTIES::SZR_IMPORTING_LAST_LOG_MESSAGE, $msg);
                 }
             }
             //Read /var/log/role-builder-output.log
             break;
         case SERVER_SNAPSHOT_CREATION_STATUS::PENDING:
             try {
                 $platformModule = PlatformFactory::NewPlatform($bundleTask->platform);
                 $platformModule->CreateServerSnapshot($bundleTask);
             } catch (Exception $e) {
                 $this->getLogger()->error($e->getMessage());
                 $bundleTask->SnapshotCreationFailed($e->getMessage());
             }
             break;
         case SERVER_SNAPSHOT_CREATION_STATUS::PREPARING:
             $addedTime = strtotime($bundleTask->dateAdded);
             if ($addedTime + 3600 < time()) {
                 $bundleTask->SnapshotCreationFailed("Server didn't send PrepareBundleResult message in time.");
             }
             break;
         case SERVER_SNAPSHOT_CREATION_STATUS::IN_PROGRESS:
             PlatformFactory::NewPlatform($bundleTask->platform)->CheckServerSnapshotStatus($bundleTask);
             break;
         case SERVER_SNAPSHOT_CREATION_STATUS::CREATING_ROLE:
             try {
                 if ($bundleTask->object == BundleTask::BUNDLETASK_OBJECT_IMAGE) {
                     if ($bundleTask->replaceType == SERVER_REPLACEMENT_TYPE::REPLACE_ALL) {
                         $dbRole = $dbServer->GetFarmRoleObject()->GetRoleObject();
                         $dbRole->__getNewRoleObject()->setImage($bundleTask->platform, $bundleTask->cloudLocation, $bundleTask->snapshotId, $bundleTask->createdById, $bundleTask->createdByEmail);
                         $this->bundleTaskLog(sprintf(_("Image replacement completed.")));
                     }
                     $this->bundleTaskLog(sprintf(_("Bundle task completed.")));
                     $bundleTask->setDate('finished');
                     $bundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::SUCCESS;
                     $bundleTask->Save();
                 } elseif ($bundleTask->object == BundleTask::BUNDLETASK_OBJECT_ROLE) {
                     if ($bundleTask->replaceType == SERVER_REPLACEMENT_TYPE::REPLACE_ALL) {
                         $saveOldRole = false;
                         try {
                             $dbRole = $dbServer->GetFarmRoleObject()->GetRoleObject();
                             if ($dbRole->name == $bundleTask->roleName && $dbRole->envId == $bundleTask->envId) {
                                 $saveOldRole = true;
                             }
                         } catch (Exception $e) {
                             //NO OLD ROLE
                         }
                         if ($dbRole && $saveOldRole) {
                             if ($dbServer) {
                                 $new_role_name = BundleTask::GenerateRoleName($dbServer->GetFarmRoleObject(), $dbServer);
                             } else {
                                 $new_role_name = $bundleTask->roleName . "-" . rand(1000, 9999);
                             }
                             $dbRole->name = $new_role_name;
                             $this->bundleTaskLog(sprintf(_("Old role '%s' (ID: %s) renamed to '%s'"), $bundleTask->roleName, $dbRole->id, $new_role_name));
                             $dbRole->save();
                         }
                     }
                     try {
                         $DBRole = DBRole::createFromBundleTask($bundleTask);
                     } catch (Exception $e) {
                         $bundleTask->SnapshotCreationFailed("Role creation failed due to internal error ({$e->getMessage()}). Please try again.");
                         return;
                     }
                     if ($bundleTask->replaceType == SERVER_REPLACEMENT_TYPE::NO_REPLACE) {
                         $bundleTask->setDate('finished');
                         $bundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::SUCCESS;
                         $this->bundleTaskLog(sprintf(_("Replacement type: %s. Bundle task status: %s"), SERVER_REPLACEMENT_TYPE::NO_REPLACE, SERVER_SNAPSHOT_CREATION_STATUS::SUCCESS));
                     } else {
                         try {
                             $this->bundleTaskLog(sprintf(_("Replacement type: %s"), $bundleTask->replaceType));
                             $r_farm_roles = array();
                             try {
                                 $DBFarm = DBFarm::LoadByID($bundleTask->farmId);
                             } catch (Exception $e) {
                                 if (stristr($e->getMessage(), "not found in database")) {
                                     $bundleTask->SnapshotCreationFailed("Farm was removed before task was finished");
                                 }
                                 return;
                             }
                             if ($bundleTask->replaceType == SERVER_REPLACEMENT_TYPE::REPLACE_FARM) {
                                 try {
                                     $r_farm_roles[] = $DBFarm->GetFarmRoleByRoleID($bundleTask->prototypeRoleId);
                                 } catch (Exception $e) {
                                 }
                             } elseif ($bundleTask->replaceType == SERVER_REPLACEMENT_TYPE::REPLACE_ALL) {
                                 /* @var $user Entity\Account\User */
                                 $user = Entity\Account\User::findPk($bundleTask->createdById);
                                 /* @var $env Entity\Account\Environment */
                                 $env = Entity\Account\Environment::findPk($bundleTask->envId);
                                 /* @var $acl Acl */
                                 $acl = Scalr::getContainer()->acl;
                                 $sql = "SELECT fr.id FROM farm_roles fr JOIN farms f ON f.id = fr.farmid WHERE fr.role_id=? AND f.env_id = ?";
                                 $args = [$bundleTask->prototypeRoleId, $bundleTask->envId];
                                 if (!$acl->isUserAllowedByEnvironment($user, $env, Acl::RESOURCE_FARMS, Acl::PERM_FARMS_UPDATE)) {
                                     $q = [];
                                     if ($acl->isUserAllowedByEnvironment($user, $env, Acl::RESOURCE_TEAM_FARMS, Acl::PERM_FARMS_UPDATE)) {
                                         $q[] = Entity\Farm::getUserTeamOwnershipSql($user->id);
                                     }
                                     if ($acl->isUserAllowedByEnvironment($user, $env, Acl::RESOURCE_OWN_FARMS, Acl::PERM_FARMS_UPDATE)) {
                                         $q[] = "f.created_by_id = ?";
                                         $args[] = $user->getId();
                                     }
                                     if (count($q)) {
                                         $sql .= ' AND (' . join(' OR ', $q) . ')';
                                     } else {
                                         $sql .= ' AND 0';
                                         // no permissions
                                     }
                                 }
                                 $farm_roles = $db->GetAll($sql, $args);
                                 foreach ($farm_roles as $farm_role) {
                                     try {
                                         $r_farm_roles[] = DBFarmRole::LoadByID($farm_role['id']);
                                     } catch (Exception $e) {
                                     }
                                 }
                             }
                             foreach ($r_farm_roles as $DBFarmRole) {
                                 if ($DBFarmRole->CloudLocation != $bundleTask->cloudLocation) {
                                     $this->bundleTaskLog(sprintf("Role '%s' (ID: %s), farm '%s' (ID: %s) using the same role " . "but in abother cloud location. Skiping it.", $DBFarmRole->GetRoleObject()->name, $DBFarmRole->ID, $DBFarmRole->GetFarmObject()->Name, $DBFarmRole->FarmID));
                                 } else {
                                     $DBFarmRole->RoleID = $bundleTask->roleId;
                                     $DBFarmRole->Save();
                                 }
                             }
                             $this->bundleTaskLog(sprintf(_("Replacement completed. Bundle task completed.")));
                             try {
                                 if ($dbServer->status == SERVER_STATUS::IMPORTING) {
                                     $dbServer->Remove();
                                 } elseif ($dbServer->status == SERVER_STATUS::TEMPORARY) {
                                     $this->bundleTaskLog("Terminating temporary server");
                                     $dbServer->terminate(DBServer::TERMINATE_REASON_TEMPORARY_SERVER_ROLE_BUILDER);
                                     $this->bundleTaskLog("Termination request has been sent");
                                 }
                             } catch (Exception $e) {
                                 $this->bundleTaskLog("Warning: {$e->getMessage()}");
                             }
                             $bundleTask->setDate('finished');
                             $bundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::SUCCESS;
                             $bundleTask->Save();
                         } catch (Exception $e) {
                             $this->getLogger()->error($e->getMessage());
                             $this->bundleTaskLog(sprintf(_("Server replacement failed: %s"), $e->getMessage()));
                             $bundleTask->setDate('finished');
                             $bundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::SUCCESS;
                         }
                     }
                 }
                 if ($bundleTask->status == SERVER_SNAPSHOT_CREATION_STATUS::SUCCESS) {
                     try {
                         if ($dbServer->status == SERVER_STATUS::IMPORTING) {
                             $dbServer->Remove();
                         } elseif ($dbServer->status == SERVER_STATUS::TEMPORARY) {
                             $this->bundleTaskLog("Terminating temporary server");
                             $dbServer->terminate(DBServer::TERMINATE_REASON_TEMPORARY_SERVER_ROLE_BUILDER);
                             $this->bundleTaskLog("Termination request has been sent");
                         }
                     } catch (Exception $e) {
                         $this->bundleTaskLog("Warning: {$e->getMessage()}");
                     }
                 }
                 $bundleTask->Save();
             } catch (Exception $e) {
                 $this->getLogger()->error($e->getMessage());
             }
             break;
     }
     return $request;
 }
Example #15
0
 /**
  * {@inheritdoc}
  * @see ServerImportInterface::import()
  */
 public function import($instanceId, $tags = [])
 {
     $instances = PlatformFactory::NewPlatform($this->farmRole->platform)->getOrphanedServers($this->farmRole->getFarm()->getEnvironment(), $this->farmRole->cloudLocation, [$instanceId]);
     if (count($instances) != 1) {
         throw new ValidationErrorException("Instance was not found");
     }
     $this->orphaned = $instances[0];
     $this->tags = $tags;
     $this->validate();
     $farm = $this->farmRole->getFarm();
     $server = $this->server = new Entity\Server();
     try {
         $server->serverId = \Scalr::GenerateUID(false);
         // DBServer::Create, startWithLetter
         $server->platform = $this->farmRole->platform;
         $server->cloudLocation = $this->farmRole->cloudLocation;
         $server->accountId = $farm->accountId;
         $server->envId = $farm->envId;
         $server->farmId = $farm->id;
         $server->farmRoleId = $this->farmRole->id;
         $server->imageId = $this->orphaned->imageId;
         $server->status = Entity\Server::STATUS_RUNNING;
         $server->type = $this->orphaned->instanceType;
         $server->remoteIp = $this->orphaned->publicIp;
         $server->localIp = $this->orphaned->privateIp;
         $server->added = new DateTime();
         $server->initialized = new DateTime();
         // initialized is used in billing, so we set current time as start point
         $server->scalarized = 0;
         $server->setFreeFarmIndex();
         $server->setFreeFarmRoleIndex();
         $server->properties[Entity\Server::SZR_KEY] = \Scalr::GenerateRandomKey(40);
         $server->properties[Entity\Server::SZR_KEY_TYPE] = SZR_KEY_TYPE::ONE_TIME;
         $server->properties[Entity\Server::SZR_VESION] = '';
         $server->properties[Entity\Server::LAUNCHED_BY_ID] = $this->user->id;
         $server->properties[Entity\Server::LAUNCHED_BY_EMAIL] = $this->user->email;
         $server->properties[Entity\Server::LAUNCH_REASON_ID] = DBServer::LAUNCH_REASON_IMPORT;
         $server->properties[Entity\Server::LAUNCH_REASON] = DBServer::getLaunchReason(DBServer::LAUNCH_REASON_IMPORT);
         $server->properties[Entity\Server::FARM_ROLE_ID] = $this->farmRole->id;
         $server->properties[Entity\Server::ROLE_ID] = $this->farmRole->roleId;
         $server->properties[Entity\Server::FARM_CREATED_BY_ID] = $farm->ownerId ?: $farm->settings[Entity\FarmSetting::CREATED_BY_ID];
         $server->properties[Entity\Server::FARM_CREATED_BY_EMAIL] = $farm->ownerId ? Entity\Account\User::findPk($farm->ownerId)->email : $farm->settings[Entity\FarmSetting::CREATED_BY_EMAIL];
         // projectId, ccId
         $projectId = $farm->settings[Entity\FarmSetting::PROJECT_ID];
         $ccId = null;
         if (!empty($projectId)) {
             try {
                 $projectEntity = ProjectEntity::findPk($projectId);
                 if ($projectEntity instanceof ProjectEntity) {
                     /* @var $projectEntity ProjectEntity */
                     $ccId = $projectEntity->ccId;
                 } else {
                     $projectId = null;
                 }
             } catch (Exception $e) {
                 $projectId = null;
             }
         }
         $server->properties[Entity\Server::FARM_PROJECT_ID] = $projectId;
         if (empty($ccId)) {
             $ccId = Entity\Account\Environment::findPk($farm->envId)->getProperty(Entity\Account\EnvironmentProperty::SETTING_CC_ID);
         }
         $server->properties[Entity\Server::ENV_CC_ID] = $ccId;
         if (!empty($server->getImage())) {
             $server->getImage()->update(['dtLastUsed' => new DateTime()]);
         }
         if (!empty($this->farmRole->getRole())) {
             $this->farmRole->getRole()->update(['lastUsed' => new DateTime()]);
         }
         $this->importServer();
         $server->save();
         $server->setTimeLog('ts_created');
         $server->setTimeLog('ts_launched', time());
         $history = $server->getHistory();
         $history->markAsLaunched($server->properties[Entity\Server::LAUNCH_REASON], $server->properties[Entity\Server::LAUNCH_REASON_ID]);
         $history->update(['cloudServerId' => $this->orphaned->cloudServerId, 'scuCollecting' => 1]);
         $this->applyTags();
         return $server;
     } catch (Exception $e) {
         if (!empty($server->serverId)) {
             // cleanup
             $server->deleteBy([['serverId' => $server->serverId]]);
             Entity\ServerProperty::deleteBy([['serverId' => $server->serverId]]);
             Entity\Server\History::deletePk($server->serverId);
             $this->db->Execute("DELETE FROM `servers_launch_timelog` WHERE server_id = ?", [$server->serverId]);
         }
         throw new ServerImportException(sprintf("Server create was failed with error: %s", $e->getMessage()), $e->getCode(), $e);
     }
 }
Example #16
0
File: Farm.php Project: scalr/scalr
 /**
  * {@inheritdoc}
  * @see AbstractEntity::save()
  */
 public function save()
 {
     $this->changed = microtime();
     $db = $this->db();
     try {
         $db->BeginTrans();
         if (empty($this->id)) {
             $this->ownerId = $this->changedById;
             $this->settings[FarmSetting::CREATED_BY_ID] = $this->ownerId;
             $this->settings[FarmSetting::CREATED_BY_EMAIL] = User::findPk($this->ownerId)->email;
             $this->added = new DateTime();
             $this->status = FARM_STATUS::TERMINATED;
             if (empty($this->settings[FarmSetting::TIMEZONE])) {
                 $this->settings[FarmSetting::TIMEZONE] = date_default_timezone_get();
             }
             $this->settings[FarmSetting::CRYPTO_KEY] = \Scalr::GenerateRandomKey(40);
             /* @var $governance Governance */
             $governance = Governance::findPk($this->envId, Governance::CATEGORY_GENERAL, Governance::GENERAL_LEASE);
             if (!empty($governance) && $governance->enabled) {
                 $this->settings[FarmSetting::LEASE_STATUS] = 'Active';
             }
             //TODO: unused field
             $this->region = Aws::REGION_US_EAST_1;
         }
         parent::save();
         if (!empty($this->_settings)) {
             $this->_settings->save();
         }
         if (isset($this->_teamsChanged)) {
             $this->saveTeams($this->_teams);
             $this->_teamsChanged = false;
         }
         $db->CommitTrans();
     } catch (Exception $e) {
         $db->RollbackTrans();
         throw $e;
     }
 }
Example #17
0
 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_UPDATE);
     $dbFarm->isLocked(true);
     $governance = new Scalr_Governance($this->Environment->id);
     $dbRole = DBRole::loadById($RoleID);
     if (!$dbRole->__getNewRoleObject()->hasAccessPermissions(User::findPk($this->user->getId()), Environment::findPk($this->Environment->id))) {
         throw new Exception(sprintf("Role #%s not found", $RoleID));
     }
     if (!empty($envs = $dbRole->__getNewRoleObject()->getAllowedEnvironments())) {
         if (!in_array($this->Environment->id, $envs)) {
             throw new Exception(sprintf("Role #%s not found", $RoleID));
         }
     }
     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(Entity\FarmSetting::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(Entity\FarmSetting::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), Entity\FarmRoleSetting::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;
 }
 /**
  * List farm roles and hosts list for each role
  *
  * Allowed args: role=(String Role Name) | behaviour=(app|www|mysql|base|memcached)
  *
  * @return DOMDocument
  */
 protected function ListRoles()
 {
     $ResponseDOMDocument = $this->CreateResponse();
     $RolesDOMNode = $ResponseDOMDocument->createElement('roles');
     $ResponseDOMDocument->documentElement->appendChild($RolesDOMNode);
     $sql_query = "SELECT id FROM farm_roles WHERE farmid=?";
     $sql_query_args = array($this->DBServer->farmId);
     // Filter by behaviour
     if ($this->GetArg("behaviour")) {
         $sql_query .= " AND role_id IN (SELECT role_id FROM role_behaviors WHERE behavior=?)";
         array_push($sql_query_args, $this->GetArg("behaviour"));
     }
     // Filter by role
     if ($this->GetArg("role")) {
         $sql_query .= " AND role_id IN (SELECT id FROM roles WHERE name=?)";
         array_push($sql_query_args, $this->GetArg("role"));
     }
     if ($this->GetArg("role-id")) {
         $sql_query .= " AND role_id = ?";
         array_push($sql_query_args, $this->GetArg("role-id"));
     }
     if ($this->GetArg("farm-role-id")) {
         $sql_query .= " AND id = ?";
         array_push($sql_query_args, $this->GetArg("farm-role-id"));
     }
     $farm_roles = $this->DB->GetAll($sql_query, $sql_query_args);
     foreach ($farm_roles as $farm_role) {
         $DBFarmRole = DBFarmRole::LoadByID($farm_role['id']);
         // Create role node
         $RoleDOMNode = $ResponseDOMDocument->createElement('role');
         $RoleDOMNode->setAttribute('behaviour', implode(",", $DBFarmRole->GetRoleObject()->getBehaviors()));
         $RoleDOMNode->setAttribute('name', DBRole::loadById($DBFarmRole->RoleID)->name);
         $RoleDOMNode->setAttribute('alias', $DBFarmRole->Alias);
         $RoleDOMNode->setAttribute('id', $DBFarmRole->ID);
         $RoleDOMNode->setAttribute('role-id', $DBFarmRole->RoleID);
         $RoleDOMNode->setAttribute('scaling-min-instances', $DBFarmRole->GetSetting(Entity\FarmRoleSetting::SCALING_MIN_INSTANCES));
         $RoleDOMNode->setAttribute('scaling-max-instances', $DBFarmRole->GetSetting(Entity\FarmRoleSetting::SCALING_MAX_INSTANCES));
         $HostsDomNode = $ResponseDOMDocument->createElement('hosts');
         $RoleDOMNode->appendChild($HostsDomNode);
         // List instances (hosts)
         $serversSql = "SELECT server_id FROM servers WHERE farm_roleid=?";
         $serversArgs = array($farm_role['id'], SERVER_STATUS::RUNNING);
         if ($this->GetArg("showInitServers")) {
             $serversSql .= " AND status IN (?,?)";
             $serversArgs[] = SERVER_STATUS::INIT;
         } else {
             $serversSql .= " AND status=?";
         }
         $servers = $this->DB->GetAll($serversSql, $serversArgs);
         // Add hosts to response
         if (count($servers) > 0) {
             foreach ($servers as $server) {
                 $DBServer = DBServer::LoadByID($server['server_id']);
                 $serverProperties = $DBServer->GetAllProperties();
                 $HostDOMNode = $ResponseDOMDocument->createElement("host");
                 $HostDOMNode->setAttribute('scalr-server-id', $DBServer->serverId);
                 $HostDOMNode->setAttribute('cloud-server-id', $DBServer->GetCloudServerID());
                 $HostDOMNode->setAttribute('internal-ip', $DBServer->localIp);
                 $HostDOMNode->setAttribute('external-ip', $DBServer->remoteIp);
                 $HostDOMNode->setAttribute('index', $DBServer->index);
                 $HostDOMNode->setAttribute('status', $DBServer->status);
                 $HostDOMNode->setAttribute('cloud-location', $DBServer->GetCloudLocation());
                 $HostDOMNode->setAttribute('cloud-location-zone', $DBServer->cloudLocationZone);
                 $HostDOMNode->setAttribute('hostname', $serverProperties[Scalr_Role_Behavior::SERVER_BASE_HOSTNAME]);
                 if (array_key_exists(SERVER_PROPERTIES::LAUNCHED_BY_EMAIL, $serverProperties)) {
                     $launchedByEmail = $serverProperties[SERVER_PROPERTIES::LAUNCHED_BY_EMAIL];
                 } else {
                     $launchedByEmail = Entity\Account\User::findPk($DBServer->GetFarmObject()->ownerId)->email;
                 }
                 $HostDOMNode->setAttribute('launched-by', $launchedByEmail);
                 if (array_key_exists(SERVER_PROPERTIES::LAUNCH_REASON_ID, $serverProperties)) {
                     $HostDOMNode->setAttribute('launch-reason-id', $serverProperties[SERVER_PROPERTIES::LAUNCH_REASON_ID]);
                 }
                 if ($DBFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MONGODB)) {
                     $HostDOMNode->setAttribute('replica-set-index', (int) $serverProperties[Scalr_Role_Behavior_MongoDB::SERVER_REPLICA_SET_INDEX]);
                     $HostDOMNode->setAttribute('shard-index', (int) $serverProperties[Scalr_Role_Behavior_MongoDB::SERVER_SHARD_INDEX]);
                 }
                 if ($DBFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL)) {
                     if (array_key_exists(SERVER_PROPERTIES::DB_MYSQL_MASTER, $serverProperties)) {
                         $isMySqlMaster = (int) $serverProperties[SERVER_PROPERTIES::DB_MYSQL_MASTER];
                     } else {
                         $isMySqlMaster = 0;
                     }
                     $HostDOMNode->setAttribute('replication-master', $isMySqlMaster);
                 }
                 if ($DBFarmRole->GetRoleObject()->getDbMsrBehavior()) {
                     if (array_key_exists(Scalr_Db_Msr::REPLICATION_MASTER, $serverProperties)) {
                         $isMaster = (int) $serverProperties[Scalr_Db_Msr::REPLICATION_MASTER];
                     } else {
                         $isMaster = 0;
                     }
                     $HostDOMNode->setAttribute('replication-master', $isMaster);
                 }
                 $HostsDomNode->appendChild($HostDOMNode);
             }
         }
         // Add role node to roles node
         $RolesDOMNode->appendChild($RoleDOMNode);
     }
     return $ResponseDOMDocument;
 }
Example #19
0
 /**
  * Generate data for ApiTest
  *
  * @param string $fixtures patch to fixtures directory
  * @param string $type api specifications type
  * @return array
  * @throws \Scalr\System\Config\Exception\YamlException
  */
 public static function loadData($fixtures, $type)
 {
     // set config
     static::$testUserId = \Scalr::config('scalr.phpunit.apiv2.userid');
     static::$user = User::findPk(static::$testUserId);
     static::$testEnvId = \Scalr::config('scalr.phpunit.apiv2.envid');
     static::$env = Environment::findPk(static::$testEnvId);
     $data = [];
     foreach (new ApiFixtureIterator(new DirectoryIterator($fixtures), $type) as $fileInfo) {
         $class = __NAMESPACE__ . '\\' . ucfirst($fileInfo->getBasename('.yaml'));
         try {
             /* @var $object ApiFixture */
             $object = new $class(Yaml::load($fileInfo->getPathname())->toArray(), $type);
             $object->prepareTestData();
             $pathInfo = $object->preparePathInfo();
         } catch (Exception $e) {
             $pathInfo = [array_merge([$class, $e, null, null, null], static::$defaultOperation)];
         }
         $data = array_merge($data, $pathInfo);
     }
     return $data;
 }
Example #20
0
 /**
  * Authentication middleware
  */
 public function authenticationMiddleware()
 {
     $bDebug = $this->request->headers('x-scalr-debug', 0) == 1;
     //If API is not enabled
     if (!$this->getContainer()->config('scalr.system.api.enabled')) {
         $this->halt(403, 'API is not enabled. See scalr.system.api.enabled');
     }
     //Authentication
     $keyId = $this->request->headers('x-scalr-key-id');
     $signature = $this->request->headers('x-scalr-signature');
     //ISO-8601 formatted date
     $date = trim(preg_replace('/\\s+/', '', $this->request->headers('x-scalr-date')));
     if (empty($keyId) || empty($signature)) {
         throw new ApiErrorException(401, ErrorMessage::ERR_BAD_AUTHENTICATION, 'Unsigned request');
     } elseif (empty($date) || ($time = strtotime($date)) === false) {
         throw new ApiErrorException(400, ErrorMessage::ERR_BAD_REQUEST, 'Missing or invalid X-Scalr-Date header');
     }
     $sigparts = explode(' ', $signature, 2);
     if (empty($sigparts) || !in_array($sigparts[0], ['V1-HMAC-SHA256'])) {
         throw new ApiErrorException(401, ErrorMessage::ERR_BAD_AUTHENTICATION, 'Invalid signature');
     }
     $this->apiKey = ApiKeyEntity::findPk($keyId);
     if (!$this->apiKey instanceof ApiKeyEntity || !$this->apiKey->active) {
         throw new ApiErrorException(401, ErrorMessage::ERR_BAD_AUTHENTICATION, 'Invalid API Key');
     }
     if (abs(time() - $time) > 300) {
         throw new ApiErrorException(401, ErrorMessage::ERR_BAD_AUTHENTICATION, 'Request is expired.' . ($bDebug ? ' Now is ' . gmdate('Y-m-d\\TH:i:s\\Z') : ''));
     }
     $now = new \DateTime('now');
     if (empty($this->apiKey->lastUsed) || $now->getTimestamp() - $this->apiKey->lastUsed->getTimestamp() > 10) {
         $this->apiKey->lastUsed = $now;
         $this->apiKey->save();
     }
     $qstr = $this->request->get();
     $canonicalStr = '';
     if (!empty($qstr)) {
         ksort($qstr);
         $canonicalStr = http_build_query($qstr, null, '&', PHP_QUERY_RFC3986);
     }
     $reqBody = $this->request->getBody();
     $stringToSign = $this->request->getMethod() . "\n" . $date . "\n" . $this->request->getPath() . "\n" . $canonicalStr . "\n" . (empty($reqBody) ? '' : $reqBody);
     if ($bDebug) {
         $this->meta->stringToSign = $stringToSign;
     }
     switch ($sigparts[0]) {
         default:
             throw new ApiErrorException(401, ErrorMessage::ERR_BAD_AUTHENTICATION, 'Invalid signature method. Please use "V1-HMAC-SHA256 [SIGNATURE]"');
             break;
         case 'V1-HMAC-SHA256':
             $algo = strtolower(substr($sigparts[0], 8));
     }
     $sig = base64_encode(hash_hmac($algo, $stringToSign, $this->apiKey->secretKey, 1));
     if ($sig !== $sigparts[1]) {
         throw new ApiErrorException(401, ErrorMessage::ERR_BAD_AUTHENTICATION, 'Signature does not match');
     }
     $user = Entity\Account\User::findPk($this->apiKey->userId);
     /* @var $user Entity\Account\User */
     if (!$user instanceof Entity\Account\User) {
         throw new ApiErrorException(401, ErrorMessage::ERR_BAD_AUTHENTICATION, 'User does not exist');
     }
     if ($user->status != Entity\Account\User::STATUS_ACTIVE) {
         throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, 'Inactive user status');
     }
     if (\Scalr::config('scalr.auth_mode') == 'ldap') {
         try {
             $ldap = \Scalr::getContainer()->ldap($user->getLdapUsername(), null);
             if (!$ldap->isValidUsername()) {
                 if ($bDebug && $ldap->getConfig()->debug) {
                     $this->meta->ldapDebug = $ldap->getLog();
                 }
                 throw new ApiErrorException(401, ErrorMessage::ERR_BAD_AUTHENTICATION, 'User does not exist');
             }
             $user->applyLdapGroups($ldap->getUserGroups());
         } catch (LdapException $e) {
             if ($bDebug && $ldap instanceof LdapClient && $ldap->getConfig()->debug) {
                 $this->meta->ldapDebug = $ldap->getLog();
             }
             throw new \RuntimeException($e->getMessage());
         }
     }
     $this->limiter->checkAccountRateLimit($this->apiKey->keyId);
     //Validates API version
     if ($this->settings[ApiApplication::SETTING_API_VERSION] != 1) {
         throw new ApiErrorException(400, ErrorMessage::ERR_BAD_REQUEST, 'Invalid API version');
     }
     if ($this->request->getBody() !== '' && strtolower($this->request->getMediaType()) !== 'application/json') {
         throw new ApiErrorException(400, ErrorMessage::ERR_BAD_REQUEST, 'Invalid Content-Type');
     }
     $this->setUser($user);
     $container = $this->getContainer();
     //Releases auditloger to ensure it will be updated
     $container->release('auditlogger');
     //Adjusts metadata to invoke audit loger
     $container->setShared('auditlogger.metadata', function ($cont) use($user) {
         return (object) ['user' => $user, 'envId' => null, 'remoteAddr' => $this->request->getIp(), 'ruid' => null, 'requestType' => AuditLogger::REQUEST_TYPE_API, 'systemTask' => null];
     });
 }
Example #21
0
 public function getFarm2($farmId)
 {
     $dbFarm = DBFarm::LoadByID($farmId);
     $this->user->getPermissions()->validate($dbFarm);
     $farmRoles = array();
     $variables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), ScopeInterface::SCOPE_FARM);
     $farmRoleVariables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), ScopeInterface::SCOPE_FARMROLE);
     foreach ($dbFarm->GetFarmRoles() as $dbFarmRole) {
         $scripts = $this->db->GetAll("\n                SELECT farm_role_scripts.*, scripts.name, scripts.os\n                FROM farm_role_scripts\n                LEFT JOIN scripts ON scripts.id = farm_role_scripts.scriptid\n                WHERE farm_roleid=? AND issystem='1'\n            ", array($dbFarmRole->ID));
         $scriptsObject = array();
         foreach ($scripts as $script) {
             if (!empty($script['scriptid']) && $script['script_type'] == Scalr_Scripting_Manager::ORCHESTRATION_SCRIPT_TYPE_SCALR || !empty($script['script_path']) && $script['script_type'] == Scalr_Scripting_Manager::ORCHESTRATION_SCRIPT_TYPE_LOCAL || !empty($script['params']) && $script['script_type'] == Scalr_Scripting_Manager::ORCHESTRATION_SCRIPT_TYPE_CHEF) {
                 $s = array('script_type' => $script['script_type'], 'script_id' => (int) $script['scriptid'], 'script' => $script['name'], 'os' => $script['os'], 'params' => unserialize($script['params']), 'target' => $script['target'], 'version' => (int) $script['version'], 'timeout' => $script['timeout'], 'isSync' => (int) $script['issync'], 'order_index' => $script['order_index'], 'event' => $script['event_name'], 'script_path' => $script['script_path'], 'run_as' => $script['run_as']);
                 if ($script['target'] == Script::TARGET_BEHAVIORS || $script['target'] == Script::TARGET_ROLES || $script['target'] == Script::TARGET_FARMROLES) {
                     switch ($script['target']) {
                         case $script['target'] == Script::TARGET_ROLES:
                             $varName = 'target_roles';
                             break;
                         case $script['target'] == Script::TARGET_FARMROLES:
                             $varName = 'target_farmroles';
                             break;
                         case $script['target'] == Script::TARGET_BEHAVIORS:
                             $varName = 'target_behaviors';
                             break;
                     }
                     $s[$varName] = array();
                     $r = $this->db->GetAll("SELECT `target` FROM farm_role_scripting_targets WHERE farm_role_script_id = ?", array($script['id']));
                     foreach ($r as $v) {
                         array_push($s[$varName], $v['target']);
                     }
                 }
                 $scriptsObject[] = $s;
             }
         }
         //Scripting params
         $scriptingParams = $this->db->Execute("\n                SELECT * FROM farm_role_scripting_params\n                WHERE farm_role_id = ? AND farm_role_script_id = '0'\n            ", array($dbFarmRole->ID));
         $sParams = array();
         while ($p = $scriptingParams->FetchRow()) {
             $sParams[] = array('hash' => $p['hash'], 'role_script_id' => $p['role_script_id'], 'params' => unserialize($p['params']));
         }
         $scalingManager = new Scalr_Scaling_Manager($dbFarmRole);
         $scaling = array();
         foreach ($scalingManager->getFarmRoleMetrics() as $farmRoleMetric) {
             $scaling[$farmRoleMetric->metricId] = $farmRoleMetric->getSettings();
         }
         $roleName = $dbFarmRole->GetRoleObject()->name;
         $storages = array('configs' => $dbFarmRole->getStorage()->getConfigs());
         foreach ($dbFarmRole->getStorage()->getVolumes() as $configKey => $config) {
             $storages['devices'][$configKey] = array();
             foreach ($config as $device) {
                 $info = array('farmRoleId' => $device->farmRoleId, 'placement' => $device->placement, 'serverIndex' => $device->serverIndex, 'storageId' => $device->storageId, 'storageConfigId' => $device->storageConfigId, 'status' => $device->status);
                 try {
                     $server = DBServer::LoadByFarmRoleIDAndIndex($device->farmRoleId, $device->serverIndex);
                     if ($server->status != SERVER_STATUS::TERMINATED) {
                         $info['serverId'] = $server->serverId;
                         $info['serverInstanceId'] = $server->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID);
                     }
                 } catch (Exception $e) {
                     $this->response->debugException($e);
                 }
                 $storages['devices'][$configKey][] = $info;
             }
         }
         $image = $dbFarmRole->GetRoleObject()->__getNewRoleObject()->getImage($dbFarmRole->Platform, $dbFarmRole->CloudLocation);
         $securityGroups = $this->getInitialSecurityGroupsList($dbFarmRole);
         $farmRoles[] = array('farm_role_id' => $dbFarmRole->ID, 'alias' => $dbFarmRole->Alias ? $dbFarmRole->Alias : $dbFarmRole->GetRoleObject()->name, 'role_id' => $dbFarmRole->RoleID, 'platform' => $dbFarmRole->Platform, 'os' => $dbFarmRole->GetRoleObject()->getOs()->name, 'os_family' => $dbFarmRole->GetRoleObject()->getOs()->family, 'os_generation' => $dbFarmRole->GetRoleObject()->getOs()->generation, 'os_version' => $dbFarmRole->GetRoleObject()->getOs()->version, 'osId' => $dbFarmRole->GetRoleObject()->getOs()->id, 'generation' => $dbFarmRole->GetRoleObject()->generation, 'group' => $dbFarmRole->GetRoleObject()->getCategoryName(), 'cat_id' => $dbFarmRole->GetRoleObject()->catId, 'isScalarized' => $dbFarmRole->GetRoleObject()->isScalarized, 'name' => $roleName, 'behaviors' => implode(",", $dbFarmRole->GetRoleObject()->getBehaviors()), 'scripting' => $scriptsObject, 'scripting_params' => $sParams, 'settings' => $dbFarmRole->GetAllSettings(), 'cloud_location' => $dbFarmRole->CloudLocation, 'launch_index' => (int) $dbFarmRole->LaunchIndex, 'scaling' => $scaling, 'image' => $image->getImage(), 'storages' => $storages, 'variables' => $farmRoleVariables->getValues($dbFarmRole->GetRoleID(), $dbFarm->ID, $dbFarmRole->ID), 'running_servers' => $dbFarmRole->GetRunningInstancesCount(), 'suspended_servers' => $dbFarmRole->GetSuspendedInstancesCount(), 'security_groups' => $securityGroups, 'hourly_rate' => $this->getInstanceTypeHourlyRate($dbFarmRole->Platform, $dbFarmRole->CloudLocation, $dbFarmRole->getInstanceType(), $dbFarmRole->GetRoleObject()->getOs()->family));
     }
     $vpc = array();
     if ($dbFarm->GetSetting(Entity\FarmSetting::EC2_VPC_ID)) {
         $vpc = array('id' => $dbFarm->GetSetting(Entity\FarmSetting::EC2_VPC_ID), 'region' => $dbFarm->GetSetting(Entity\FarmSetting::EC2_VPC_REGION));
     }
     /* @var $farm Entity\Farm */
     $farm = Entity\Farm::findPk($dbFarm->ID);
     // or implement AccessPermissionsInterface in DBFarm
     $farmOwnerEditable = $this->request->hasPermissions($farm, Acl::PERM_FARMS_CHANGE_OWNERSHIP) || $dbFarm->ownerId == $this->user->getId();
     $projectEditable = $this->user->isAccountOwner() || $this->request->hasPermissions($farm, Acl::PERM_FARMS_PROJECTS);
     $farmTeams = $farm->getTeams()->map(function ($team) {
         /* @var $ft Entity\Account\Team */
         return $team->name;
     });
     return array('farm' => array('name' => $dbFarm->Name, 'description' => $dbFarm->Comments, 'rolesLaunchOrder' => $dbFarm->RolesLaunchOrder, 'timezone' => $dbFarm->GetSetting(Entity\FarmSetting::TIMEZONE), 'variables' => $variables->getValues(0, $dbFarm->ID), 'vpc' => $vpc, 'status' => $dbFarm->Status, 'hash' => $dbFarm->Hash, 'owner' => $farmOwnerEditable ? $dbFarm->ownerId : ($dbFarm->ownerId ? Entity\Account\User::findPk($dbFarm->ownerId)->email : ''), 'ownerEditable' => $farmOwnerEditable, 'teamOwner' => $farmTeams, 'teamOwnerEditable' => $farmOwnerEditable, 'launchPermission' => $this->request->hasPermissions($farm, Acl::PERM_FARMS_LAUNCH_TERMINATE), 'projectEditable' => $projectEditable, Entity\FarmSetting::SZR_UPD_REPOSITORY => $dbFarm->GetSetting(Entity\FarmSetting::SZR_UPD_REPOSITORY), Entity\FarmSetting::SZR_UPD_SCHEDULE => $dbFarm->GetSetting(Entity\FarmSetting::SZR_UPD_SCHEDULE)), 'roles' => $farmRoles, 'lock' => $dbFarm->isLocked(false), 'changed' => $dbFarm->changedTime);
 }