// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\r // SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AWS.Deploy.CLI.ServerMode.Models; using AWS.Deploy.Common; using AWS.Deploy.Common.Recipes; using AWS.Deploy.Recipes; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; namespace AWS.Deploy.CLI.ServerMode.Controllers { [Produces("application/json")] [ApiController] [Route("api/v1/[controller]")] public class RecipeController : ControllerBase { private readonly IRecipeHandler _recipeHandler; private readonly IProjectDefinitionParser _projectDefinitionParser; public RecipeController(IRecipeHandler recipeHandler, IProjectDefinitionParser projectDefinitionParser) { _recipeHandler = recipeHandler; _projectDefinitionParser = projectDefinitionParser; } private async Task<List<RecipeDefinition>> GetAllAvailableRecipes(string? projectPath = null) { var recipePaths = new HashSet<string> { RecipeLocator.FindRecipeDefinitionsPath() }; HashSet<string> customRecipePaths = new HashSet<string>(); if (!string.IsNullOrEmpty(projectPath)) { var projectDefinition = await _projectDefinitionParser.Parse(projectPath); customRecipePaths = await _recipeHandler.LocateCustomRecipePaths(projectDefinition); } return await _recipeHandler.GetRecipeDefinitions(recipeDefinitionPaths: recipePaths.Union(customRecipePaths).ToList()); } /// <summary> /// Gets a list of available recipe IDs. /// </summary> [HttpGet("recipes")] [SwaggerOperation(OperationId = "ListAllRecipes")] [SwaggerResponse(200, type: typeof(ListAllRecipesOutput))] [ProducesResponseType(Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest)] public async Task<IActionResult> ListAllRecipes([FromQuery] string? projectPath = null) { var recipeDefinitions = await GetAllAvailableRecipes(projectPath); var recipes = recipeDefinitions .Select(x => new RecipeSummary( x.Id, x.Version, x.Name, x.Description, x.ShortDescription, x.TargetService, x.DeploymentType.ToString(), x.DeploymentBundle.ToString()) ).ToList(); var output = new ListAllRecipesOutput { Recipes = recipes }; return Ok(output); } /// <summary> /// Gets a summary of the specified Recipe. /// </summary> [HttpGet("{recipeId}")] [SwaggerOperation(OperationId = "GetRecipe")] [SwaggerResponse(200, type: typeof(RecipeSummary))] [ProducesResponseType(Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest)] public async Task<IActionResult> GetRecipe(string recipeId, [FromQuery] string? projectPath = null) { if (string.IsNullOrEmpty(recipeId)) { return BadRequest($"A Recipe ID was not provided."); } var recipeDefinitions = await GetAllAvailableRecipes(projectPath); var selectedRecipeDefinition = recipeDefinitions.FirstOrDefault(x => x.Id.Equals(recipeId)); if (selectedRecipeDefinition == null) { return BadRequest($"Recipe ID {recipeId} not found."); } var output = new RecipeSummary( selectedRecipeDefinition.Id, selectedRecipeDefinition.Version, selectedRecipeDefinition.Name, selectedRecipeDefinition.Description, selectedRecipeDefinition.ShortDescription, selectedRecipeDefinition.TargetService, selectedRecipeDefinition.DeploymentType.ToString(), selectedRecipeDefinition.DeploymentBundle.ToString() ); return Ok(output); } /// <summary> /// Gets a summary of the specified recipe option settings. /// </summary> [HttpGet("{recipeId}/settings")] [SwaggerOperation(OperationId = "GetRecipeOptionSettings")] [SwaggerResponse(200, type: typeof(List<RecipeOptionSettingSummary>))] [ProducesResponseType(Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest)] public async Task<IActionResult> GetRecipeOptionSettings(string recipeId, [FromQuery] string? projectPath = null) { if (string.IsNullOrEmpty(recipeId)) { return BadRequest($"A Recipe ID was not provided."); } var recipeDefinitions = await GetAllAvailableRecipes(projectPath); var selectedRecipeDefinition = recipeDefinitions.FirstOrDefault(x => x.Id.Equals(recipeId)); if (selectedRecipeDefinition == null) { return BadRequest($"Recipe ID {recipeId} not found."); } var settings = GetOptionSettingSummary(selectedRecipeDefinition.OptionSettings); return Ok(settings); } private List<RecipeOptionSettingSummary> GetOptionSettingSummary(List<OptionSettingItem> optionSettingItems) { var settings = new List<RecipeOptionSettingSummary>(); foreach (var optionSetting in optionSettingItems) { settings.Add(new RecipeOptionSettingSummary( optionSetting.Id, optionSetting.Name, optionSetting.Description, optionSetting.Type.ToString() ) { Settings = GetOptionSettingSummary(optionSetting.ChildOptionSettings) }); } return settings; } } }