in src/AWS.Deploy.Common/Recipes/Validation/OptionSettingItemValidators/SecurityGroupsInVpcValidator.cs [41:130]
public async Task<ValidationResult> Validate(object input, Recommendation recommendation, OptionSettingItem optionSettingItem)
{
if (string.IsNullOrEmpty(VpcId))
return ValidationResult.Failed($"The '{nameof(SecurityGroupsInVpcValidator)}' validator is missing the '{nameof(VpcId)}' configuration.");
var vpcId = "";
// The ECS Fargate recipes expose a separate radio button to select the default VPC which is mutually exclusive
// with specifying an explicit VPC Id. Because we give preference to "UseDefault" in the CDK project,
// we should do so here as well and validate the security groups against the default VPC if it's selected.
if (!string.IsNullOrEmpty(IsDefaultVpcOptionSettingId))
{
var isDefaultVpcOptionSetting = _optionSettingHandler.GetOptionSetting(recommendation, IsDefaultVpcOptionSettingId);
var shouldUseDefaultVpc = _optionSettingHandler.GetOptionSettingValue<bool>(recommendation, isDefaultVpcOptionSetting);
if (shouldUseDefaultVpc)
{
var vpc = await _awsResourceQueryer.GetDefaultVpc();
if (vpc != null)
{
vpcId = vpc.VpcId;
}
}
}
// If the "Use default?" option doesn't exist in the recipe, or it does and was false, or
// we failed to look up the default VPC, then use the explicity VPC Id
if (string.IsNullOrEmpty(vpcId))
{
var vpcIdSetting = _optionSettingHandler.GetOptionSetting(recommendation, VpcId);
vpcId = _optionSettingHandler.GetOptionSettingValue<string>(recommendation, vpcIdSetting);
}
if (string.IsNullOrEmpty(vpcId))
return ValidationResult.Failed("The VpcId setting is not set or is empty. Make sure to set the VPC Id first.");
var securityGroupIds = (await _awsResourceQueryer.DescribeSecurityGroups(vpcId)).Select(x => x.GroupId);
// The ASP.NET Fargate recipe uses a list of security groups
if (input?.TryDeserialize<SortedSet<string>>(out var inputList) ?? false)
{
var invalidSecurityGroups = new List<string>();
foreach (var securityGroup in inputList!)
{
if (!securityGroupIds.Contains(securityGroup))
invalidSecurityGroups.Add(securityGroup);
}
if (invalidSecurityGroups.Any())
{
return ValidationResult.Failed($"The selected security group(s) ({string.Join(", ", invalidSecurityGroups)}) " +
$"are invalid since they do not belong to the currently selected VPC {vpcId}.");
}
return ValidationResult.Valid();
}
// The Console ECS Fargate Service recipe uses a comma-separated string, which will fall through the TryDeserialize above
if (input is string)
{
// Security groups aren't required
if (string.IsNullOrEmpty(input.ToString()))
{
return ValidationResult.Valid();
}
var securityGroupList = input.ToString()?.Split(',') ?? new string[0];
var invalidSecurityGroups = new List<string>();
foreach (var securityGroup in securityGroupList)
{
if (!securityGroupIds.Contains(securityGroup))
invalidSecurityGroups.Add(securityGroup);
}
if (invalidSecurityGroups.Any())
{
return ValidationResult.Failed($"The selected security group(s) ({string.Join(", ", invalidSecurityGroups)}) " +
$"are invalid since they do not belong to the currently selected VPC {vpcId}.");
}
return ValidationResult.Valid();
}
return new ValidationResult
{
IsValid = securityGroupIds.Contains(input?.ToString()),
ValidationFailedMessage = ValidationFailedMessage
};
}