public function onFarmSave(DBFarm $dbFarm, DBFarmRole $dbFarmRole) { try { $account = Scalr_Account::init()->loadById($dbFarm->ClientID); if (!$account->isFeatureEnabled(Scalr_Limits::FEATURE_CHEF)) { $dbFarmRole->ClearSettings("chef."); return false; } $db = Core::GetDBInstance(); $runListId = $dbFarmRole->GetSetting(self::ROLE_CHEF_RUNLIST_ID); $attributes = $dbFarmRole->GetSetting(self::ROLE_CHEF_ATTRIBUTES); $checksum = $dbFarmRole->GetSetting(self::ROLE_CHEF_CHECKSUM); $chefRoleName = $dbFarmRole->GetSetting(self::ROLE_CHEF_ROLE_NAME); $chefServerId = $dbFarmRole->GetSetting(self::ROLE_CHEF_SERVER_ID); // Need to remove chef role if chef was disabled for current farmrole if (!$runListId && $chefRoleName) { $this->removeChefRole($chefServerId, $chefRoleName); $dbFarmRole->ClearSettings("chef."); return true; } if ($runListId) { $runListInfo = $this->db->GetRow("SELECT chef_server_id, runlist FROM services_chef_runlists WHERE id=?", array($runListId)); $newChefServerId = $runListInfo['chef_server_id']; if ($newChefServerId != $chefServerId && $chefServerId) { // Remove role from old server $this->removeChefRole($chefServerId, $chefRoleName); $createNew = true; } if (!$chefServerId) { $createNew = true; } $chefServerInfo = $this->db->GetRow("SELECT * FROM services_chef_servers WHERE id=?", array($runListInfo['chef_server_id'])); $chefServerInfo['auth_key'] = $this->getCrypto()->decrypt($chefServerInfo['auth_key'], $this->cryptoKey); $chefClient = Scalr_Service_Chef_Client::getChef($chefServerInfo['url'], $chefServerInfo['username'], trim($chefServerInfo['auth_key'])); $roleName = "scalr-{$dbFarmRole->ID}"; $setSettings = false; if ($createNew) { $chefClient->createRole($roleName, $roleName, json_decode($runListInfo['runlist']), json_decode($attributes), $runListInfo['chef_environment']); $setSettings = true; } else { if ($dbFarmRole->GetSetting(self::ROLE_CHEF_CHECKSUM) != md5("{$runListInfo['runlist']}.{$attributes}")) { $chefClient->updateRole($roleName, $roleName, json_decode($runListInfo['runlist']), json_decode($attributes), $runListInfo['chef_environment']); $setSettings = true; } } if ($setSettings) { $dbFarmRole->SetSetting(self::ROLE_CHEF_ROLE_NAME, $roleName); $dbFarmRole->SetSetting(self::ROLE_CHEF_SERVER_ID, $runListInfo['chef_server_id']); $dbFarmRole->SetSetting(self::ROLE_CHEF_CHECKSUM, md5("{$runListInfo['runlist']}.{$attributes}")); } } } catch (Exception $e) { throw new Exception("Chef settings error: {$e->getMessage()} ({$e->getTraceAsString()})"); } }
public function onFarmSave(DBFarm $dbFarm, DBFarmRole $dbFarmRole) { if (!$dbFarmRole->GetSetting(self::ROLE_COOKIE_NAME)) { $cookie = substr(sha1(microtime(true) . rand(0, 100000)), 0, 20); $dbFarmRole->SetSetting(self::ROLE_COOKIE_NAME, $cookie, DBFarmRole::TYPE_LCL); } }
public function setMsrSettings($settings) { if ($settings->volumeConfig) { try { $storageVolume = Scalr_Storage_Volume::init(); try { $storageVolume->loadById($settings->volumeConfig->id); $storageVolume->setConfig($settings->volumeConfig); $storageVolume->save(); } catch (Exception $e) { if (strpos($e->getMessage(), 'not found')) { $storageVolume->loadBy(array('id' => $settings->volumeConfig->id, 'client_id' => $this->dbServer->clientId, 'env_id' => $this->dbServer->envId, 'name' => "'{$this->databaseType}' data volume", 'type' => $this->dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_ENGINE), 'platform' => $this->dbServer->platform, 'size' => $settings->volumeConfig->size, 'fstype' => $settings->volumeConfig->fstype, 'purpose' => $this->databaseType, 'farm_roleid' => $this->dbFarmRole->ID, 'server_index' => $this->dbServer->index)); $storageVolume->setConfig($settings->volumeConfig); $storageVolume->save(true); } else { throw $e; } } $this->dbFarmRole->SetSetting(Scalr_Db_Msr::VOLUME_ID, $storageVolume->id, DBFarmRole::TYPE_LCL); } catch (Exception $e) { $this->logger->error(new FarmLogMessage($this->dbServer->farmId, "Cannot save storage volume: {$e->getMessage()}")); } } if ($settings->snapshotConfig) { try { $storageSnapshot = Scalr_Model::init(Scalr_Model::STORAGE_SNAPSHOT); try { $storageSnapshot->loadById($settings->snapshotConfig->id); $storageSnapshot->setConfig($settings->snapshotConfig); $storageSnapshot->save(); } catch (Exception $e) { if (strpos($e->getMessage(), 'not found')) { $storageSnapshot->loadBy(array('id' => $settings->snapshotConfig->id, 'client_id' => $this->dbServer->clientId, 'farm_id' => $this->dbServer->farmId, 'farm_roleid' => $this->dbServer->farmRoleId, 'env_id' => $this->dbServer->envId, 'name' => sprintf(_("'{$this->databaseType}' data bundle #%s"), $settings->snapshotConfig->id), 'type' => $this->dbFarmRole->GetSetting(Scalr_Db_Msr::DATA_STORAGE_ENGINE), 'platform' => $this->dbServer->platform, 'description' => sprintf(_("'{$this->databaseType}' data bundle created on Farm '%s' -> Role '%s'"), $this->dbFarmRole->GetFarmObject()->name, $this->dbFarmRole->GetRoleObject()->name), 'service' => $this->databaseType)); $storageSnapshot->setConfig($settings->snapshotConfig); $storageSnapshot->save(true); } else { throw $e; } } $this->dbFarmRole->SetSetting(Scalr_Db_Msr::SNAPSHOT_ID, $storageSnapshot->id, DBFarmRole::TYPE_LCL); } catch (Exception $e) { $this->logger->error(new FarmLogMessage($event->DBServer->farmId, "Cannot save storage snapshot: {$e->getMessage()}")); } } }
public function onFarmSave(DBFarm $dbFarm, DBFarmRole $dbFarmRole) { $vpcId = $dbFarm->GetSetting(Entity\FarmSetting::EC2_VPC_ID); if (!$vpcId) { //REMOVE VPC RELATED SETTINGS return; } if ($dbFarmRole->GetSetting(self::ROLE_VPC_ROUTER_CONFIGURED) == 1) { // ALL OBJECTS ALREADY CONFIGURED return true; } $aws = $dbFarm->GetEnvironmentObject()->aws($dbFarmRole->CloudLocation); $niId = $dbFarmRole->GetSetting(self::ROLE_VPC_NID); // If there is no public IP allocate it and associate with NI $publicIp = $dbFarmRole->GetSetting(self::ROLE_VPC_IP); if ($niId && !$publicIp) { $filter = array(array('name' => AddressFilterNameType::networkInterfaceId(), 'value' => $niId)); $addresses = $aws->ec2->address->describe(null, null, $filter); $address = $addresses->get(0); $associate = false; if (!$address) { $address = $aws->ec2->address->allocate('vpc'); $associate = true; } $publicIp = $address->publicIp; if ($associate) { $associateAddressRequestData = new AssociateAddressRequestData(); $associateAddressRequestData->networkInterfaceId = $niId; $associateAddressRequestData->allocationId = $address->allocationId; $associateAddressRequestData->allowReassociation = true; //Associate PublicIP with NetworkInterface $aws->ec2->address->associate($associateAddressRequestData); } $dbFarmRole->SetSetting(self::ROLE_VPC_IP, $publicIp, Entity\FarmRoleSetting::TYPE_LCL); $dbFarmRole->SetSetting(self::ROLE_VPC_AID, $address->allocationId, Entity\FarmRoleSetting::TYPE_LCL); } $dbFarmRole->SetSetting(self::ROLE_VPC_ROUTER_CONFIGURED, 1, Entity\FarmRoleSetting::TYPE_LCL); }
public function onFarmTerminated(DBFarmRole $dbFarmRole) { $dbFarmRole->SetSetting(self::ROLE_CLUSTER_STATUS, "", DBFarmRole::TYPE_LCL); }
public function onFarmTerminated(DBFarmRole $dbFarmRole) { if (in_array($this->behavior, array(ROLE_BEHAVIORS::PERCONA, ROLE_BEHAVIORS::MYSQL2, ROLE_BEHAVIORS::MARIADB))) { $dbFarmRole->SetSetting(self::ROLE_NO_DATA_BUNDLE_FOR_SLAVES, 1, DBFarmRole::TYPE_LCL); } }
/** * @return DBFarmRole * @param DBRole $DBRole */ public function AddRole(DBRole $DBRole, $platform, $cloudLocation, $launchIndex) { $this->DB->Execute("INSERT INTO farm_roles SET \r\n\t\t\t\tfarmid=?, role_id=?, reboot_timeout=?, launch_timeout=?, status_timeout = ?, launch_index = ?, platform = ?, cloud_location=?", array($this->ID, $DBRole->id, 300, 300, 600, $launchIndex, $platform, $cloudLocation)); $farm_role_id = $this->DB->Insert_ID(); $DBFarmRole = new DBFarmRole($farm_role_id); $DBFarmRole->FarmID = $this->ID; $DBFarmRole->RoleID = $DBRole->id; $DBFarmRole->Platform = $platform; $DBFarmRole->CloudLocation = $cloudLocation; $default_settings = array(DBFarmRole::SETTING_SCALING_MIN_INSTANCES => 1, DBFarmRole::SETTING_SCALING_MAX_INSTANCES => 1, DBFarmRole::SETTING_SCALING_POLLING_INTERVAL => 2, DBFarmRole::SETTING_EXCLUDE_FROM_DNS => false, DBFarmRole::SETTING_BALANCING_USE_ELB => false, DBFarmRole::SETTING_AWS_AVAIL_ZONE => 'x-scalr-diff', DBFarmRole::SETTING_AWS_INSTANCE_TYPE => $DBRole->instanceType); foreach ($default_settings as $k => $v) { $DBFarmRole->SetSetting($k, $v); } return $DBFarmRole; }
/** * Adds a role to farm * * @param DBRole $DBRole The role object * @param string $platform The cloud platform * @param string $cloudLocation The cloud location * @param int $launchIndex Launch index * @param string $alias optional * @return DBFarmRole */ public function AddRole(DBRole $DBRole, $platform, $cloudLocation, $launchIndex, $alias = "") { if (empty($alias)) { $alias = $DBRole->name; } $this->DB->Execute("\n INSERT INTO farm_roles\n SET farmid=?,\n role_id=?,\n reboot_timeout=?,\n launch_timeout=?,\n status_timeout = ?,\n launch_index = ?,\n platform = ?,\n cloud_location=?,\n `alias` = ?\n ", [$this->ID, $DBRole->id, 300, 300, 600, $launchIndex, $platform, $cloudLocation, $alias]); $farm_role_id = $this->DB->Insert_ID(); $DBFarmRole = new DBFarmRole($farm_role_id); $DBFarmRole->FarmID = $this->ID; $DBFarmRole->RoleID = $DBRole->id; $DBFarmRole->Platform = $platform; $DBFarmRole->CloudLocation = $cloudLocation; $DBFarmRole->Alias = $alias; $default_settings = [Entity\FarmRoleSetting::SCALING_MIN_INSTANCES => 1, Entity\FarmRoleSetting::SCALING_MAX_INSTANCES => 1]; foreach ($default_settings as $k => $v) { $DBFarmRole->SetSetting($k, $v); } if ($farm_role_id && $DBFarmRole && \Scalr::getContainer()->analytics->enabled) { \Scalr::getContainer()->analytics->tags->syncValue($this->ClientID, \Scalr\Stats\CostAnalytics\Entity\TagEntity::TAG_ID_FARM_ROLE, $farm_role_id, sprintf('%s', $DBFarmRole->Alias)); } return $DBFarmRole; }
public function onFarmSave(DBFarm $dbFarm, DBFarmRole $dbFarmRole) { $vpcId = $dbFarm->GetSetting(DBFarm::SETTING_EC2_VPC_ID); if (!$vpcId) { //REMOVE VPC RELATED SETTINGS return; } if ($dbFarmRole->GetSetting(self::ROLE_VPC_ROUTER_CONFIGURED) == 1) { // ALL OBJECTS ALREADY CONFIGURED return true; } $aws = $dbFarm->GetEnvironmentObject()->aws($dbFarmRole->CloudLocation); $filter = array(array('name' => SubnetFilterNameType::vpcId(), 'value' => $vpcId), array('name' => SubnetFilterNameType::tagKey(), 'value' => 'scalr-sn-type'), array('name' => SubnetFilterNameType::tagValue(), 'value' => self::INTERNET_ACCESS_FULL)); // Try to find scalr FULL subnet $subnets = $aws->ec2->subnet->describe(null, $filter); if ($subnets->count() > 0) { $subnetId = $subnets->get(0)->subnetId; } if (!$subnetId) { $platform = PlatformFactory::NewPlatform(SERVER_PLATFORMS::EC2); $subnet = $platform->AllocateNewSubnet($aws->ec2, $vpcId, null); $subnetId = $subnet->subnetId; //ADD TAGS try { $subnet->createTags(array(array('key' => "scalr-id", 'value' => SCALR_ID), array('key' => "scalr-sn-type", 'value' => self::INTERNET_ACCESS_FULL), array('key' => "Name", 'value' => 'Scalr System Subnet'))); } catch (Exception $e) { } $routingTableId = $platform->getRoutingTable(self::INTERNET_ACCESS_FULL, $aws, null, $vpcId); //Associate Routing table with subnet $aws->ec2->routeTable->associate($routingTableId, $subnetId); } $niId = $dbFarmRole->GetSetting(self::ROLE_VPC_NID); if (!$niId) { //Create Network interface $createNetworkInterfaceRequestData = new CreateNetworkInterfaceRequestData($subnetId); // Check and create security group $filter = array(array('name' => SecurityGroupFilterNameType::groupName(), 'value' => array('SCALR-VPC')), array('name' => SecurityGroupFilterNameType::vpcId(), 'value' => $vpcId)); try { $list = $aws->ec2->securityGroup->describe(null, null, $filter); if ($list->count() > 0 && $list->get(0)->groupName == 'SCALR-VPC') { $sgId = $list->get(0)->groupId; } } catch (Exception $e) { throw new Exception("Cannot get list of security groups (1): {$e->getMessage()}"); } if (!$sgId) { $sgId = $aws->ec2->securityGroup->create('SCALR-VPC', 'System SG for Scalr VPC integration', $vpcId); $ipRangeList = new IpRangeList(); $ipRangeList->append(new IpRangeData('0.0.0.0/0')); $ipRangeListLocal = new IpRangeList(); $ipRangeListLocal->append(new IpRangeData('10.0.0.0/8')); $aws->ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 8008, 8013, $ipRangeList), new IpPermissionData('tcp', 80, 80, $ipRangeList), new IpPermissionData('tcp', 443, 443, $ipRangeList), new IpPermissionData('tcp', 0, 65535, $ipRangeListLocal), new IpPermissionData('udp', 0, 65535, $ipRangeListLocal)), $sgId); } $createNetworkInterfaceRequestData->setSecurityGroupId(array('groupId' => $sgId)); $networkInterface = $aws->ec2->networkInterface->create($createNetworkInterfaceRequestData); // Disable sourceDeskCheck $networkInterface->modifyAttribute(NetworkInterfaceAttributeType::sourceDestCheck(), 0); $niId = $networkInterface->networkInterfaceId; $dbFarmRole->SetSetting(self::ROLE_VPC_NID, $niId, DBFarmRole::TYPE_LCL); try { $networkInterface->createTags(array(array('key' => "scalr-id", 'value' => SCALR_ID), array('key' => "Name", 'value' => 'Scalr System ENI'))); } catch (Exception $e) { } } // If there is no public IP allocate it and associate with NI $publicIp = $dbFarmRole->GetSetting(self::ROLE_VPC_IP); if ($niId && !$publicIp) { $address = $aws->ec2->address->allocate('vpc'); $publicIp = $address->publicIp; $dbFarmRole->SetSetting(self::ROLE_VPC_IP, $publicIp, DBFarmRole::TYPE_LCL); $dbFarmRole->SetSetting(self::ROLE_VPC_AID, $address->allocationId, DBFarmRole::TYPE_LCL); $associateAddressRequestData = new AssociateAddressRequestData(); $associateAddressRequestData->networkInterfaceId = $niId; $associateAddressRequestData->allocationId = $address->allocationId; //Associate PublicIP with NetworkInterface $aws->ec2->address->associate($associateAddressRequestData); } $dbFarmRole->SetSetting(self::ROLE_VPC_ROUTER_CONFIGURED, 1, DBFarmRole::TYPE_LCL); }
public function setVolumeConfig($volumeConfig, DBFarmRole $dbFarmRole, DBServer $dbServer) { try { $storageVolume = Scalr_Storage_Volume::init(); try { $storageVolume->loadById($volumeConfig->id); $storageVolume->setConfig($volumeConfig); $storageVolume->save(); } catch (Exception $e) { if (strpos($e->getMessage(), 'not found')) { $storageVolume->loadBy(array('id' => $volumeConfig->id, 'client_id' => $dbFarmRole->GetFarmObject()->ClientID, 'env_id' => $dbFarmRole->GetFarmObject()->EnvID, 'name' => sprintf("'%s' data volume", $this->behavior), 'type' => $dbFarmRole->GetSetting(static::ROLE_DATA_STORAGE_ENGINE), 'platform' => $dbFarmRole->Platform, 'size' => $volumeConfig->size, 'fstype' => $volumeConfig->fstype, 'purpose' => $this->behavior, 'farm_roleid' => $dbFarmRole->ID, 'server_index' => $dbServer->index)); $storageVolume->setConfig($volumeConfig); $storageVolume->save(true); } else { throw $e; } } $dbFarmRole->SetSetting(static::ROLE_VOLUME_ID, $storageVolume->id, DBFarmRole::TYPE_LCL); } catch (Exception $e) { $this->logger->error(new FarmLogMessage($dbFarmRole->FarmID, "Cannot save storage volume: {$e->getMessage()}")); } }
private function performDbMsrAction($action, DBFarmRole $dbFarmRole, $tz) { $timeouted = false; if ($dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_ENABLED")) && $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_EVERY")) != 0) { if ($dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_IS_RUNNING")) == 1) { // Wait for timeout time * 2 (Example: NIVs problem with big mysql snapshots) // We must wait for running bundle process. $timeout = $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_EVERY")) * (3600 * 2); $lastTs = $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_RUNNING_TS")); if ($lastTs + $timeout < time()) { $timeouted = true; } if ($timeouted) { $dbFarmRole->SetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_IS_RUNNING"), 0, DBFarmRole::TYPE_LCL); } } else { /* * Check bundle window */ $period = $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_EVERY")); $timeout = $period * 3600; $lastActionTime = $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_LAST_TS")); $performAction = false; if ($period % 24 == 0) { if ($lastActionTime) { $days = $period / 24; $dateTime = new DateTime(null, new DateTimeZone($tz)); $currentDate = (int) $dateTime->format("Ymd"); $dateTime->setTimestamp(strtotime("+{$days} day", $lastActionTime)); $nextDate = (int) $dateTime->format("Ymd"); if ($nextDate > $currentDate) { return; } } $pbwFrom = (int) ($dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_TIMEFRAME_START_HH")) . $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_TIMEFRAME_START_MM"))); $pbwTo = (int) ($dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_TIMEFRAME_END_HH")) . $dbFarmRole->GetSetting(Scalr_Db_Msr::getConstant("DATA_{$action}_TIMEFRAME_END_MM"))); if ($pbwFrom && $pbwTo) { $dateTime = new DateTime(null, new DateTimeZone($tz)); $currentTime = (int) $dateTime->format("Hi"); //$current_time = (int)date("Hi"); //BUG HERE: 22:00 - 6:00 - doesn't work if ($pbwFrom <= $currentTime && $pbwTo >= $currentTime) { $performAction = true; } } else { $performAction = true; } } else { //Check timeout if ($lastActionTime + $timeout < time()) { $performAction = true; } } if ($performAction) { $behavior = Scalr_Role_Behavior::loadByName($dbFarmRole->GetRoleObject()->getDbMsrBehavior()); if ($action == 'BUNDLE') { $behavior->createDataBundle($dbFarmRole, array('compressor' => $dbFarmRole->GetSetting(Scalr_Role_DbMsrBehavior::ROLE_DATA_BUNDLE_COMPRESSION), 'useSlave' => $dbFarmRole->GetSetting(Scalr_Role_DbMsrBehavior::ROLE_DATA_BUNDLE_USE_SLAVE))); } if ($action == 'BACKUP') { $behavior->createBackup($dbFarmRole); } } } } }
public static function farmUpdateRoleSettings(DBFarmRole $DBFarmRole, $oldSettings, $newSettings) { $db = \Scalr::getDb(); $DBFarm = $DBFarmRole->GetFarmObject(); $DBFarmRole->SetSetting(DBFarmRole::SETTING_AWS_ELASIC_IPS_MAP, null, DBFarmRole::TYPE_LCL); $isVPC = $DBFarm->GetSetting(DBFarm::SETTING_EC2_VPC_ID); $aws = $DBFarm->GetEnvironmentObject()->aws($DBFarmRole->CloudLocation); // Disassociate IP addresses if checkbox was unchecked if (!$newSettings[DBFarmRole::SETTING_AWS_USE_ELASIC_IPS] && $oldSettings[DBFarmRole::SETTING_AWS_USE_ELASIC_IPS]) { $eips = $db->Execute("\n SELECT * FROM elastic_ips WHERE farm_roleid = ?\n ", array($DBFarmRole->ID)); while ($eip = $eips->FetchRow()) { try { $aws->ec2->address->disassociate($eip['ipaddress']); } catch (Exception $e) { } } $db->Execute("\n DELETE FROM elastic_ips\n WHERE farm_roleid = ?\n ", array($DBFarmRole->ID)); } //TODO: Handle situation when tab was not opened, but max instances setting was changed. if ($newSettings[DBFarmRole::SETTING_AWS_ELASIC_IPS_MAP] && $newSettings[DBFarmRole::SETTING_AWS_USE_ELASIC_IPS]) { $map = explode(";", $newSettings[DBFarmRole::SETTING_AWS_ELASIC_IPS_MAP]); foreach ($map as $ipconfig) { list($serverIndex, $ipAddress) = explode("=", $ipconfig); if (!$serverIndex) { continue; } try { $dbServer = DBServer::LoadByFarmRoleIDAndIndex($DBFarmRole->ID, $serverIndex); } catch (Exception $e) { } // Allocate new IP if needed if (!$ipAddress || $ipAddress == '0.0.0.0') { if ($dbServer) { $domain = $isVPC ? 'vpc' : null; $address = $aws->ec2->address->allocate($domain); $ipAddress = $address->publicIp; $allocationId = $address->allocationId; } else { continue; } } // Remove old association $db->Execute("\n DELETE FROM elastic_ips\n WHERE farm_roleid = ? AND instance_index=?\n ", array($DBFarmRole->ID, $serverIndex)); if ($ipAddress) { //Remove old IP association $db->Execute("\n DELETE FROM elastic_ips\n WHERE ipaddress=?\n ", array($ipAddress)); if (!$allocationId && $isVPC) { $allocationId = $aws->ec2->address->describe($ipAddress)->get(0)->allocationId; } // Associate IP with server in our db $db->Execute("\n INSERT INTO elastic_ips\n SET env_id=?,\n farmid=?,\n farm_roleid=?,\n ipaddress=?,\n state='0',\n instance_id='',\n clientid=?,\n instance_index=?,\n allocation_id=?\n ", array($DBFarm->EnvID, $DBFarmRole->FarmID, $DBFarmRole->ID, $ipAddress, $DBFarm->ClientID, $serverIndex, $allocationId)); // Associate IP on AWS with running server try { $dbServer = DBServer::LoadByFarmRoleIDAndIndex($DBFarmRole->ID, $serverIndex); $db->Execute("\n UPDATE elastic_ips\n SET state='1',\n server_id = ?\n WHERE ipaddress = ?\n ", array($dbServer->serverId, $ipAddress)); $update = false; if ($dbServer->remoteIp != $ipAddress) { if ($dbServer && $dbServer->status == SERVER_STATUS::RUNNING) { $fireEvent = self::associateIpAddress($dbServer, $ipAddress, $isVPC ? $allocationId : null); } } if ($fireEvent) { $event = new IPAddressChangedEvent($dbServer, $ipAddress, $dbServer->localIp); Scalr::FireEvent($dbServer->farmId, $event); } } catch (Exception $e) { } } else { Logger::getLogger(LOG_CATEGORY::FARM)->fatal(sprintf(_("Cannot allocate elastic ip address for instance %s on farm %s (2)"), $dbServer->serverId, $DBFarm->Name)); } } } }
public static function farmUpdateRoleSettings(DBFarmRole $DBFarmRole, $oldSettings, $newSettings) { //Conver OLD ELB settings into NEW ELB SETTINGS if ($newSettings[DBFarmRole::SETTING_BALANCING_USE_ELB] == 1 && !$newSettings[DBFarmRole::SETTING_AWS_ELB_ENABLED]) { $newSettings[DBFarmRole::SETTING_AWS_ELB_ENABLED] = 1; $newSettings[DBFarmRole::SETTING_AWS_ELB_ID] = $newSettings[DBFarmRole::SETTING_BALANCING_NAME]; $DBFarmRole->SetSetting(DBFarmRole::SETTING_AWS_ELB_ENABLED, 1, DBFarmRole::TYPE_CFG); $DBFarmRole->SetSetting(DBFarmRole::SETTING_AWS_ELB_ID, $newSettings[DBFarmRole::SETTING_BALANCING_NAME], DBFarmRole::TYPE_LCL); } //NEW ELB: try { $DBFarm = $DBFarmRole->GetFarmObject(); $elb = $DBFarm->GetEnvironmentObject()->aws($DBFarmRole)->elb; /* * aws.elb.enabled * aws.elb.id":"scalr-97f8a108ce4100-775", * aws.elb.remove */ if ($newSettings[DBFarmRole::SETTING_AWS_ELB_ENABLED]) { if ($oldSettings[DBFarmRole::SETTING_AWS_ELB_ID] == $newSettings[DBFarmRole::SETTING_AWS_ELB_ID]) { return true; } // Setup new service // ADD ELB to role_cloud_services $service = new FarmRoleService($DBFarmRole, $newSettings[DBFarmRole::SETTING_AWS_ELB_ID]); $service->setType(FarmRoleService::SERVICE_AWS_ELB); $service->save(); // Add running instances to ELB $servers = $DBFarmRole->GetServersByFilter(array('status' => SERVER_STATUS::RUNNING)); $newInstances = array(); foreach ($servers as $DBServer) { $newInstances[] = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID); } try { if (count($newInstances) > 0) { $elb->loadBalancer->registerInstances($newSettings[DBFarmRole::SETTING_AWS_ELB_ID], $newInstances); } } catch (Exception $e) { } try { //Check and deregister old instances instances $list = $elb->loadBalancer->describeInstanceHealth($newSettings[DBFarmRole::SETTING_AWS_ELB_ID], array()); /* @var $instance \Scalr\Service\Aws\Elb\DataType\InstanceStateData */ $instances = array(); foreach ($list as $instance) { if (!in_array($instance->instanceId, $newInstances)) { array_push($instances, $instance->instanceId); } } if (count($instances) > 0) { $elb->loadBalancer->deregisterInstances($newSettings[DBFarmRole::SETTING_AWS_ELB_ID], $instances); } } catch (Exception $e) { } } else { $clearSettings = true; } if ($newSettings['aws.elb.remove']) { if ($newSettings[DBFarmRole::SETTING_AWS_ELB_ID]) { $elb->loadBalancer->delete($newSettings[DBFarmRole::SETTING_AWS_ELB_ID]); } $clearSettings = true; } if ($clearSettings) { $DBFarmRole->ClearSettings("aws.elb."); $service = new FarmRoleService($DBFarmRole, $newSettings[DBFarmRole::SETTING_AWS_ELB_ID]); $service->remove(); } // Check and remove OLD ELB settings if ($newSettings['aws.elb.enabled'] && $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME)) { $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_NAME, null, DBFarmRole::TYPE_LCL); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME, null, DBFarmRole::TYPE_LCL); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_USE_ELB, null, DBFarmRole::TYPE_LCL); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH, null, DBFarmRole::TYPE_LCL); $DBFarmRole->ClearSettings("lb.avail_zone"); $DBFarmRole->ClearSettings("lb.healthcheck"); $DBFarmRole->ClearSettings("lb.role.listener"); } } catch (Exception $e) { throw new Exception("Error with ELB on Role '{$DBFarmRole->GetRoleObject()->name}': {$e->getMessage()}"); } //OLD ELB /* try { // Load balancer settings if ($newSettings[DBFarmRole::SETTING_BALANCING_USE_ELB] == 1) { // Listeners $DBFarmRole->ClearSettings("lb.role.listener"); $listenersList = new ListenerList(); $li = 0; foreach ($newSettings as $sk => $sv) { if (stristr($sk, "lb.role.listener")) { $li++; $listener_chunks = explode("#", $sv); $listenersList->append(new ListenerData( trim($listener_chunks[1]), trim($listener_chunks[2]), trim($listener_chunks[0]), null, trim($listener_chunks[3]) )); $DBFarmRole->SetSetting("lb.role.listener.{$li}", str_replace(" ", "", $sv)); } } $avail_zones = array(); $avail_zones_setting_hash = ""; foreach ($newSettings as $skey => $sval) { if (preg_match("/^lb.avail_zone.(.*)?$/", $skey, $macthes)) { if ($macthes[1] != 'hash' && $macthes[1] != '.hash') { if ($sval == 1) { array_push($avail_zones, $macthes[1]); } $avail_zones_setting_hash .= "[{$macthes[1]}:{$sval}]"; } } } if (!$DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME)) { $elb_name = sprintf("scalr-%s-%s", $DBFarm->Hash, rand(100,999)); //Creates a new ELB $elb_dns_name = $elb->loadBalancer->create($elb_name, $listenersList, $avail_zones); if (!empty($elb_dns_name)) { $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME, $elb_dns_name); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_NAME, $elb_name); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH, $avail_zones_setting_hash); $register_servers = true; } } if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME)) { $healthCheckType = new HealthCheckData(); $healthCheckType->target = $newSettings[DBFarmRole::SETTING_BALANCING_HC_TARGET]; $healthCheckType->healthyThreshold = $newSettings[DBFarmRole::SETTING_BALANCING_HC_HTH]; $healthCheckType->interval = $newSettings[DBFarmRole::SETTING_BALANCING_HC_INTERVAL]; $healthCheckType->timeout = $newSettings[DBFarmRole::SETTING_BALANCING_HC_TIMEOUT]; $healthCheckType->unhealthyThreshold = $newSettings[DBFarmRole::SETTING_BALANCING_HC_UTH]; $hash = md5(serialize(array( $healthCheckType->target, $healthCheckType->healthyThreshold, $healthCheckType->interval, $healthCheckType->timeout, $healthCheckType->unhealthyThreshold, ))); if ($elb_name || ($hash != $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH))) { //Updates current Elb $elb->loadBalancer->configureHealthCheck( $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $healthCheckType ); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH, $hash); } // Configure AVAIL zones for the LB if (!$elb_name && $avail_zones_setting_hash != $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH)) { $lb = $elb->loadBalancer->describe($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME))->get(0); $add_avail_zones = array(); $rem_avail_zones = array(); foreach ($newSettings as $skey => $sval) { if (preg_match("/^lb.avail_zone.(.*)?$/", $skey, $m)) { if ($sval == 1 && !in_array($m[1], $lb->availabilityZones)) { array_push($add_avail_zones, $m[1]); } if ($sval == 0 && in_array($m[1], $lb->availabilityZones)) { array_push($rem_avail_zones, $m[1]); } } } if (count($add_avail_zones) > 0) { $lb->enableAvailabilityZones($add_avail_zones); } if (count($rem_avail_zones) > 0) { $lb->disableAvailabilityZones($rem_avail_zones); } $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH, $avail_zones_setting_hash); } } if ($register_servers) { $servers = $DBFarmRole->GetServersByFilter(array('status' => SERVER_STATUS::RUNNING)); $instances = array(); foreach ($servers as $DBServer) { $instances[] = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID); } if (count($instances) > 0) { $elb->loadBalancer->registerInstances($elb_name, $instances); } } } else { if ($oldSettings[DBFarmRole::SETTING_BALANCING_HOSTNAME]) { try { $elb->loadBalancer->delete($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME)); } catch (Exception $e) { } $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_NAME, ""); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME, ""); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_USE_ELB, "0"); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH, ""); $DBFarmRole->ClearSettings("lb.avail_zone"); $DBFarmRole->ClearSettings("lb.healthcheck"); $DBFarmRole->ClearSettings("lb.role.listener"); } } } catch (Exception $e) { throw new Exception("Error with ELB on Role '{$DBFarmRole->GetRoleObject()->name}': {$e->getMessage()}"); } */ }
public static function farmUpdateRoleSettings(DBFarmRole $DBFarmRole, $oldSettings, $newSettings) { try { $DBFarm = $DBFarmRole->GetFarmObject(); $Client = Client::Load($DBFarm->ClientID); $AmazonELB = Scalr_Service_Cloud_Aws::newElb($DBFarmRole->CloudLocation, $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::ACCESS_KEY), $DBFarm->GetEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::SECRET_KEY)); // Load balancer settings if ($newSettings[DBFarmRole::SETTING_BALANCING_USE_ELB] == 1) { // Listeners $DBFarmRole->ClearSettings("lb.role.listener"); $ELBListenersList = new ELBListenersList(); $li = 0; foreach ($newSettings as $sk => $sv) { if (stristr($sk, "lb.role.listener")) { $li++; $listener_chunks = explode("#", $sv); $ELBListenersList->AddListener($listener_chunks[0], $listener_chunks[1], $listener_chunks[2], $listener_chunks[3]); $DBFarmRole->SetSetting("lb.role.listener.{$li}", $sv); } } $avail_zones = array(); $avail_zones_setting_hash = ""; foreach ($newSettings as $skey => $sval) { if (preg_match("/^lb.avail_zone.(.*)?\$/", $skey, $macthes)) { if ($macthes[1] != 'hash' && $macthes[1] != '.hash') { if ($sval == 1) { array_push($avail_zones, $macthes[1]); } $avail_zones_setting_hash .= "[{$macthes[1]}:{$sval}]"; } } } if (!$DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME)) { $elb_name = sprintf("scalr-%s-%s", $DBFarm->Hash, rand(100, 999)); //CREATE NEW ELB $elb_dns_name = $AmazonELB->CreateLoadBalancer($elb_name, $avail_zones, $ELBListenersList); if ($elb_dns_name) { $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME, $elb_dns_name); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_NAME, $elb_name); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH, $avail_zones_setting_hash); $register_servers = true; } } if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME)) { $ELBHealthCheckType = new ELBHealthCheckType($newSettings[DBFarmRole::SETTING_BALANCING_HC_TARGET], $newSettings[DBFarmRole::SETTING_BALANCING_HC_HTH], $newSettings[DBFarmRole::SETTING_BALANCING_HC_INTERVAL], $newSettings[DBFarmRole::SETTING_BALANCING_HC_TIMEOUT], $newSettings[DBFarmRole::SETTING_BALANCING_HC_UTH]); $hash = md5(serialize($ELBHealthCheckType)); if ($elb_name || $hash != $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH)) { //UPDATE CURRENT ELB $AmazonELB->ConfigureHealthCheck($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $ELBHealthCheckType); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH, $hash); } // Configure AVAIL zones for the LB if (!$elb_name && $avail_zones_setting_hash != $DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH)) { $info = $AmazonELB->DescribeLoadBalancers(array($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME))); $elb = $info->DescribeLoadBalancersResult->LoadBalancerDescriptions->member; $c = (array) $elb->AvailabilityZones; if (!is_array($c['member'])) { $c_zones = array($c['member']); } else { $c_zones = $c['member']; } $add_avail_zones = array(); $rem_avail_zones = array(); foreach ($newSettings as $skey => $sval) { if (preg_match("/^lb.avail_zone.(.*)?\$/", $skey, $m)) { if ($sval == 1 && !in_array($m[1], $c_zones)) { array_push($add_avail_zones, $m[1]); } if ($sval == 0 && in_array($m[1], $c_zones)) { array_push($rem_avail_zones, $m[1]); } } } if (count($add_avail_zones) > 0) { $AmazonELB->EnableAvailabilityZonesForLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $add_avail_zones); } if (count($rem_avail_zones) > 0) { $AmazonELB->DisableAvailabilityZonesForLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $rem_avail_zones); } $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_AZ_HASH, $avail_zones_setting_hash); } } if ($register_servers) { $servers = $DBFarmRole->GetServersByFilter(array('status' => SERVER_STATUS::RUNNING)); $instances = array(); foreach ($servers as $DBServer) { $instances[] = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID); } if (count($instances) > 0) { $AmazonELB->RegisterInstancesWithLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME), $instances); } } } else { if ($oldSettings[DBFarmRole::SETTING_BALANCING_HOSTNAME]) { try { $AmazonELB->DeleteLoadBalancer($DBFarmRole->GetSetting(DBFarmRole::SETTING_BALANCING_NAME)); } catch (Exception $e) { } $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_NAME, ""); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HOSTNAME, ""); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_USE_ELB, "0"); $DBFarmRole->SetSetting(DBFarmRole::SETTING_BALANCING_HC_HASH, ""); $DBFarmRole->ClearSettings("lb.avail_zone"); $DBFarmRole->ClearSettings("lb.healthcheck"); $DBFarmRole->ClearSettings("lb.role.listener"); } } } catch (Exception $e) { throw new Exception("Error with ELB on Role '{$DBFarmRole->GetRoleObject()->name}': {$e->getMessage()}"); } }
/** * @return DBFarmRole * @param DBRole $DBRole */ public function AddRole(DBRole $DBRole, $platform, $cloudLocation, $launchIndex, $alias = "") { if (empty($alias)) { $alias = $DBRole->name; } $this->DB->Execute("INSERT INTO farm_roles SET\n farmid=?, role_id=?, reboot_timeout=?, launch_timeout=?, status_timeout = ?,\n launch_index = ?, platform = ?, cloud_location=?, `alias` = ?", array($this->ID, $DBRole->id, 300, 300, 600, $launchIndex, $platform, $cloudLocation, $alias)); $farm_role_id = $this->DB->Insert_ID(); $DBFarmRole = new DBFarmRole($farm_role_id); $DBFarmRole->FarmID = $this->ID; $DBFarmRole->RoleID = $DBRole->id; $DBFarmRole->Platform = $platform; $DBFarmRole->CloudLocation = $cloudLocation; $DBFarmRole->Alias = $alias; $default_settings = array(DBFarmRole::SETTING_SCALING_MIN_INSTANCES => 1, DBFarmRole::SETTING_SCALING_MAX_INSTANCES => 1); foreach ($default_settings as $k => $v) { $DBFarmRole->SetSetting($k, $v); } return $DBFarmRole; }
public static function farmUpdateRoleSettings(DBFarmRole $dbFarmRole, $oldSettings, $newSettings) { $db = \Scalr::getDb(); $dbFarm = $dbFarmRole->GetFarmObject(); $dbFarmRole->SetSetting(DBFarmRole::SETIING_CLOUDSTACK_STATIC_NAT_MAP, null, DBFarmRole::TYPE_LCL); $platform = PlatformFactory::NewPlatform($dbFarmRole->Platform); $cs = Scalr_Service_Cloud_Cloudstack::newCloudstack($platform->getConfigVariable(Modules_Platforms_Cloudstack::API_URL, $dbFarm->GetEnvironmentObject()), $platform->getConfigVariable(Modules_Platforms_Cloudstack::API_KEY, $dbFarm->GetEnvironmentObject()), $platform->getConfigVariable(Modules_Platforms_Cloudstack::SECRET_KEY, $dbFarm->GetEnvironmentObject()), $dbFarmRole->Platform); // Disassociate IP addresses if checkbox was unchecked if (!$newSettings[DBFarmRole::SETIING_CLOUDSTACK_USE_STATIC_NAT] && $oldSettings[DBFarmRole::SETIING_CLOUDSTACK_USE_STATIC_NAT]) { $eips = $db->Execute("\n SELECT * FROM elastic_ips WHERE farm_roleid = ?\n ", array($dbFarmRole->ID)); while ($eip = $eips->FetchRow()) { try { $cs->disassociateIpAddress($eip['allocation_id']); } catch (Exception $e) { } } $db->Execute("DELETE FROM elastic_ips WHERE farm_roleid = ?", array($dbFarmRole->ID)); } //TODO: Handle situation when tab was not opened, but max instances setting was changed. if ($newSettings[DBFarmRole::SETIING_CLOUDSTACK_STATIC_NAT_MAP] && $newSettings[DBFarmRole::SETIING_CLOUDSTACK_USE_STATIC_NAT]) { $map = explode(";", $newSettings[DBFarmRole::SETIING_CLOUDSTACK_STATIC_NAT_MAP]); foreach ($map as $ipconfig) { list($serverIndex, $ipAddress) = explode("=", $ipconfig); if (!$serverIndex) { continue; } $dbServer = false; try { $dbServer = DBServer::LoadByFarmRoleIDAndIndex($dbFarmRole->ID, $serverIndex); if ($dbServer->remoteIp == $ipAddress) { continue; } // Remove old association $db->Execute("\n DELETE FROM elastic_ips WHERE farm_roleid = ? AND instance_index=?\n ", array($dbFarmRole->ID, $serverIndex)); } catch (Exception $e) { } // Allocate new IP if needed if (!$ipAddress || $ipAddress == '0.0.0.0') { if ($dbServer) { $ipAddress = self::setStaticNatForServer($dbServer); } else { continue; } } else { //Remove old IP association $db->Execute("\n DELETE FROM elastic_ips WHERE ipaddress=?\n ", array($ipAddress)); $info = $cs->listPublicIpAddresses(null, null, null, null, null, $ipAddress); $info = $info->publicipaddress[0]; // Associate IP with server in our db $db->Execute("INSERT INTO elastic_ips SET\n env_id=?,\n farmid=?,\n farm_roleid=?,\n ipaddress=?,\n state='0',\n instance_id='',\n clientid=?,\n instance_index=?,\n allocation_id=?\n ", array($dbFarm->EnvID, $dbFarmRole->FarmID, $dbFarmRole->ID, $ipAddress, $dbFarm->ClientID, $serverIndex, $info->id)); } $ipInfo = $db->GetRow("SELECT allocation_id FROM elastic_ips WHERE ipaddress = ? LIMIT 1", $ipAddress); // Associate IP on AWS with running server if ($dbServer) { try { $db->Execute("UPDATE elastic_ips SET state='1', server_id = ? WHERE ipaddress = ?", array($dbServer->serverId, $ipAddress)); $update = false; if ($dbServer->remoteIp != $ipAddress) { if ($dbServer && $dbServer->status == SERVER_STATUS::RUNNING) { $fireEvent = self::associateIpAddress($dbServer, $ipAddress, $ipInfo['allocation_id']); } } if ($fireEvent) { $event = new IPAddressChangedEvent($dbServer, $ipAddress, $dbServer->localIp); Scalr::FireEvent($dbServer->farmId, $event); } } catch (Exception $e) { } } } } }