Пример #1
0
        public Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var settingValue = _consoleUtilities
                               .AskUserForValue(
                string.Empty,
                recommendation.GetOptionSettingValue(optionSetting).ToString(),
                allowEmpty: true,
                resetValue: recommendation.GetOptionSettingDefaultValue <string>(optionSetting),
                // validators:
                publishArgs =>
                (publishArgs.Contains("-o ") || publishArgs.Contains("--output "))
                            ? "You must not include -o/--output as an additional argument as it is used internally."
                            : "",
                publishArgs =>
                (publishArgs.Contains("-c ") || publishArgs.Contains("--configuration ")
                            ? "You must not include -c/--configuration as an additional argument. You can set the build configuration in the advanced settings."
                            : ""),
                publishArgs =>
                (publishArgs.Contains("--self-contained") || publishArgs.Contains("--no-self-contained")
                            ? "You must not include --self-contained/--no-self-contained as an additional argument. You can set the self-contained property in the advanced settings."
                            : ""))
                               .ToString()
                               .Replace("\"", "\"\"");

            recommendation.DeploymentBundle.DotnetPublishAdditionalBuildArguments = settingValue;

            return(Task.FromResult <object>(settingValue));
        }
Пример #2
0
        public void CanBuildRehydratedOptionSettingsItem()
        {
            // ARRANGE
            var expectedValidator = new RequiredValidator
            {
                ValidationFailedMessage = "Custom Test Message"
            };

            var optionSettingItem = new OptionSettingItem("id", "name", "description")
            {
                Name       = "Test Item",
                Validators = new List <OptionSettingItemValidatorConfig>
                {
                    new OptionSettingItemValidatorConfig
                    {
                        ValidatorType = OptionSettingItemValidatorList.Required,
                        Configuration = expectedValidator
                    }
                }
            };

            var json = JsonConvert.SerializeObject(optionSettingItem, Formatting.Indented);

            var deserialized = JsonConvert.DeserializeObject <OptionSettingItem>(json);

            // ACT
            var validators = deserialized.BuildValidators();

            // ASSERT
            validators.Length.ShouldEqual(1);
            validators.First().ShouldBeType(expectedValidator.GetType());
            validators.OfType <RequiredValidator>().First().ValidationFailedMessage.ShouldEqual(expectedValidator.ValidationFailedMessage);
        }
Пример #3
0
        [InlineData("arn:aws:ecs:us-east-1:012345678910:fluster/test", false)] //fluster instead of cluster
        public void ClusterArnValidationTests(string value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            optionSettingItem.Validators.Add(GetRegexValidatorConfig("arn:[^:]+:ecs:[^:]*:[0-9]{12}:cluster/.+"));
            Validate(optionSettingItem, value, isValid);
        }
Пример #4
0
        public void DesiredCountValidationTests(int value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            optionSettingItem.Validators.Add(GetRangeValidatorConfig(1, 5000));
            Validate(optionSettingItem, value, isValid);
        }
Пример #5
0
        public void HasABindingForAllOptionSettingItemValidators()
        {
            // ARRANGE
            var allValidators = Enum.GetValues(typeof(OptionSettingItemValidatorList));

            var optionSettingItem = new OptionSettingItem("id", "name", "description")
            {
                Validators =
                    allValidators
                    .Cast <OptionSettingItemValidatorList>()
                    .Select(validatorType =>
                            new OptionSettingItemValidatorConfig
                {
                    ValidatorType = validatorType
                }
                            )
                    .ToList()
            };

            // ACT
            var validators = optionSettingItem.BuildValidators();

            // ASSERT
            validators.Length.ShouldEqual(allValidators.Length);
        }
Пример #6
0
        [InlineData("arn:aws:iam::1234567890124354:role/S3Access", false)] //invalid account ID
        public void RoleArnValidationTests(string value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            optionSettingItem.Validators.Add(GetRegexValidatorConfig("arn:.+:iam::[0-9]{12}:.+"));
            Validate(optionSettingItem, value, isValid);
        }
