Пример #1
0
        public async Task <AWSCredentials> ResolveAWSCredentials(string profileName, string lastUsedProfileName)
        {
            AWSCredentials credentials;

            var chain = new CredentialProfileStoreChain();

            if (!string.IsNullOrEmpty(profileName))
            {
                if (chain.TryGetAWSCredentials(profileName, out credentials) &&
                    await CanLoadCredentials(credentials))
                {
                    _toolInteractiveService.WriteLine($"Configuring AWS Credentials from Profile {profileName}.");
                    return(credentials);
                }
            }

            if (!string.IsNullOrEmpty(lastUsedProfileName) &&
                chain.TryGetAWSCredentials(lastUsedProfileName, out credentials) &&
                await CanLoadCredentials(credentials))
            {
                _toolInteractiveService.WriteLine($"Configuring AWS Credentials with previous configured profile value {lastUsedProfileName}.");
                return(credentials);
            }

            try
            {
                credentials = FallbackCredentialsFactory.GetCredentials();

                if (await CanLoadCredentials(credentials))
                {
                    _toolInteractiveService.WriteLine("Configuring AWS Credentials using AWS SDK credential search.");
                    return(credentials);
                }
            }
            catch (AmazonServiceException)
            {
                // FallbackCredentialsFactory throws an exception if no credentials are found. Burying exception because if no credentials are found
                // we want to continue and ask the user to select a profile.
            }

            var sharedCredentials = new SharedCredentialsFile();

            if (sharedCredentials.ListProfileNames().Count == 0)
            {
                _toolInteractiveService.WriteErrorLine("Unable to resolve AWS credentials to access AWS.");
                throw new NoAWSCredentialsFoundException();
            }

            var consoleUtilities    = new ConsoleUtilities(_toolInteractiveService);
            var selectedProfileName = consoleUtilities.AskUserToChoose(sharedCredentials.ListProfileNames(), "Select AWS Credentials Profile", null);

            if (!chain.TryGetAWSCredentials(selectedProfileName, out credentials) ||
                !(await CanLoadCredentials(credentials)))
            {
                _toolInteractiveService.WriteErrorLine($"Unable to create AWS credentials for profile {selectedProfileName}.");
                throw new NoAWSCredentialsFoundException();
            }

            return(credentials);
        }
Пример #2
0
 private void PrintInvalidStackNameMessage()
 {
     _toolInteractiveService.WriteLine();
     _toolInteractiveService.WriteErrorLine(
         "Invalid stack name. A stack name can contain only alphanumeric characters (case-sensitive) and hyphens. " +
         "It must start with an alphabetic character and can't be longer than 128 characters");
 }
