Skip to content

Commit

Permalink
Merge pull request #269 from aws/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
philasmar authored Jul 26, 2021
2 parents cc7cbcf + 1a9cc33 commit 28e6e39
Show file tree
Hide file tree
Showing 41 changed files with 1,197 additions and 119 deletions.
13 changes: 13 additions & 0 deletions .chglog/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,20 @@ options:
- build
- ci
- chore
sort_by: Subject
commit_groups:
sort_by: Custom
title_order:
- feat
- fix
- docs
- style
- refactor
- perf
- test
- build
- ci
- chore
title_maps:
feat: Features
fix: Bug Fixes
Expand Down
85 changes: 84 additions & 1 deletion src/AWS.Deploy.CLI/Commands/CommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
using AWS.Deploy.Orchestration.Data;
using AWS.Deploy.Orchestration.Utilities;
using AWS.Deploy.CLI.Commands.CommandHandlerInput;
using AWS.Deploy.Common.IO;
using AWS.Deploy.Common.DeploymentManifest;

namespace AWS.Deploy.CLI.Commands
{
Expand All @@ -32,6 +34,8 @@ public class CommandFactory : ICommandFactory
private static readonly Option<bool> _optionDiagnosticLogging = new(new []{"-d", "--diagnostics"}, "Enable diagnostic output.");
private static readonly Option<string> _optionApply = new("--apply", "Path to the deployment settings file to be applied.");
private static readonly Option<bool> _optionDisableInteractive = new(new []{"-s", "--silent" }, "Disable interactivity to deploy without any prompts for user input.");
private static readonly Option<string> _optionOutputDirectory = new(new[]{"-o", "--output"}, "Directory path in which the CDK deployment project will be saved.");
private static readonly Option<string> _optionProjectDisplayName = new(new[] { "--project-display-name" }, "The name of the deployment project that will be displayed in the list of available deployment options.");

private readonly IToolInteractiveService _toolInteractiveService;
private readonly IOrchestratorInteractiveService _orchestratorInteractiveService;
Expand All @@ -49,6 +53,7 @@ public class CommandFactory : ICommandFactory
private readonly IDeployedApplicationQueryer _deployedApplicationQueryer;
private readonly ITypeHintCommandFactory _typeHintCommandFactory;
private readonly IConsoleUtilities _consoleUtilities;
private readonly IDeploymentManifestEngine _deploymentManifestEngine;

public CommandFactory(
IToolInteractiveService toolInteractiveService,
Expand All @@ -66,7 +71,8 @@ public CommandFactory(
ITemplateMetadataReader templateMetadataReader,
IDeployedApplicationQueryer deployedApplicationQueryer,
ITypeHintCommandFactory typeHintCommandFactory,
IConsoleUtilities consoleUtilities)
IConsoleUtilities consoleUtilities,
IDeploymentManifestEngine deploymentManifestEngine)
{
_toolInteractiveService = toolInteractiveService;
_orchestratorInteractiveService = orchestratorInteractiveService;
Expand All @@ -84,6 +90,7 @@ public CommandFactory(
_deployedApplicationQueryer = deployedApplicationQueryer;
_typeHintCommandFactory = typeHintCommandFactory;
_consoleUtilities = consoleUtilities;
_deploymentManifestEngine = deploymentManifestEngine;
}

public Command BuildRootCommand()
Expand All @@ -98,6 +105,7 @@ public Command BuildRootCommand()
rootCommand.Add(BuildDeployCommand());
rootCommand.Add(BuildListCommand());
rootCommand.Add(BuildDeleteCommand());
rootCommand.Add(BuildDeploymentProjectCommand());
rootCommand.Add(BuildServerModeCommand());

return rootCommand;
Expand Down Expand Up @@ -307,6 +315,81 @@ private Command BuildListCommand()
return listCommand;
}

/// <summary>
/// Builds the top level command called "deployment-project" which supports the creation and saving of the
/// CDK deployment project.
/// </summary>
/// <returns>An instance of the <see cref="Command"/> class</returns>
private Command BuildDeploymentProjectCommand()
{
var deploymentProjectCommand = new Command("deployment-project",
"Save the deployment project inside a user provided directory path.");

var generateDeploymentProjectCommand = new Command("generate",
"Save the deployment project inside a user provided directory path without proceeding with a deployment")
{
_optionOutputDirectory,
_optionDiagnosticLogging,
_optionProjectPath,
_optionProjectDisplayName
};

generateDeploymentProjectCommand.Handler = CommandHandler.Create(async (GenerateDeploymentProjectCommandHandlerInput input) =>
{
try
{
_toolInteractiveService.Diagnostics = input.Diagnostics;
var projectDefinition = await _projectParserUtility.Parse(input.ProjectPath ?? "");

var saveDirectory = input.Output ?? "";
var projectDisplayName = input.ProjectDisplayName ?? "";

OrchestratorSession session = new OrchestratorSession(projectDefinition);

var targetApplicationFullPath = new DirectoryManager().GetDirectoryInfo(projectDefinition.ProjectPath).FullName;

var generateDeploymentProject = new GenerateDeploymentProjectCommand(
_toolInteractiveService,
_consoleUtilities,
_cdkProjectHandler,
_commandLineWrapper,
new DirectoryManager(),
new FileManager(),
session,
_deploymentManifestEngine,
targetApplicationFullPath);

await generateDeploymentProject.ExecuteAsync(saveDirectory, projectDisplayName);

return CommandReturnCodes.SUCCESS;
}
catch (Exception e) when (e.IsAWSDeploymentExpectedException())
{
if (input.Diagnostics)
_toolInteractiveService.WriteErrorLine(e.PrettyPrint());
else
{
_toolInteractiveService.WriteErrorLine(string.Empty);
_toolInteractiveService.WriteErrorLine(e.Message);
}
// bail out with an non-zero return code.
return CommandReturnCodes.USER_ERROR;
}
catch (Exception e)
{
// This is a bug
_toolInteractiveService.WriteErrorLine(
"Unhandled exception. This is a bug. Please copy the stack trace below and file a bug at https://github.com/aws/aws-dotnet-deploy. " +
e.PrettyPrint());

return CommandReturnCodes.UNHANDLED_EXCEPTION;
}
});

deploymentProjectCommand.Add(generateDeploymentProjectCommand);
return deploymentProjectCommand;
}

private Command BuildServerModeCommand()
{
var serverModeCommand = new Command(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

namespace AWS.Deploy.CLI.Commands.CommandHandlerInput
{
/// <summary>
/// This class maps the command line options for the "deployment-project generate" command to the appropriate C# properties.
/// </summary>
public class GenerateDeploymentProjectCommandHandlerInput
{
public string? ProjectPath { get; set; }
public bool Diagnostics { get; set; }
public string? Output { get; set; }
public string? ProjectDisplayName { get; set; }
}
}
30 changes: 10 additions & 20 deletions src/AWS.Deploy.CLI/Commands/DeployCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,11 @@ public async Task ConfigureDeployment(CloudApplication cloudApplication, Orchest
// Apply the user entered project name to the recommendation so that any default settings based on project name are applied.
selectedRecommendation.OverrideProjectName(cloudApplication.Name);

var deploymentBundleDefinition = orchestrator.GetDeploymentBundleDefinition(selectedRecommendation);

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

if (userDeploymentSettings != null)
{
ConfigureDeploymentFromConfigFile(selectedRecommendation, deploymentBundleDefinition, userDeploymentSettings);
ConfigureDeploymentFromConfigFile(selectedRecommendation, userDeploymentSettings);
}

if (!_toolInteractiveService.DisableInteractive)
Expand Down Expand Up @@ -215,7 +213,7 @@ private async Task<Recommendation> GetSelectedRecommendationFromPreviousDeployme
" does not match the original recipe used to deploy the application stack.");
}

selectedRecommendation.ApplyPreviousSettings(existingCloudApplicationMetadata.Settings);
selectedRecommendation = selectedRecommendation.ApplyPreviousSettings(existingCloudApplicationMetadata.Settings);

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

Expand Down Expand Up @@ -250,23 +248,16 @@ private async Task<Recommendation> GetSelectedRecommendationFromPreviousDeployme
/// This method is used to set the values for Option Setting Items when a deployment is being performed using a user specifed config file.
/// </summary>
/// <param name="recommendation">The selected recommendation settings used for deployment <see cref="Recommendation"/></param>
/// <param name="deploymentBundleDefinition">The container for the deployment bundle used by an application. <see cref="DeploymentBundleDefinition"/></param>
/// <param name="userDeploymentSettings">The deserialized object from the user provided config file. <see cref="UserDeploymentSettings"/></param>
private void ConfigureDeploymentFromConfigFile(Recommendation recommendation, DeploymentBundleDefinition deploymentBundleDefinition, UserDeploymentSettings userDeploymentSettings)
private void ConfigureDeploymentFromConfigFile(Recommendation recommendation, UserDeploymentSettings userDeploymentSettings)
{
foreach (var entry in userDeploymentSettings.LeafOptionSettingItems)
{
var optionSettingJsonPath = entry.Key;
var optionSettingValue = entry.Value;

var isPartOfDeploymentBundle = true;
var optionSetting = deploymentBundleDefinition.Parameters.FirstOrDefault(x => x.Id.Equals(optionSettingJsonPath));
if (optionSetting == null)
{
optionSetting = recommendation.GetOptionSetting(optionSettingJsonPath);
isPartOfDeploymentBundle = false;
}

var optionSetting = recommendation.GetOptionSetting(optionSettingJsonPath);

if (!recommendation.IsExistingCloudApplication || optionSetting.Updatable)
{
object settingValue;
Expand All @@ -291,11 +282,10 @@ private void ConfigureDeploymentFromConfigFile(Recommendation recommendation, De
{
throw new InvalidOverrideValueException($"Invalid value {optionSettingValue} for option setting item {optionSettingJsonPath}");
}

optionSetting.SetValueOverride(settingValue);

if (isPartOfDeploymentBundle)
SetDeploymentBundleOptionSetting(recommendation, optionSetting.Id, settingValue);
SetDeploymentBundleOptionSetting(recommendation, optionSetting.Id, settingValue);
}
}

Expand Down Expand Up @@ -341,7 +331,7 @@ private void SetDeploymentBundleOptionSetting(Recommendation recommendation, str
new DotnetPublishSelfContainedBuildCommand(_consoleUtilities).OverrideValue(recommendation, (bool)settingValue);
break;
default:
throw new OptionSettingItemDoesNotExistException($"The Option Setting Item { optionSettingId } does not exist.");
return;
}
}

Expand Down Expand Up @@ -485,7 +475,7 @@ private async Task CreateDeploymentBundle(Orchestrator orchestrator, Recommendat
errorMessage += "Specify a valid Docker execution directory as part of the deployment settings file and try again.";
throw new DockerBuildFailedException(errorMessage);
}

_toolInteractiveService.WriteLine(string.Empty);
var answer = _consoleUtilities.AskYesNoQuestion("Do you want to go back and modify the current configuration?", "true");
if (answer == YesNo.Yes)
Expand Down
Loading

0 comments on commit 28e6e39

Please sign in to comment.