Пример #7
0
        [InlineData("arn:aws:elasticbeanstack:eu-west-1:123456789012:platform/MyPlatform", false)] //Typo elasticbeanstack instead of elasticbeanstalk
        public void ElasticBeanstalkPlatformArnValidationTest(string value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            optionSettingItem.Validators.Add(GetRegexValidatorConfig("arn:[^:]+:elasticbeanstalk:[^:]+:[^:]*:platform/.+"));
            Validate(optionSettingItem, value, isValid);
        }
        private async Task ConfigureDeployment(Recommendation recommendation, OptionSettingItem setting)
        {
            _toolInteractiveService.WriteLine(string.Empty);
            _toolInteractiveService.WriteLine($"{setting.Name}:");
            _toolInteractiveService.WriteLine($"{setting.Description}");

            var    currentValue = recommendation.GetOptionSettingValue(setting);
            object settingValue = null;

            if (setting.AllowedValues?.Count > 0)
            {
                var userInputConfig = new UserInputConfiguration <string>
                {
                    DisplaySelector = x => setting.ValueMapping[x],
                    DefaultSelector = x => x.Equals(currentValue),
                    CreateNew       = false
                };

                var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(setting.AllowedValues, string.Empty, userInputConfig);
                settingValue = userResponse.SelectedOption;

                // If they didn't change the value then don't store so we can rely on using the default in the recipe.
                if (Equals(settingValue, currentValue))
                {
                    return;
                }
            }
            else
            {
                if (setting.TypeHint.HasValue && _typeHintCommandFactory.GetCommand(setting.TypeHint.Value) is var typeHintCommand && typeHintCommand != null)
                {
                    settingValue = await typeHintCommand.Execute(recommendation, setting);
                }
Пример #9
0
        [InlineData(" 123 abc-456 ", false)] //leading and trailing space
        public void EC2KeyPairValidationTest(string value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            // It allows all ASCII characters but without leading and trailing spaces
            optionSettingItem.Validators.Add(GetRegexValidatorConfig("^(?! ).+(?<! )$"));
            Validate(optionSettingItem, value, isValid);
        }
Пример #10
0
        [InlineData("123*&$_abc_", false)] //invalid characters
        public void ECSServiceNameValidationTests(string value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            // Up to 255 letters (uppercase and lowercase), numbers, hyphens, and underscores are allowed.
            optionSettingItem.Validators.Add(GetRegexValidatorConfig("^([A-Za-z0-9_-]{1,255})$"));
            Validate(optionSettingItem, value, isValid);
        }
Пример #11
0
        [InlineData("abc/123/#", false)] // invalid character forward slash(/)
        public void ApplicationNameValidationTest(string value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            //can contain up to 100 Unicode characters, not including forward slash (/).
            optionSettingItem.Validators.Add(GetRegexValidatorConfig("^[^/]{1,100}$"));
            Validate(optionSettingItem, value, isValid);
        }
Пример #12
0
        [InlineData("-12-abc", false)] // invalid character leading hyphen (-)
        public void EnvironmentNameValidationTest(string value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            // Must be from 4 to 40 characters in length. The name can contain only letters, numbers, and hyphens.
            // It can't start or end with a hyphen.
            optionSettingItem.Validators.Add(GetRegexValidatorConfig("^[a-zA-Z0-9][a-zA-Z0-9-]{2,38}[a-zA-Z0-9]$"));
            Validate(optionSettingItem, value, isValid);
        }
Пример #13
0
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var currentValue = recommendation.GetOptionSettingValue(optionSetting);
            var keyPairs     = await _awsResourceQueryer.ListOfEC2KeyPairs();

            var userInputConfiguration = new UserInputConfiguration <KeyPairInfo>(
                kp => kp.KeyName,
                kp => kp.KeyName.Equals(currentValue)
                )
            {
                AskNewName   = true,
                EmptyOption  = true,
                CurrentValue = currentValue
            };

            var settingValue = "";

            while (true)
            {
                var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(keyPairs, "Select key pair to use:", userInputConfiguration);

                if (userResponse.IsEmpty)
                {
                    settingValue = "";
                    break;
                }
                else
                {
                    settingValue = userResponse.SelectedOption?.KeyName ?? userResponse.NewName ??
                                   throw new UserPromptForNameReturnedNullException("The user prompt for a new EC2 Key Pair name was null or empty.");
                }

                if (userResponse.CreateNew && !string.IsNullOrEmpty(userResponse.NewName))
                {
                    _toolInteractiveService.WriteLine(string.Empty);
                    _toolInteractiveService.WriteLine("You have chosen to create a new key pair.");
                    _toolInteractiveService.WriteLine("You are required to specify a directory to save the key pair private key.");

                    var answer = _consoleUtilities.AskYesNoQuestion("Do you want to continue?", "false");
                    if (answer == YesNo.No)
                    {
                        continue;
                    }

                    _toolInteractiveService.WriteLine(string.Empty);
                    _toolInteractiveService.WriteLine($"A new key pair will be created with the name {settingValue}.");

                    var keyPairDirectory = _consoleUtilities.AskForEC2KeyPairSaveDirectory(recommendation.ProjectPath);

                    await _awsResourceQueryer.CreateEC2KeyPair(settingValue, keyPairDirectory);
                }

                break;
            }

            return(settingValue ?? "");
        }
Пример #14
0
        [InlineData("vpc-ffffffffaaaabbbb12", false)] //suffix length greater than 17
        public void VpcIdValidationTests(string value, bool isValid)
        {
            var optionSettingItem = new OptionSettingItem("id", "name", "description");

            //must start with the \"vpc-\" prefix,
            //followed by either 8 or 17 characters consisting of digits and letters(lower-case) from a to f.
            optionSettingItem.Validators.Add(GetRegexValidatorConfig("^vpc-([0-9a-f]{8}|[0-9a-f]{17})$"));
            Validate(optionSettingItem, value, isValid);
        }
Пример #15
0
        public Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var answer = _consoleUtilities.AskYesNoQuestion(string.Empty, recommendation.GetOptionSettingValue <string>(optionSetting));

            recommendation.DeploymentBundle.DotnetPublishSelfContainedBuild = answer == YesNo.Yes;
            var result = answer == YesNo.Yes ? "true" : "false";

            return(Task.FromResult <object>(result));
        }
        public SetOptionSettingTests()
        {
            var projectPath     = SystemIOUtilities.ResolvePath("WebAppNoDockerFile");
            var engine          = new RecommendationEngine(new[] { RecipeLocator.FindRecipeDefinitionsPath() }, new Orchestrator.OrchestratorSession());
            var recommendations = engine.ComputeRecommendations(projectPath, new Dictionary <string, string>()).GetAwaiter().GetResult();

            _recommendation = recommendations.First(r => r.Recipe.Id == Constants.ASPNET_CORE_BEANSTALK_RECIPE_ID);

            _optionSetting = _recommendation.Recipe.OptionSettings.First(x => x.Id.Equals("EnvironmentType"));
        }
        public Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var settingValue =
                _consoleUtilities.AskUserForValue(
                    string.Empty,
                    recommendation.GetOptionSettingValue <string>(optionSetting),
                    allowEmpty: false,
                    resetValue: recommendation.GetOptionSettingDefaultValue <string>(optionSetting) ?? "");

            recommendation.DeploymentBundle.DotnetPublishBuildConfiguration = settingValue;
            return(Task.FromResult <object>(settingValue));
        }
        public Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var settingValue = _consoleUtilities
                               .AskUserForValue(
                string.Empty,
                recommendation.GetOptionSettingValue <string>(optionSetting),
                allowEmpty: true,
                resetValue: recommendation.GetOptionSettingDefaultValue <string>(optionSetting) ?? "",
                validators: executionDirectory => ValidateExecutionDirectory(executionDirectory));

            recommendation.DeploymentBundle.DockerExecutionDirectory = settingValue;
            return(Task.FromResult <object>(settingValue));
        }