Пример #3
0
        private async Task <bool> CanDeleteAsync(string stackName)
        {
            var stack = await GetStackAsync(stackName);

            if (stack == null)
            {
                _interactiveService.WriteErrorLine($"Stack with name {stackName} does not exist.");
                return(false);
            }

            var canDelete = stack.Tags.Any(tag => tag.Key.Equals(CloudFormationIdentifierConstants.STACK_TAG));

            if (!canDelete)
            {
                _interactiveService.WriteErrorLine("Only stacks that were deployed with this tool can be deleted.");
            }

            return(canDelete);
        }
        public async Task ExecuteAsync(bool saveCdkProject)
        {
            // Ensure a .NET project can be found.
            ProjectDefinition project = null;

            try
            {
                project = new ProjectDefinition(_session.ProjectPath);
            }
            catch (ProjectFileNotFoundException ex)
            {
                var files = Directory.GetFiles(_session.ProjectPath, "*.sln");
                if (files.Any())
                {
                    _toolInteractiveService.WriteErrorLine($"This directory contains a solution file, but the tool requires a project file. Please run the tool from the directory that contains a .csproj/.fsproj or provide a path to the .csproj/.fsproj via --project-path flag.");
                }
                else
                {
                    _toolInteractiveService.WriteErrorLine($"A project was not found at the path {_session.ProjectPath}");
                }

                throw new FailedToFindDeployableTargetException(ex);
            }

            var orchestrator =
                new Orchestrator.Orchestrator(
                    _session,
                    _orchestratorInteractiveService,
                    _cdkProjectHandler,
                    _awsResourceQueryer,
                    _deploymentBundleHandler,
                    new[] { RecipeLocator.FindRecipeDefinitionsPath() });

            // Determine what recommendations are possible for the project.
            var recommendations = await orchestrator.GenerateDeploymentRecommendations();

            if (recommendations.Count == 0)
            {
                _toolInteractiveService.WriteLine(string.Empty);
                _toolInteractiveService.WriteErrorLine($"The project you are trying to deploy is currently not supported.");
                throw new FailedToGenerateAnyRecommendations();
            }

            // Look to see if there are any existing deployed applications using any of the compatible recommendations.
            var existingApplications = await orchestrator.GetExistingDeployedApplications(recommendations);

            _toolInteractiveService.WriteLine(string.Empty);

            string cloudApplicationName;

            if (existingApplications.Count == 0)
            {
                var title = "Name the AWS stack to deploy your application to" + Environment.NewLine +
                            "(A stack is a collection of AWS resources that you can manage as a single unit.)" + Environment.NewLine +
                            "--------------------------------------------------------------------------------";
                cloudApplicationName =
                    _consoleUtilities.AskUserForValue(
                        title,
                        GetDefaultApplicationName(project.ProjectPath),
                        allowEmpty: false);
            }
            else
            {
                var title = "Select the AWS stack to deploy your application to" + Environment.NewLine +
                            "(A stack is a collection of AWS resources that you can manage as a single unit.)";

                var userResponse = _consoleUtilities.AskUserToChooseOrCreateNew(existingApplications.Select(x => x.Name).ToList(), title, askNewName: true, defaultNewName: GetDefaultApplicationName(project.ProjectPath));
                cloudApplicationName = userResponse.SelectedOption ?? userResponse.NewName;
            }

            var existingCloudApplication = existingApplications.FirstOrDefault(x => string.Equals(x.Name, cloudApplicationName));

            Recommendation selectedRecommendation = null;

            _toolInteractiveService.WriteLine(string.Empty);
            // If using a previous deployment preset settings for deployment based on last deployment.
            if (existingCloudApplication != null)
            {
                var existingCloudApplicationMetadata = await orchestrator.LoadCloudApplicationMetadata(existingCloudApplication.Name);

                selectedRecommendation = recommendations.FirstOrDefault(x => string.Equals(x.Recipe.Id, existingCloudApplication.RecipeId, StringComparison.InvariantCultureIgnoreCase));
                selectedRecommendation.ApplyPreviousSettings(existingCloudApplicationMetadata.Settings);

                var header = $"Loading {existingCloudApplication.Name} settings:";

                _toolInteractiveService.WriteLine(header);
                _toolInteractiveService.WriteLine(new string('-', header.Length));
                var optionSettings =
                    selectedRecommendation
                    .Recipe
                    .OptionSettings
                    .Where(x =>
                {
                    if (!selectedRecommendation.IsOptionSettingDisplayable(x))
                    {
                        return(false);
                    }

                    var value = selectedRecommendation.GetOptionSettingValue(x);
                    if (value == null || value.ToString() == string.Empty || object.Equals(value, x.DefaultValue))
                    {
                        return(false);
                    }

                    return(true);
                })
                    .ToArray();

                foreach (var setting in optionSettings)
                {
                    DisplayOptionSetting(selectedRecommendation, setting, -1, optionSettings.Length, DisplayOptionSettingsMode.Readonly);
                }
            }
            else
            {
                selectedRecommendation = _consoleUtilities.AskToChooseRecommendation(recommendations);
            }

            // Apply the user enter project name to the recommendation so that any default settings based on project name are applied.
            selectedRecommendation.OverrideProjectName(cloudApplicationName);

            var systemCapabilities = await _session.SystemCapabilities;

            if (selectedRecommendation.Recipe.DeploymentType == DeploymentTypes.CdkProject &&
                !systemCapabilities.NodeJsMinVersionInstalled)
            {
                _toolInteractiveService.WriteErrorLine("The selected deployment option requires Node.js 10.3 or later, which was not detected.  Please install Node.js: https://nodejs.org/en/download/");
                throw new MissingNodeJsException();
            }

            if (selectedRecommendation.Recipe.DeploymentBundle == DeploymentBundleTypes.Container)
            {
                if (!systemCapabilities.DockerInfo.DockerInstalled)
                {
                    _toolInteractiveService.WriteErrorLine("The selected deployment option requires Docker, which was not detected. Please install and start the appropriate version of Docker for you OS: https://docs.docker.com/engine/install/");
                    throw new MissingDockerException();
                }

                if (!systemCapabilities.DockerInfo.DockerContainerType.Equals("linux", StringComparison.OrdinalIgnoreCase))
                {
                    _toolInteractiveService.WriteErrorLine("The deployment tool requires Docker to be running in linux mode. Please switch Docker to linux mode to continue.");
                    throw new DockerContainerTypeException();
                }
            }

            var deploymentBundleDefinition = orchestrator.GetDeploymentBundleDefinition(selectedRecommendation);

            var configurableOptionSettings = selectedRecommendation.Recipe.OptionSettings.Union(deploymentBundleDefinition.Parameters);

            await ConfigureDeployment(selectedRecommendation, configurableOptionSettings, false);

            var cloudApplication = new CloudApplication
            {
                Name = cloudApplicationName
            };

            if (!ConfirmDeployment(selectedRecommendation))
            {
                return;
            }

            await CreateDeploymentBundle(orchestrator, selectedRecommendation, cloudApplication);

            await orchestrator.DeployRecommendation(cloudApplication, selectedRecommendation);
        }
Пример #5
0
 public void LogErrorMessageLine(string?message)
 {
     _interactiveService.WriteErrorLine(message);
 }