public async Task Validate()

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
            };
        }