Пример #19
0
        public void WhenValidatorTypeAndConfigurationHaveAMismatchThenValidatorTypeWins()
        {
            // ARRANGE
            var optionSettingItem = new OptionSettingItem("id", "name", "description")
            {
                Name       = "Test Item",
                Validators = new List <OptionSettingItemValidatorConfig>
                {
                    new OptionSettingItemValidatorConfig
                    {
                        ValidatorType = OptionSettingItemValidatorList.Regex,
                        // Required can only map to RequiredValidator, this setup doesn't make sense:
                        Configuration = new RangeValidator
                        {
                            Min = 1
                        }
                    }
                }
            };

            var json = JsonConvert.SerializeObject(optionSettingItem, Formatting.Indented);

            var deserialized = JsonConvert.DeserializeObject <OptionSettingItem>(json);

            Exception exception = null;

            IOptionSettingItemValidator[] validators = null;

            // ACT
            try
            {
                validators = deserialized.BuildValidators();
            }
            catch (Exception e)
            {
                exception = e;
            }

            // ASSERT
            exception.ShouldBeNull();

            // we have our built validator
            validators.ShouldNotBeNull();
            validators.Length.ShouldEqual(1);

            // things get a little odd, the type is correct,
            // but the output messages is going to be from the RangeValidator.
            validators.First().ShouldBeType <RegexValidator>();
            validators.OfType <RegexValidator>().First().ValidationFailedMessage.ShouldEqual(
                new RangeValidator().ValidationFailedMessage);
        }
        private void DisplayOptionSetting(Recommendation recommendation, OptionSettingItem optionSetting, int optionSettingNumber, int optionSettingsCount, DisplayOptionSettingsMode mode)
        {
            var value = recommendation.GetOptionSettingValue(optionSetting);

            Type typeHintResponseType = null;

            if (optionSetting.Type == OptionSettingValueType.Object)
            {
                var typeHintResponseTypeFullName = $"AWS.Deploy.CLI.TypeHintResponses.{optionSetting.TypeHint}TypeHintResponse";
                typeHintResponseType = Assembly.GetExecutingAssembly().GetType(typeHintResponseTypeFullName);
            }

            DisplayValue(recommendation, optionSetting, optionSettingNumber, optionSettingsCount, typeHintResponseType, mode);
        }
