Converts astrisk(*) pattern to regular expression
public static convertAsteriskPatternToRegexp ( string $pattern ) : string | ||
$pattern | string | Pattern with asterisk |
return | string | Regular expression |
/** * Prepare governance security groups patterns * @param string $list List of security groups, separated by comma * @return Array Security groups patterns */ public static function prepareSecurityGroupsPatterns($list) { $result = []; if (!empty($list)) { $sgs = explode(',', $list); foreach ($sgs as $sg) { $sg = trim($sg); if (!empty($sg)) { $pattern = ['value' => $sg]; if (strpos($sg, '*') !== false) { $pattern['regexp'] = \Scalr_Governance::convertAsteriskPatternToRegexp($sg); } $result[strtolower($sg)] = $pattern; } } } return $result; }
/** * Gets default vpc security group list * * @param SecurityGroupList $sgList * @param string $vpcId * @param string $serviceName Service name (rds, elb ...) * @return array */ private function getDefaultSgRow($sgList, $vpcId, $serviceName = null) { $governance = new Scalr_Governance($this->getEnvironmentId()); $governanceSecurityGroups = $governance->getValue(SERVER_PLATFORMS::EC2, Scalr_Governance::getEc2SecurityGroupPolicyNameForService($serviceName), null); $vpcSgList = []; $sgDefaultNames = []; $wildCardSgDefaultNames = []; $defaultSecurityGroups = []; foreach ($sgList as $sg) { if ($sg->vpcId == $vpcId) { $vpcSgList[$sg->groupName] = $sg->groupId; } } if (!empty($governanceSecurityGroups['value'])) { $sgs = explode(',', $governanceSecurityGroups['value']); foreach ($sgs as $sg) { if ($sg != '') { array_push($sgDefaultNames, trim($sg)); if (strpos($sg, '*') !== false) { array_push($wildCardSgDefaultNames, trim($sg)); } } } unset($sgs); } if (!empty($sgDefaultNames)) { $foundVpcSgNames = []; foreach ($sgDefaultNames as $groupName) { if (!isset($vpcSgList[$groupName])) { if (in_array($groupName, $wildCardSgDefaultNames)) { $wildCardMatchedSgs = []; $groupNamePattern = \Scalr_Governance::convertAsteriskPatternToRegexp($groupName); foreach ($vpcSgList as $sgGroupName => $sgGroupId) { if (preg_match($groupNamePattern, $sgGroupName) === 1) { array_push($wildCardMatchedSgs, $sgGroupName); } } if (count($wildCardMatchedSgs) == 1) { $defaultSecurityGroups[] = ['securityGroupId' => $vpcSgList[$wildCardMatchedSgs[0]], 'securityGroupName' => $wildCardMatchedSgs[0]]; } else { $defaultSecurityGroups[] = ['securityGroupId' => null, 'securityGroupName' => $groupName]; } $foundVpcSgNames[] = $groupName; } } else { $defaultSecurityGroups[] = ['securityGroupId' => $vpcSgList[$groupName], 'securityGroupName' => $groupName]; $foundVpcSgNames[] = $groupName; } } $missingSgs = array_diff($sgDefaultNames, $foundVpcSgNames); foreach ($missingSgs as $missingSg) { $defaultSecurityGroups[] = ['securityGroupId' => null, 'securityGroupName' => $missingSg]; } } elseif (isset($vpcSgList['default']) && empty($governanceSecurityGroups)) { $defaultSecurityGroups[] = ['securityGroupId' => $vpcSgList['default'], 'securityGroupName' => 'default']; } return $defaultSecurityGroups; }
/** * Gets the list of the security groups for the specified db server. * * If server does not have required security groups this method will create them. * * @param DBServer $DBServer The DB Server instance * @param \Scalr\Service\Aws\Ec2 $ec2 Ec2 Client instance * @param string $vpcId optional The ID of VPC * @param \Scalr_Governance $governance Governance * @param string $osFamily optional OS family of the instance * @return array Returns array looks like array(groupid-1, groupid-2, ..., groupid-N) */ 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; }