Since: 5.0 (07.08.2014)
Author: Igor Vodiasov (invar@scalr.com)
Inheritance: extends Scalr\Model\AbstractEntity
Example #1
0
File: Role.php Project: scalr/scalr
 /**
  * Add, replace or remove image in role
  *
  * @param   string  $platform      The cloud platform
  * @param   string  $cloudLocation The cloud location
  * @param   string  $imageId       optional Either Identifier of the Image to add or NULL to remove
  * @param   integer $userId        The identifier of the User who adds the Image
  * @param   string  $userEmail     The email address of the User who adds the Image
  *
  * @throws ImageInUseException
  * @throws ImageNotFoundException
  * @throws NotAcceptableImageStatusException
  * @throws OsMismatchException
  * @throws \Scalr\Exception\ModelException
  */
 public function setImage($platform, $cloudLocation, $imageId, $userId, $userEmail)
 {
     if (in_array($platform, [\SERVER_PLATFORMS::GCE, \SERVER_PLATFORMS::AZURE])) {
         $cloudLocation = '';
     }
     $history = new ImageHistory();
     $history->roleId = $this->id;
     $history->platform = $platform;
     $history->cloudLocation = $cloudLocation;
     $history->addedById = $userId;
     $history->addedByEmail = $userEmail;
     $oldImage = null;
     try {
         $oldImage = $this->getImage($platform, $cloudLocation);
         $history->oldImageId = $oldImage->imageId;
         if ($imageId) {
             if ($oldImage->imageId == $imageId) {
                 return;
             }
         }
     } catch (\Exception $e) {
     }
     if ($imageId) {
         /* @var $newImage Image */
         $newImage = Image::findOne([['id' => $imageId], ['platform' => $platform], ['cloudLocation' => $cloudLocation], ['$or' => [['accountId' => null], ['$and' => [['accountId' => $this->accountId], ['$or' => [['envId' => null], ['envId' => $this->envId]]]]]]]]);
         if (!$newImage) {
             throw new ImageNotFoundException(sprintf("The Image does not exist, or isn't owned by your account: %s, %s, %s", $platform, $cloudLocation, $imageId));
         }
         if ($newImage->status !== Image::STATUS_ACTIVE) {
             throw new NotAcceptableImageStatusException(sprintf("You can't add image %s because of its status: %s", $newImage->id, $newImage->status));
         }
         if ($newImage->getOs()->family && $newImage->getOs()->generation) {
             // check only if they are set
             if ($this->getOs()->family != $newImage->getOs()->family || $this->getOs()->generation != $newImage->getOs()->generation) {
                 throw new OsMismatchException(sprintf("OS mismatch between Image: %s, family: %s and Role: %d, family: %s", $newImage->id, $newImage->getOs()->family, $this->id, $this->getOs()->family));
             }
         }
         if ($this->isScalarized && !($newImage->isScalarized || $newImage->hasCloudInit)) {
             throw new ImageNotScalarizedException("You can not add the Image {$newImage->id} because neither it is not use Scalr Agent nor cloud-init");
         }
         $history->imageId = $newImage->id;
         if ($oldImage) {
             $oldImage->delete();
         }
         $newRoleImage = new RoleImage();
         $newRoleImage->roleId = $this->id;
         $newRoleImage->imageId = $newImage->id;
         $newRoleImage->platform = $newImage->platform;
         $newRoleImage->cloudLocation = $newImage->cloudLocation;
         $newRoleImage->save();
     } else {
         if ($oldImage) {
             if ($oldImage->isUsed()) {
                 throw new ImageInUseException(sprintf("The Image for roleId: %d, platform: %s, cloudLocation: %s is used by some FarmRole", $oldImage->roleId, $oldImage->platform, $oldImage->cloudLocation));
             }
             $oldImage->delete();
         }
     }
     $history->save();
 }