Пример #21
0
        public Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var settingValue = _consoleUtilities
                               .AskUserForValue(
                string.Empty,
                recommendation.GetOptionSettingValue <string>(optionSetting),
                allowEmpty: true,
                resetValue: recommendation.GetOptionSettingDefaultValue <string>(optionSetting) ?? "",
                validators: buildArgs => ValidateBuildArgs(buildArgs))
                               .ToString()
                               .Replace("\"", "\"\"");

            recommendation.DeploymentBundle.DockerBuildArgs = settingValue;
            return(Task.FromResult <object>(settingValue));
        }
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var currentValue             = recommendation.GetOptionSettingValue(optionSetting);
            var applicationOptionSetting = recommendation.GetOptionSetting(optionSetting.ParentSettingId);

            var applicationName = recommendation.GetOptionSettingValue(applicationOptionSetting) as string;
            var environments    = await _awsResourceQueryer.ListOfElasticBeanstalkEnvironments(_session, applicationName);

            var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(
                options: environments.Select(env => env.EnvironmentName),
                title: "Select Elastic Beanstalk environment to deploy to:",
                askNewName: true,
                defaultNewName: currentValue.ToString());

            return(userResponse.SelectedOption ?? userResponse.NewName);
        }
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var currentValue = recommendation.GetOptionSettingValue(optionSetting);
            var platformArns = await _awsResourceQueryer.GetElasticBeanstalkPlatformArns(_session);

            var userInputConfiguration = new UserInputConfiguration <PlatformSummary>
            {
                DisplaySelector = platform => $"{platform.PlatformBranchName} v{platform.PlatformVersion}",
                DefaultSelector = platform => platform.PlatformArn.Equals(currentValue),
                CreateNew       = false
            };

            var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(platformArns, "Select the Platform to use:", userInputConfiguration);

            return(userResponse.SelectedOption?.PlatformArn);
        }
Пример #24
0
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var loadBalancers = await _awsResourceQueryer.ListOfLoadBalancers(LoadBalancerTypeEnum.Application);

            var currentValue = recommendation.GetOptionSettingValue <string>(optionSetting);

            var userInputConfiguration = new UserInputConfiguration <LoadBalancer>(
                loadBalancer => loadBalancer.LoadBalancerName,
                loadBalancer => loadBalancer.LoadBalancerArn.Equals(currentValue))
            {
                AskNewName = false
            };

            var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(loadBalancers, "Select Load Balancer to deploy to:", userInputConfiguration);

            return(userResponse.SelectedOption?.LoadBalancerArn ?? string.Empty);
        }
Пример #25
0
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var typeHintData  = optionSetting.GetTypeHintData <IAMRoleTypeHintData>();
            var existingRoles = await _awsResourceQueryer.ListOfIAMRoles(typeHintData?.ServicePrincipal);

            var currentTypeHintResponse = recommendation.GetOptionSettingValue <IAMRoleTypeHintResponse>(optionSetting);

            var userInputConfiguration = new UserInputConfiguration <Role>(
                role => role.RoleName,
                role => currentTypeHintResponse.RoleArn?.Equals(role.Arn) ?? false);

            var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(existingRoles, "Select an IAM role", userInputConfiguration);

            return(new IAMRoleTypeHintResponse
            {
                CreateNew = userResponse.CreateNew,
                RoleArn = userResponse.SelectedOption?.Arn
            });
        }
