private function GetServerSecurityGroupsList(DBServer $DBServer, \Scalr\Service\Aws\Ec2 $ec2, $vpcId = "", \Scalr_Governance $governance = null, $osFamily = null)
{
$retval = array();
$checkGroups = array();
$wildCardSgs = [];
$sgGovernance = false;
$allowAdditionalSgs = true;
$roleBuilderSgName = \Scalr::config('scalr.aws.security_group_name') . "-rb";
if ($governance && $DBServer->farmRoleId) {
$sgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS);
if ($osFamily == 'windows' && $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'windows')) {
$sgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'windows');
}
if ($sgs !== null) {
$governanceSecurityGroups = @explode(",", $sgs);
if (!empty($governanceSecurityGroups)) {
foreach ($governanceSecurityGroups as $sg) {
if ($sg != '') {
array_push($checkGroups, trim($sg));
if (strpos($sg, '*') !== false) {
array_push($wildCardSgs, trim($sg));
}
}
}
}
if (!empty($checkGroups)) {
$sgGovernance = true;
}
$allowAdditionalSgs = $governance->getValue(SERVER_PLATFORMS::EC2, \Scalr_Governance::AWS_SECURITY_GROUPS, 'allow_additional_sec_groups');
}
}
if (!$sgGovernance || $allowAdditionalSgs) {
if ($DBServer->farmRoleId != 0) {
$dbFarmRole = $DBServer->GetFarmRoleObject();
if ($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SECURITY_GROUPS_LIST) !== null) {
// New SG management
$sgs = @json_decode($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SECURITY_GROUPS_LIST));
if (!empty($sgs)) {
foreach ($sgs as $sg) {
if (stripos($sg, 'sg-') === 0) {
array_push($retval, $sg);
} else {
array_push($checkGroups, $sg);
}
}
}
} else {
// Old SG management
array_push($checkGroups, 'default');
array_push($checkGroups, \Scalr::config('scalr.aws.security_group_name'));
if (!$vpcId) {
array_push($checkGroups, "scalr-farm.{$DBServer->farmId}");
array_push($checkGroups, "scalr-role.{$DBServer->farmRoleId}");
}
$additionalSgs = trim($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_SG_LIST));
if ($additionalSgs) {
$sgs = explode(",", $additionalSgs);
if (!empty($sgs)) {
foreach ($sgs as $sg) {
$sg = trim($sg);
if (stripos($sg, 'sg-') === 0) {
array_push($retval, $sg);
} else {
array_push($checkGroups, $sg);
}
}
}
}
}
} else {
array_push($checkGroups, $roleBuilderSgName);
}
}
// No name based security groups, return only SG ids.
if (empty($checkGroups)) {
return $retval;
}
// Filter groups
$filter = array(array('name' => SecurityGroupFilterNameType::groupName(), 'value' => $checkGroups));
// If instance run in VPC, add VPC filter
if ($vpcId != '') {
$filter[] = array('name' => SecurityGroupFilterNameType::vpcId(), 'value' => $vpcId);
}
// Get filtered list of SG required by scalr;
try {
$list = $ec2->securityGroup->describe(null, null, $filter);
$sgList = array();
foreach ($list as $sg) {
/* @var $sg \Scalr\Service\Aws\Ec2\DataType\SecurityGroupData */
if ($vpcId == '' && !$sg->vpcId || $vpcId && $sg->vpcId == $vpcId) {
$sgList[$sg->groupName] = $sg->groupId;
}
}
unset($list);
} catch (Exception $e) {
throw new Exception("Cannot get list of security groups (1): {$e->getMessage()}");
}
foreach ($checkGroups as $groupName) {
// Check default SG
if ($groupName == 'default') {
array_push($retval, $sgList[$groupName]);
// Check Roles builder SG
} elseif ($groupName == $roleBuilderSgName) {
if (!isset($sgList[$groupName])) {
try {
$securityGroupId = $ec2->securityGroup->create($roleBuilderSgName, "Security group for Roles Builder", $vpcId);
$ipRangeList = new IpRangeList();
foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) {
$ipRangeList->append(new IpRangeData($ip));
}
sleep(2);
$ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 22, 22, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList)), $securityGroupId);
$sgList[$roleBuilderSgName] = $securityGroupId;
} catch (Exception $e) {
throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $roleBuilderSgName, $e->getMessage()));
}
}
array_push($retval, $sgList[$groupName]);
//Check scalr-farm.* security group
} elseif (stripos($groupName, 'scalr-farm.') === 0) {
if (!isset($sgList[$groupName])) {
try {
$securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmID N%s", $DBServer->farmId), $vpcId);
sleep(2);
$userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->keychain(SERVER_PLATFORMS::EC2)->properties[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID], null, $groupName));
$ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList)), $securityGroupId);
$sgList[$groupName] = $securityGroupId;
} catch (Exception $e) {
throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage()));
}
}
array_push($retval, $sgList[$groupName]);
//Check scalr-role.* security group
} elseif (stripos($groupName, 'scalr-role.') === 0) {
if (!isset($sgList[$groupName])) {
try {
$securityGroupId = $ec2->securityGroup->create($groupName, sprintf("Security group for FarmRoleID N%s on FarmID N%s", $DBServer->GetFarmRoleObject()->ID, $DBServer->farmId), $vpcId);
sleep(2);
// DB rules
$dbRules = $DBServer->GetFarmRoleObject()->GetRoleObject()->getSecurityRules();
$groupRules = array();
foreach ($dbRules as $rule) {
$groupRules[CryptoTool::hash($rule['rule'])] = $rule;
}
// Behavior rules
foreach (\Scalr_Role_Behavior::getListForFarmRole($DBServer->GetFarmRoleObject()) as $bObj) {
$bRules = $bObj->getSecurityRules();
foreach ($bRules as $r) {
if ($r) {
$groupRules[CryptoTool::hash($r)] = array('rule' => $r);
}
}
}
// Default rules
$userIdGroupPairList = new UserIdGroupPairList(new UserIdGroupPairData($DBServer->GetEnvironmentObject()->keychain(SERVER_PLATFORMS::EC2)->properties[Entity\CloudCredentialsProperty::AWS_ACCOUNT_ID], null, $groupName));
$rules = array(new IpPermissionData('tcp', 0, 65535, null, $userIdGroupPairList), new IpPermissionData('udp', 0, 65535, null, $userIdGroupPairList));
foreach ($groupRules as $rule) {
$group_rule = explode(":", $rule["rule"]);
$rules[] = new IpPermissionData($group_rule[0], $group_rule[1], $group_rule[2], new IpRangeData($group_rule[3]));
}
$ec2->securityGroup->authorizeIngress($rules, $securityGroupId);
$sgList[$groupName] = $securityGroupId;
} catch (Exception $e) {
throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage()));
}
}
array_push($retval, $sgList[$groupName]);
} elseif ($groupName == \Scalr::config('scalr.aws.security_group_name')) {
if (!isset($sgList[$groupName])) {
try {
$securityGroupId = $ec2->securityGroup->create($groupName, "Security rules needed by Scalr", $vpcId);
$ipRangeList = new IpRangeList();
foreach (\Scalr::config('scalr.aws.ip_pool') as $ip) {
$ipRangeList->append(new IpRangeData($ip));
}
// TODO: Open only FOR VPC ranges
$ipRangeList->append(new IpRangeData('10.0.0.0/8'));
sleep(2);
$ec2->securityGroup->authorizeIngress(array(new IpPermissionData('tcp', 3306, 3306, $ipRangeList), new IpPermissionData('tcp', 8008, 8013, $ipRangeList), new IpPermissionData('udp', 8014, 8014, $ipRangeList)), $securityGroupId);
$sgList[$groupName] = $securityGroupId;
} catch (Exception $e) {
throw new Exception(sprintf(_("Cannot create security group '%s': %s"), $groupName, $e->getMessage()));
}
}
array_push($retval, $sgList[$groupName]);
} else {
if (!isset($sgList[$groupName])) {
if (!in_array($groupName, $wildCardSgs)) {
throw new Exception(sprintf(_("Security group '%s' is not found"), $groupName));
} else {
$wildCardMatchedSgs = [];
$groupNamePattern = \Scalr_Governance::convertAsteriskPatternToRegexp($groupName);
foreach ($sgList as $sgGroupName => $sgGroupId) {
if (preg_match($groupNamePattern, $sgGroupName) === 1) {
array_push($wildCardMatchedSgs, $sgGroupId);
}
}
if (empty($wildCardMatchedSgs)) {
throw new Exception(sprintf(_("Security group matched to pattern '%s' is not found."), $groupName));
} else {
if (count($wildCardMatchedSgs) > 1) {
throw new Exception(sprintf(_("There are more than one Security group matched to pattern '%s' found."), $groupName));
} else {
array_push($retval, $wildCardMatchedSgs[0]);
}
}
}
} else {
array_push($retval, $sgList[$groupName]);
}
}
}
return $retval;
}