Example #2
0
 /**
  * Associates a new Image with the Role
  *
  * @param  int      $roleId     The Identifier of the role
  * @return \Scalr\Api\DataType\ResultEnvelope
  * @throws ApiErrorException
  */
 public function registerImageAction($roleId)
 {
     $this->checkScopedPermissions('ROLES', 'MANAGE');
     //Gets role checking Environment scope
     $role = $this->getRole($roleId, true);
     $object = $this->request->getJsonBody();
     $objectImageId = static::getBareId($object, 'image');
     $objectRoleId = static::getBareId($object, 'role');
     if (empty($objectImageId)) {
         throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Invalid body");
     }
     if (!preg_match('/' . ApiApplication::REGEXP_UUID . '/', $objectImageId)) {
         throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid image identifier");
     }
     if (!empty($objectRoleId) && $roleId != $objectRoleId) {
         throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid identifier of the role");
     }
     if (is_object($object->image)) {
         $imageAdapter = $this->adapter('image');
         //Pre validates the request object
         $imageAdapter->validateObject($object->image);
     }
     $criteria = $this->getScopeCriteria();
     $criteria[] = ['hash' => $objectImageId];
     /* @var $image Entity\Image */
     $image = Entity\Image::findOne($criteria);
     if (empty($image)) {
         throw new ApiErrorException(404, ErrorMessage::ERR_INVALID_VALUE, "The Image either does not exist or isn't in scope for the current Environment.");
     }
     $roleImage = Entity\RoleImage::findOne([['roleId' => $roleId], ['platform' => $image->platform], ['cloudLocation' => $image->cloudLocation]]);
     if (!empty($roleImage)) {
         throw new ApiErrorException(400, ErrorMessage::ERR_BAD_REQUEST, sprintf("Image with cloud location %s has already been registered", $image->cloudLocation));
     }
     $this->setImage($role, $image->platform, $image->cloudLocation, $image->id, $this->getUser()->id, $this->getUser()->email);
     $this->response->setStatus(201);
     return $this->result(['image' => ['id' => $image->hash], 'role' => ['id' => $role->id]]);
 }
