/** * Creates clone for the farm * * @param string $name The name of the farm * @param Scalr_Account_User $user The user object * @param int $envId The identifier of the environment * @return DBFarm Returns clone */ public function cloneFarm($name = false, Scalr_Account_User $user, $envId) { $account = $user->getAccount(); $account->validateLimit(Scalr_Limits::ACCOUNT_FARMS, 1); $definition = $this->getDefinition(); if (!$name) { $template = ""; if (!stristr($definition->name, "clone")) { $template = $definition->name . ' (clone #%s)'; $i = 1; } else { preg_match("/^(.*?)\\(clone \\#([0-9]*)\\)\$/si", $definition->name, $matches); $template = trim($matches[1]) . " (clone #%s)"; $i = $matches[2] + 1; } while (true) { $name = sprintf($template, $i); if (!$this->DB->GetOne("SELECT id FROM farms WHERE name = ? AND env_id = ? LIMIT 1", array($name, $this->EnvID))) { break; } else { $i++; } } } $dbFarm = self::create($name, $user, $envId); $dbFarm->createdByUserId = $user->id; $dbFarm->createdByUserEmail = $user->getEmail(); $dbFarm->RolesLaunchOrder = $definition->rolesLaunchOrder; $dbFarm->SetSetting(DBFarm::SETTING_TIMEZONE, $definition->settings[DBFarm::SETTING_TIMEZONE]); $dbFarm->SetSetting(DBFarm::SETTING_EC2_VPC_ID, $definition->settings[DBFarm::SETTING_EC2_VPC_ID]); $dbFarm->SetSetting(DBFarm::SETTING_EC2_VPC_REGION, $definition->settings[DBFarm::SETTING_EC2_VPC_REGION]); $dbFarm->SetSetting(DBFarm::SETTING_SZR_UPD_REPOSITORY, $definition->settings[DBFarm::SETTING_SZR_UPD_REPOSITORY]); $dbFarm->SetSetting(DBFarm::SETTING_SZR_UPD_SCHEDULE, $definition->settings[DBFarm::SETTING_SZR_UPD_SCHEDULE]); $dbFarm->SetSetting(DBFarm::SETTING_LEASE_STATUS, $definition->settings[DBFarm::SETTING_LEASE_STATUS]); $variables = new Scalr_Scripting_GlobalVariables($dbFarm->ClientID, $envId, Scalr_Scripting_GlobalVariables::SCOPE_FARM); $variables->setValues($definition->globalVariables, 0, $dbFarm->ID, 0); foreach ($definition->roles as $index => $role) { $dbFarmRole = $dbFarm->AddRole(DBRole::loadById($role->roleId), $role->platform, $role->cloudLocation, $index + 1, $role->alias); $oldRoleSettings = $dbFarmRole->GetAllSettings(); $dbFarmRole->applyDefinition($role, true); $newSettings = $dbFarmRole->GetAllSettings(); Scalr_Helpers_Dns::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $newSettings); // Platfrom specified updates if ($dbFarmRole->Platform == SERVER_PLATFORMS::EC2) { \Scalr\Modules\Platforms\Ec2\Helpers\EbsHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $newSettings); \Scalr\Modules\Platforms\Ec2\Helpers\EipHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $newSettings); \Scalr\Modules\Platforms\Ec2\Helpers\ElbHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $newSettings); } if (in_array($dbFarmRole->Platform, array(SERVER_PLATFORMS::IDCF, SERVER_PLATFORMS::CLOUDSTACK))) { CloudstackHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $newSettings); } $dbFarmRolesList[] = $dbFarmRole; $usedPlatforms[$role->platform] = 1; } if ($usedPlatforms[SERVER_PLATFORMS::EC2]) { \Scalr\Modules\Platforms\Ec2\Helpers\Ec2Helper::farmSave($dbFarm, $dbFarmRolesList); } if ($usedPlatforms[SERVER_PLATFORMS::EUCALYPTUS]) { \Scalr\Modules\Platforms\Eucalyptus\Helpers\EucalyptusHelper::farmSave($dbFarm, $dbFarmRolesList); } if ($usedPlatforms[SERVER_PLATFORMS::CLOUDSTACK]) { CloudstackHelper::farmSave($dbFarm, $dbFarmRolesList); } $dbFarm->save(); return $dbFarm; }
public function xBuildAction() { $this->request->defineParams(array('farmId' => array('type' => 'int'), 'roles' => array('type' => 'json'), 'farm' => array('type' => 'json'), 'roleUpdate' => array('type' => 'int'))); $this->request->restrictAccess(Acl::RESOURCE_FARMS, Acl::PERM_FARMS_MANAGE); if (!$this->isFarmConfigurationValid($this->getParam('farmId'), $this->getParam('farm'), (array) $this->getParam('roles'))) { if ($this->errors['error_count'] != 0) { $this->response->failure(); $this->response->data(array('errors' => $this->errors)); return; } } $farm = $this->getParam('farm'); $client = Client::Load($this->user->getAccountId()); if ($this->getParam('farmId')) { $dbFarm = DBFarm::LoadByID($this->getParam('farmId')); $this->user->getPermissions()->validate($dbFarm); $dbFarm->isLocked(); if ($this->getParam('changed') && $dbFarm->changedTime && $this->getParam('changed') != $dbFarm->changedTime) { $userName = '******'; $changed = explode(' ', $this->getParam('changed')); $changedTime = intval($changed[1]); try { $user = new Scalr_Account_User(); $user->loadById($dbFarm->changedByUserId); $userName = $user->getEmail(); } catch (Exception $e) { } $this->response->failure(); $this->response->data(array('changedFailure' => sprintf('%s changed this farm at %s', $userName, Scalr_Util_DateTime::convertTz($changedTime)))); return; } $dbFarm->changedByUserId = $this->user->getId(); $dbFarm->changedTime = microtime(); $bNew = false; } else { $this->user->getAccount()->validateLimit(Scalr_Limits::ACCOUNT_FARMS, 1); $dbFarm = new DBFarm(); $dbFarm->ClientID = $this->user->getAccountId(); $dbFarm->EnvID = $this->getEnvironmentId(); $dbFarm->Status = FARM_STATUS::TERMINATED; $dbFarm->createdByUserId = $this->user->getId(); $dbFarm->createdByUserEmail = $this->user->getEmail(); $dbFarm->changedByUserId = $this->user->getId(); $dbFarm->changedTime = microtime(); $bNew = true; } if ($this->getParam('farm')) { $dbFarm->Name = $this->request->stripValue($farm['name']); $dbFarm->RolesLaunchOrder = $farm['rolesLaunchOrder']; $dbFarm->Comments = $this->request->stripValue($farm['description']); } if (empty($dbFarm->Name)) { throw new Exception(_("Farm name required")); } if (!$bNew && $farm['owner'] && $farm['owner'] != $dbFarm->createdByUserId) { if ($dbFarm->createdByUserId == $this->user->getId() || $this->user->isAccountOwner()) { $user = (new Scalr_Account_User())->loadById($farm['owner']); $dbFarm->createdByUserId = $user->getId(); $dbFarm->createdByUserEmail = $user->getEmail(); // TODO: move to subclass \Farm\Setting\OwnerHistory $history = unserialize($dbFarm->GetSetting(DBFarm::SETTING_OWNER_HISTORY)); if (!is_array($history)) { $history = []; } $history[] = ['newId' => $user->getId(), 'newEmail' => $user->getEmail(), 'changedById' => $this->user->getId(), 'changedByEmail' => $this->user->getEmail(), 'dt' => date('Y-m-d H:i:s')]; $dbFarm->SetSetting(DBFarm::SETTING_OWNER_HISTORY, serialize($history)); } } $dbFarm->save(); $governance = new Scalr_Governance($this->getEnvironmentId()); if (!$this->getParam('farmId') && $governance->isEnabled(Scalr_Governance::CATEGORY_GENERAL, Scalr_Governance::GENERAL_LEASE)) { $dbFarm->SetSetting(DBFarm::SETTING_LEASE_STATUS, 'Active'); // for created farm } if (isset($farm['variables'])) { $variables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), Scalr_Scripting_GlobalVariables::SCOPE_FARM); $variables->setValues(is_array($farm['variables']) ? $farm['variables'] : [], 0, $dbFarm->ID, 0, '', false, true); } if (!$farm['timezone']) { $farm['timezone'] = date_default_timezone_get(); } $dbFarm->SetSetting(DBFarm::SETTING_TIMEZONE, $farm['timezone']); $dbFarm->SetSetting(DBFarm::SETTING_EC2_VPC_ID, $farm['vpc_id']); $dbFarm->SetSetting(DBFarm::SETTING_EC2_VPC_REGION, $farm['vpc_region']); if (!$dbFarm->GetSetting(DBFarm::SETTING_CRYPTO_KEY)) { $dbFarm->SetSetting(DBFarm::SETTING_CRYPTO_KEY, Scalr::GenerateRandomKey(40)); } if ($this->getContainer()->analytics->enabled) { if ($this->request->isInterfaceBetaOrNotHostedScalr()) { //Cost analytics project must be set for the Farm object $dbFarm->setProject(!empty($farm['projectId']) ? $farm['projectId'] : null, $this->request->isInterfaceBetaOrNotHostedScalr()); } else { if (isset($bNew)) { //Default project is set for hosted scalr accounts. Users cannot manage it. $farm['projectId'] = $dbFarm->setProject(null); } } } $virtualFarmRoles = array(); $roles = $this->getParam('roles'); if (!empty($roles)) { foreach ($roles as $role) { if (strpos($role['farm_role_id'], "virtual_") !== false) { $dbRole = DBRole::loadById($role['role_id']); $dbFarmRole = $dbFarm->AddRole($dbRole, $role['platform'], $role['cloud_location'], (int) $role['launch_index'], $role['alias']); $virtualFarmRoles[$role['farm_role_id']] = $dbFarmRole->ID; } } } $usedPlatforms = array(); $dbFarmRolesList = array(); $newFarmRolesList = array(); $farmRoleVariables = new Scalr_Scripting_GlobalVariables($this->user->getAccountId(), $this->getEnvironmentId(), Scalr_Scripting_GlobalVariables::SCOPE_FARMROLE); if (!empty($roles)) { foreach ($roles as $role) { if ($role['farm_role_id']) { if ($virtualFarmRoles[$role['farm_role_id']]) { $role['farm_role_id'] = $virtualFarmRoles[$role['farm_role_id']]; } $update = true; $dbFarmRole = DBFarmRole::LoadByID($role['farm_role_id']); $dbRole = DBRole::loadById($dbFarmRole->RoleID); $role['role_id'] = $dbFarmRole->RoleID; if ($dbFarmRole->Platform == SERVER_PLATFORMS::GCE) { $dbFarmRole->CloudLocation = $role['cloud_location']; } } else { $update = false; $dbRole = DBRole::loadById($role['role_id']); $dbFarmRole = $dbFarm->AddRole($dbRole, $role['platform'], $role['cloud_location'], (int) $role['launch_index']); } if ($dbRole->hasBehavior(ROLE_BEHAVIORS::RABBITMQ)) { $role['settings'][DBFarmRole::SETTING_SCALING_MAX_INSTANCES] = $role['settings'][DBFarmRole::SETTING_SCALING_MIN_INSTANCES]; } if ($dbFarmRole->NewRoleID) { continue; } if ($update) { $dbFarmRole->LaunchIndex = (int) $role['launch_index']; $dbFarmRole->Alias = $role['alias']; $dbFarmRole->Save(); } $usedPlatforms[$role['platform']] = 1; $oldRoleSettings = $dbFarmRole->GetAllSettings(); // Update virtual farm_role_id with actual value $scripts = (array) $role['scripting']; if (count($virtualFarmRoles) > 0) { array_walk_recursive($scripts, function (&$v, $k) use($virtualFarmRoles) { if (is_string($v)) { $v = str_replace(array_keys($virtualFarmRoles), array_values($virtualFarmRoles), $v); } }); array_walk_recursive($role['settings'], function (&$v, $k) use($virtualFarmRoles) { if (is_string($v)) { $v = str_replace(array_keys($virtualFarmRoles), array_values($virtualFarmRoles), $v); } }); } $dbFarmRole->ClearSettings("chef."); if (!empty($role['scaling_settings']) && is_array($role['scaling_settings'])) { foreach ($role['scaling_settings'] as $k => $v) { $dbFarmRole->SetSetting($k, $v, DBFarmRole::TYPE_CFG); } } foreach ($role['settings'] as $k => $v) { $dbFarmRole->SetSetting($k, $v, DBFarmRole::TYPE_CFG); } /****** Scaling settings ******/ $scalingManager = new Scalr_Scaling_Manager($dbFarmRole); $scalingManager->setFarmRoleMetrics(is_array($role['scaling']) ? $role['scaling'] : array()); //TODO: optimize this code... $this->db->Execute("DELETE FROM farm_role_scaling_times WHERE farm_roleid=?", array($dbFarmRole->ID)); // 5 = Time based scaling -> move to constants if ($role['scaling'][5]) { foreach ($role['scaling'][5] as $scal_period) { $chunks = explode(":", $scal_period['id']); $this->db->Execute("INSERT INTO farm_role_scaling_times SET\n farm_roleid\t\t= ?,\n start_time\t\t= ?,\n end_time\t\t= ?,\n days_of_week\t= ?,\n instances_count\t= ?\n ", array($dbFarmRole->ID, $chunks[0], $chunks[1], $chunks[2], $chunks[3])); } } /*****************/ /* Update role params */ $dbFarmRole->SetParameters((array) $role['params']); /* End of role params management */ /* Add script options to databse */ $dbFarmRole->SetScripts($scripts, (array) $role['scripting_params']); /* End of scripting section */ /* Add services configuration */ $dbFarmRole->SetServiceConfigPresets((array) $role['config_presets']); /* End of scripting section */ /* Add storage configuration */ if (isset($role['storages'])) { if (isset($role['storages']['configs'])) { $dbFarmRole->getStorage()->setConfigs($role['storages']['configs']); } } $farmRoleVariables->setValues(is_array($role['variables']) ? $role['variables'] : [], $dbFarmRole->GetRoleID(), $dbFarm->ID, $dbFarmRole->ID, '', false, true); Scalr_Helpers_Dns::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); foreach (Scalr_Role_Behavior::getListForFarmRole($dbFarmRole) as $behavior) { $behavior->onFarmSave($dbFarm, $dbFarmRole); } /** * Platfrom specified updates */ if ($dbFarmRole->Platform == SERVER_PLATFORMS::EC2) { \Scalr\Modules\Platforms\Ec2\Helpers\EbsHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); \Scalr\Modules\Platforms\Ec2\Helpers\EipHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); \Scalr\Modules\Platforms\Ec2\Helpers\ElbHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); } if (in_array($dbFarmRole->Platform, array(SERVER_PLATFORMS::IDCF, SERVER_PLATFORMS::CLOUDSTACK))) { Scalr\Modules\Platforms\Cloudstack\Helpers\CloudstackHelper::farmUpdateRoleSettings($dbFarmRole, $oldRoleSettings, $role['settings']); } $dbFarmRolesList[] = $dbFarmRole; $newFarmRolesList[] = $dbFarmRole->ID; } } if (!$this->getParam('roleUpdate')) { foreach ($dbFarm->GetFarmRoles() as $dbFarmRole) { if (!$dbFarmRole->NewRoleID && !in_array($dbFarmRole->ID, $newFarmRolesList)) { $dbFarmRole->Delete(); } } } if ($usedPlatforms[SERVER_PLATFORMS::CLOUDSTACK]) { \Scalr\Modules\Platforms\Cloudstack\Helpers\CloudstackHelper::farmSave($dbFarm, $dbFarmRolesList); } if ($usedPlatforms[SERVER_PLATFORMS::EC2]) { \Scalr\Modules\Platforms\Ec2\Helpers\Ec2Helper::farmSave($dbFarm, $dbFarmRolesList); } if ($usedPlatforms[SERVER_PLATFORMS::EUCALYPTUS]) { \Scalr\Modules\Platforms\Eucalyptus\Helpers\EucalyptusHelper::farmSave($dbFarm, $dbFarmRolesList); } $dbFarm->save(); if (!$client->GetSettingValue(CLIENT_SETTINGS::DATE_FARM_CREATED)) { $client->SetSettingValue(CLIENT_SETTINGS::DATE_FARM_CREATED, time()); } $this->response->success('Farm successfully saved'); $this->response->data(array('farmId' => $dbFarm->ID)); }