Пример #26
0
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var currentVpcTypeHintResponse = optionSetting.GetTypeHintData <VpcTypeHintResponse>();

            var vpcs = await _awsResourceQueryer.GetListOfVpcs(_session);

            var userInputConfig = new UserInputConfiguration <Vpc>
            {
                DisplaySelector = vpc =>
                {
                    var name     = vpc.Tags?.FirstOrDefault(x => x.Key == "Name")?.Value ?? string.Empty;
                    var namePart =
                        string.IsNullOrEmpty(name)
                            ? ""
                            : $" ({name}) ";

                    var isDefaultPart =
                        vpc.IsDefault
                            ? " *** Account Default VPC ***"
                            : "";

                    return($"{vpc.VpcId}{namePart}{isDefaultPart}");
                },
                DefaultSelector = vpc =>
                                  !string.IsNullOrEmpty(currentVpcTypeHintResponse?.VpcId)
                        ? vpc.VpcId == currentVpcTypeHintResponse.VpcId
                        : vpc.IsDefault
            };

            var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(
                vpcs,
                "Select a VPC",
                userInputConfig);

            return(new VpcTypeHintResponse
            {
                IsDefault = userResponse.SelectedOption?.IsDefault == true,
                CreateNew = userResponse.CreateNew,
                VpcId = userResponse.SelectedOption?.VpcId ?? ""
            });
        }
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var clusters = await _awsResourceQueryer.ListOfECSClusters();

            var currentTypeHintResponse = recommendation.GetOptionSettingValue <ECSClusterTypeHintResponse>(optionSetting);

            var userInputConfiguration = new UserInputConfiguration <Cluster>(
                cluster => cluster.ClusterName,
                cluster => cluster.ClusterArn.Equals(currentTypeHintResponse?.ClusterArn),
                currentTypeHintResponse.NewClusterName)
            {
                AskNewName = true
            };

            var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(clusters, "Select ECS cluster to deploy to:", userInputConfiguration);

            return(new ECSClusterTypeHintResponse(
                       userResponse.CreateNew,
                       userResponse.SelectedOption?.ClusterArn ?? string.Empty,
                       userResponse.NewName ?? string.Empty));
        }
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var applications = await _awsResourceQueryer.ListOfElasticBeanstalkApplications();

            var currentTypeHintResponse = recommendation.GetOptionSettingValue <BeanstalkApplicationTypeHintResponse>(optionSetting);

            var userInputConfiguration = new UserInputConfiguration <ApplicationDescription>(
                app => app.ApplicationName,
                app => app.ApplicationName.Equals(currentTypeHintResponse?.ApplicationName),
                currentTypeHintResponse.ApplicationName)
            {
                AskNewName = true,
            };

            var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(applications, "Select Elastic Beanstalk application to deploy to:", userInputConfiguration);

            return(new BeanstalkApplicationTypeHintResponse(
                       userResponse.CreateNew,
                       userResponse.SelectedOption?.ApplicationName ?? userResponse.NewName
                       ?? throw new UserPromptForNameReturnedNullException("The user response for a new application name was null.")
                       ));
        }
        public async Task <object> Execute(Recommendation recommendation, OptionSettingItem optionSetting)
        {
            var applications = await _awsResourceQueryer.ListOfElasticBeanstalkApplications(_session);

            var currentTypeHintResponse = recommendation.GetOptionSettingValue <BeanstalkApplicationTypeHintResponse>(optionSetting);

            var userInputConfiguration = new UserInputConfiguration <ApplicationDescription>
            {
                DisplaySelector = app => app.ApplicationName,
                DefaultSelector = app => app.ApplicationName.Equals(currentTypeHintResponse?.ApplicationName),
                AskNewName      = true,
                DefaultNewName  = currentTypeHintResponse.ApplicationName
            };

            var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(applications, "Select Elastic Beanstalk application to deploy to:", userInputConfiguration);

            return(new BeanstalkApplicationTypeHintResponse
            {
                CreateNew = userResponse.CreateNew,
                ApplicationName = userResponse.SelectedOption?.ApplicationName ?? userResponse.NewName
            });
        }
Пример #30
0
        public SetOptionSettingTests()
        {
            var projectPath = SystemIOUtilities.ResolvePath("WebAppNoDockerFile");

            var parser         = new ProjectDefinitionParser(new FileManager(), new DirectoryManager());
            var awsCredentials = new Mock <AWSCredentials>();
            var session        = new OrchestratorSession(
                parser.Parse(projectPath).Result,
                awsCredentials.Object,
                "us-west-2",
                "123456789012")
            {
                AWSProfileName = "default"
            };

            var engine          = new RecommendationEngine(new[] { RecipeLocator.FindRecipeDefinitionsPath() }, session);
            var recommendations = engine.ComputeRecommendations().GetAwaiter().GetResult();

            _recommendation = recommendations.First(r => r.Recipe.Id == Constants.ASPNET_CORE_BEANSTALK_RECIPE_ID);

            _optionSetting = _recommendation.Recipe.OptionSettings.First(x => x.Id.Equals("EnvironmentType"));
        }