Example #3
0
 /**
  * @param   string  $platform       Name of platform
  * @param   string  $cloudLocation  Name of location
  * @param   array   $ids            The list of the identifiers of the cloud instances
  * @param   int     $roleId         optional    Identifier of Role
  * @return  array
  * @throws  Exception
  */
 public function checkStatus($platform, $cloudLocation, $ids, $roleId = null)
 {
     if (!in_array($platform, $this->allowedPlatforms)) {
         throw new Exception(sprintf("Platform '%s' is not supported", $platform));
     }
     if (!$this->environment->isPlatformEnabled($platform)) {
         throw new Exception(sprintf("Platform '%s' is not enabled", $platform));
     }
     if (empty($ids) || empty($ids[0])) {
         throw new Exception("You should provide at least one instanceId");
     }
     $instances = PlatformFactory::NewPlatform($platform)->getOrphanedServers($this->getEnvironmentEntity(), $cloudLocation, $ids);
     $status = ['instances' => $instances];
     $imageIds = array_unique(array_map(function ($item) {
         return $item->imageId;
     }, $instances));
     if (count($imageIds) != 1) {
         $status['compatibility'] = ['success' => false];
         return $status;
     }
     /* @var $instance OrphanedServer */
     $instance = $instances[0];
     $status['compatibility'] = ['success' => true];
     // Check vpc compatibility
     if ($instance->vpcId && $instance->subnetId) {
         $gov = new Scalr_Governance($this->getEnvironmentId());
         $vpcGovernanceRegions = $gov->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, 'regions');
         if (isset($vpcGovernanceRegions)) {
             if (!array_key_exists($cloudLocation, $vpcGovernanceRegions)) {
                 $status['compatibility']['success'] = false;
                 $status['compatibility']['message'] = sprintf('Region <b>%s</b> is not allowed by the Governance.', $cloudLocation);
             } else {
                 $vpcGovernanceIds = $vpcGovernanceRegions[$cloudLocation]['ids'];
                 if (!empty($vpcGovernanceIds) && !in_array($instance->vpcId, $vpcGovernanceIds)) {
                     $status['compatibility']['success'] = false;
                     $status['compatibility']['message'] = sprintf('VPC <b>%s</b> is not allowed by the Governance.', $instance->vpcId);
                 } else {
                     $vpcGovernanceIds = $gov->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::AWS_VPC, 'ids');
                     /* @var $platformObject Ec2PlatformModule */
                     $platformObject = PlatformFactory::NewPlatform(SERVER_PLATFORMS::EC2);
                     $subnet = $platformObject->listSubnets($this->getEnvironment(), $cloudLocation, $instance->vpcId, true, $instance->subnetId);
                     if (isset($vpcGovernanceIds[$instance->vpcId])) {
                         if (!empty($vpcGovernanceIds[$instance->vpcId]) && is_array($vpcGovernanceIds[$instance->vpcId]) && !in_array($instance->subnetId, $vpcGovernanceIds[$instance->vpcId])) {
                             $status['compatibility']['success'] = false;
                             $status['compatibility']['message'] = sprintf('Subnet <b>%s</b> is prohibited by the Governance.', $instance->subnetId);
                         } else {
                             if ($vpcGovernanceIds[$instance->vpcId] == "outbound-only" && $subnet['type'] != 'private') {
                                 $status['compatibility']['success'] = false;
                                 $status['compatibility']['message'] = 'Only private subnets are allowed by the Governance.';
                             } else {
                                 if ($vpcGovernanceIds[$instance->vpcId] == "full" && $subnet['type'] != 'public') {
                                     $status['compatibility']['success'] = false;
                                     $status['compatibility']['message'] = 'Only public subnets are allowed by the Governance.';
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (!$status['compatibility']['success']) {
         return $status;
     }
     $scopeCriteria = ['$or' => [['accountId' => null], ['$and' => [['accountId' => $this->getUser()->accountId], ['$or' => [['envId' => null], ['envId' => $this->getEnvironment()->id]]]]]]];
     /* @var $image Entity\Image */
     $image = Entity\Image::findOne([['platform' => $platform], ['cloudLocation' => $cloudLocation], ['id' => $instance->imageId], $scopeCriteria]);
     $status['image'] = ['success' => !!$image, 'data' => ['id' => $instance->imageId]];
     if ($image) {
         if ($image->isScalarized) {
             $status['image']['success'] = false;
             $status['image']['isScalarized'] = true;
             return $status;
         }
         $status['image']['data'] = ['hash' => $image->hash, 'name' => $image->name, 'id' => $image->id, 'scope' => $image->getScope()];
         $criteria = [['platform' => $platform], ['imageId' => $image->id]];
         if (!($platform == SERVER_PLATFORMS::GCE || $platform == SERVER_PLATFORMS::AZURE)) {
             $criteria[] = ['cloudLocation' => $cloudLocation];
         }
         $roleIds = [];
         foreach (Entity\RoleImage::find($criteria) as $ri) {
             $roleIds[] = $ri->roleId;
         }
         if (count($roleIds)) {
             $roles = Entity\Role::find([['id' => ['$in' => $roleIds]], ['isScalarized' => false], $scopeCriteria]);
             $status['role'] = ['availableRoles' => [], 'image' => Scalr_UI_Controller_Images::controller()->convertEntityToArray($image)];
             $selectedRole = null;
             if (count($roles) == 1) {
                 $selectedRole = $roles->current();
             } else {
                 if ($roleId && in_array($roleId, $roleIds)) {
                     foreach ($roles as $role) {
                         /* @var $role Entity\Role */
                         if ($role->id == $roleId) {
                             $selectedRole = $role;
                             break;
                         }
                     }
                 }
             }
             foreach ($roles as $role) {
                 /* @var $role Entity\Role */
                 $status['role']['availableRoles'][] = ['id' => $role->id, 'name' => $role->name, 'scope' => $role->getScope()];
             }
             if ($selectedRole) {
                 $status['role']['success'] = true;
                 $status['role']['data'] = ['id' => $selectedRole->id, 'name' => $selectedRole->name, 'scope' => $selectedRole->getScope()];
                 $farms = [];
                 $status['farmrole'] = ['instance' => ['instanceType' => $instance->instanceType, 'vpcId' => $instance->vpcId, 'subnetId' => $instance->subnetId, 'roleName' => $selectedRole->name]];
                 foreach (Entity\Farm::find([['envId' => $this->getEnvironment()->id], ['status' => FARM_STATUS::RUNNING]]) as $farm) {
                     /* @var $farm Entity\Farm */
                     if ($this->request->hasPermissions($farm, Acl::PERM_FARMS_UPDATE) && $this->request->hasPermissions($farm, Acl::PERM_FARMS_SERVERS)) {
                         // cloud specific (EC2)
                         if ($farm->settings[Entity\FarmSetting::EC2_VPC_ID] == $instance->vpcId) {
                             $farms[$farm->id] = ['id' => $farm->id, 'name' => $farm->name, 'farmroles' => []];
                         }
                     }
                 }
                 foreach (Entity\FarmRole::find([['farmId' => ['$in' => array_keys($farms)]], ['roleId' => $selectedRole->id]]) as $farmRole) {
                     /* @var $farmRole Entity\FarmRole */
                     if (isset($farms[$farmRole->farmId])) {
                         if (!$instance->subnetId || $instance->subnetId && in_array($instance->subnetId, json_decode($farmRole->settings[Entity\FarmRoleSetting::AWS_VPC_SUBNET_ID]))) {
                             $farms[$farmRole->farmId]['farmroles'][] = ['id' => $farmRole->id, 'name' => $farmRole->alias, 'tags' => $farmRole->getCloudTags(true)];
                         }
                     }
                 }
                 $status['farmrole']['data'] = array_values($farms);
                 $status['farmrole']['success'] = false;
             } else {
                 if (count($roles) > 1) {
                     $status['role']['success'] = false;
                 } else {
                     $status['role']['success'] = false;
                 }
             }
         } else {
             $status['role']['success'] = false;
             $status['role']['image'] = Scalr_UI_Controller_Images::controller()->convertEntityToArray($image);
         }
     }
     return $status;
 }
Example #4
0
 /**
  * Gets the Image Entity
  *
  * @return  Image|null   Returns the Image that corresponds to the Server
  */
 public function getImage()
 {
     if (empty($this->_image) && !empty($this->roleId) && !empty($this->platform)) {
         $i = new Image();
         $ri = new RoleImage();
         $rec = $this->db()->GetRow("\n                SELECT {$i->fields()}\n                FROM {$i->table()}\n                LEFT JOIN {$ri->table()} ON {$i->columnPlatform} = {$ri->columnPlatform}\n                    AND {$i->columnCloudLocation} = {$ri->columnCloudLocation}\n                    AND {$i->columnId} = {$ri->columnImageId}\n                WHERE {$ri->columnRoleId} = ?\n                AND {$ri->columnPlatform} = ?\n                AND {$ri->columnCloudLocation} = ?\n                AND ({$i->columnAccountId} IS NULL OR {$i->columnAccountId} = ?\n                    AND ({$i->columnEnvId} IS NULL OR {$i->columnEnvId} = ?)\n                )\n            ", [$this->roleId, $this->platform, in_array($this->platform, [SERVER_PLATFORMS::GCE, SERVER_PLATFORMS::AZURE]) ? '' : $this->cloudLocation, $this->getFarm()->accountId, $this->getFarm()->envId]);
         if ($rec) {
             $this->_image = $i;
             $this->_image->load($rec);
         }
     }
     return $this->_image;
 }
Example #5
0
 /**
  * @param   int   $roleId
  * @throws  Exception
  * @throws  Scalr_Exception_Core
  * @throws  Scalr_Exception_InsufficientPermissions
  * @throws  Scalr_UI_Exception_NotFound
  */
 public function editAction($roleId = 0)
 {
     $this->request->restrictAccess('ROLES', 'MANAGE');
     $params = array();
     $params['scriptData'] = \Scalr\Model\Entity\Script::getScriptingData($this->user->getAccountId(), $this->getEnvironmentId(true));
     $params['categories'] = array_values($this->listRoleCategories());
     $params['accountScripts'] = [];
     if (!$this->user->isScalrAdmin()) {
         foreach (Scalr_UI_Controller_Account2_Orchestration::controller()->getOrchestrationRules() as $script) {
             $script['system'] = 'account';
             $params['accountScripts'][] = $script;
         }
     }
     $envs = [];
     if ($this->request->getScope() == ScopeInterface::SCOPE_ACCOUNT) {
         foreach (Environment::find([['accountId' => $this->user->getAccountId()]], null, ['name' => true]) as $env) {
             /* @var $env Environment */
             $envs[] = ['id' => $env->id, 'name' => $env->name, 'enabled' => 1];
         }
     }
     $variables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(true), ScopeInterface::SCOPE_ROLE);
     if ($roleId) {
         /* @var $role Role */
         $role = Role::findPk($roleId);
         if (!$role) {
             throw new Scalr_Exception_Core(sprintf(_("Role ID#%s not found in database"), $roleId));
         }
         $this->request->checkPermissions($role, true);
         $images = array();
         foreach (RoleImage::find([['roleId' => $role->id]]) as $image) {
             /* @var $image RoleImage */
             $im = $image->getImage();
             $a = get_object_vars($image);
             if ($im) {
                 $b = get_object_vars($im);
                 $b['scope'] = $im->getScope();
                 $b['dtAdded'] = Scalr_Util_DateTime::convertTz($b['dtAdded']);
                 $b['software'] = $im->getSoftwareAsString();
                 $a['name'] = $im->name;
                 $a['hash'] = $im->hash;
                 $a['extended'] = $b;
             }
             $images[] = $a;
         }
         $properties = [];
         foreach (RoleProperty::find([['roleId' => $role->id], ['name' => ['$like' => 'chef.%']]]) as $prop) {
             /* @var $prop RoleProperty */
             $properties[$prop->name] = $prop->value;
         }
         $params['role'] = array('roleId' => $role->id, 'name' => $role->name, 'catId' => $role->catId, 'os' => $role->getOs()->name, 'osId' => $role->osId, 'osFamily' => $role->getOs()->family, 'osGeneration' => $role->getOs()->generation, 'osVersion' => $role->getOs()->version, 'description' => $role->description, 'behaviors' => $role->getBehaviors(), 'images' => $images, 'scripts' => $role->getScripts(), 'dtadded' => Scalr_Util_DateTime::convertTz($role->added), 'addedByEmail' => $role->addedByEmail, 'chef' => $properties, 'isQuickStart' => $role->isQuickStart, 'isDeprecated' => $role->isDeprecated, 'isScalarized' => $role->isScalarized, 'environments' => []);
         if ($this->request->getScope() == ScopeInterface::SCOPE_ACCOUNT) {
             $allowedEnvs = $role->getAllowedEnvironments();
             if (!empty($allowedEnvs)) {
                 foreach ($envs as &$env) {
                     $env['enabled'] = in_array($env['id'], $allowedEnvs) ? 1 : 0;
                 }
             }
             $params['role']['environments'] = $envs;
         }
         $params['role']['variables'] = $variables->getValues($role->id);
         $params['roleUsage'] = ['farms' => $role->getFarmsCount($this->user->getAccountId(), $this->getEnvironmentId(true)), 'instances' => $role->getServersCount($this->user->getAccountId(), $this->getEnvironmentId(true))];
     } else {
         $params['role'] = array('roleId' => 0, 'name' => '', 'arch' => 'x86_64', 'agent' => 2, 'description' => '', 'behaviors' => array(), 'images' => array(), 'scripts' => array(), 'tags' => array(), 'environments' => [], 'variables' => $variables->getValues(), 'isScalarized' => 1);
         if ($this->request->getScope() == ScopeInterface::SCOPE_ACCOUNT) {
             $params['role']['environments'] = $envs;
         }
     }
     $this->response->page('ui/roles/edit.js', $params, ['ui/roles/edit/overview.js', 'ui/roles/edit/images.js', 'ui/roles/edit/scripting.js', 'ui/roles/edit/variables.js', 'ui/roles/edit/chef.js', 'ui/roles/edit/environments.js', 'ui/scripts/scriptfield.js', 'ui/core/variablefield.js', 'ui/services/chef/chefsettings.js'], ['ui/roles/edit.css', 'ui/scripts/scriptfield.css']);
 }
Example #6
0
 public function editAction()
 {
     $this->request->restrictAccess(Acl::RESOURCE_FARMS_ROLES, Acl::PERM_FARMS_ROLES_MANAGE);
     $this->request->defineParams(array('roleId' => array('type' => 'int')));
     $params = array();
     $params['scriptData'] = \Scalr\Model\Entity\Script::getScriptingData($this->user->getAccountId(), $this->getEnvironmentId(true));
     $params['categories'] = $this->db->GetAll("SELECT * FROM role_categories WHERE env_id IS NULL OR env_id = ?", [$this->user->isScalrAdmin() ? null : $this->getEnvironmentId()]);
     $params['accountScripts'] = [];
     if (!$this->user->isScalrAdmin()) {
         foreach (self::loadController('Orchestration', 'Scalr_UI_Controller_Account2')->getOrchestrationRules() as $script) {
             $script['system'] = 'account';
             $params['accountScripts'][] = $script;
         }
     }
     $variables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->user->isScalrAdmin() ? 0 : $this->getEnvironmentId(), Scalr_Scripting_GlobalVariables::SCOPE_ROLE);
     if ($this->getParam('roleId')) {
         $dbRole = DBRole::loadById($this->getParam('roleId'));
         if (!$this->user->isScalrAdmin()) {
             $this->user->getPermissions()->validate($dbRole);
         }
         $images = array();
         foreach (RoleImage::find([['roleId' => $dbRole->id]]) as $image) {
             /* @var $image RoleImage */
             $im = $image->getImage();
             $a = get_object_vars($image);
             if ($im) {
                 $b = get_object_vars($im);
                 $b['dtAdded'] = Scalr_Util_DateTime::convertTz($b['dtAdded']);
                 $b['software'] = $im->getSoftwareAsString();
                 $a['name'] = $im->name;
                 $a['hash'] = $im->hash;
                 $a['extended'] = $b;
             }
             $images[] = $a;
         }
         $params['role'] = array('roleId' => $dbRole->id, 'name' => $dbRole->name, 'catId' => $dbRole->catId, 'os' => $dbRole->getOs()->name, 'osId' => $dbRole->osId, 'osFamily' => $dbRole->getOs()->family, 'osGeneration' => $dbRole->getOs()->generation, 'osVersion' => $dbRole->getOs()->version, 'description' => $dbRole->description, 'behaviors' => $dbRole->getBehaviors(), 'images' => $images, 'scripts' => $dbRole->getScripts(), 'dtadded' => Scalr_Util_DateTime::convertTz($dbRole->dateAdded), 'addedByEmail' => $dbRole->addedByEmail, 'chef' => $dbRole->getProperties('chef.'));
         $params['role']['variables'] = $variables->getValues($dbRole->id);
         if ($this->user->isScalrAdmin()) {
             $params['roleUsage'] = array('farms' => $dbRole->getFarmRolesCount(), 'instances' => $this->db->GetOne("SELECT COUNT(*) FROM servers LEFT JOIN farm_roles ON servers.farm_roleid = farm_roles.id WHERE farm_roles.role_id=?", array($dbRole->id)));
         } else {
             $params['roleUsage'] = array('farms' => $dbRole->getFarmRolesCount($this->getEnvironmentId()), 'instances' => $this->db->GetOne("SELECT COUNT(*) FROM servers LEFT JOIN farm_roles ON servers.farm_roleid = farm_roles.id WHERE farm_roles.role_id=? AND env_id=?", array($dbRole->id, $this->getEnvironmentId())));
         }
     } else {
         $params['role'] = array('roleId' => 0, 'name' => '', 'arch' => 'x86_64', 'agent' => 2, 'description' => '', 'behaviors' => array(), 'images' => array(), 'scripts' => array(), 'tags' => array(), 'variables' => $variables->getValues());
     }
     $this->response->page('ui/roles/edit.js', $params, array('ui/roles/edit/overview.js', 'ui/roles/edit/images.js', 'ui/roles/edit/scripting.js', 'ui/roles/edit/variables.js', 'ui/roles/edit/chef.js', 'ui/scripts/scriptfield.js', 'ui/core/variablefield.js', 'ui/services/chef/chefsettings.js'), array('ui/roles/edit.css', 'ui/scripts/scriptfield.css'));
 }