using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.SelfService.Portal.Core.API.Authorization; using Microsoft.SelfService.Portal.Core.API.Context; using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentRule.Add; using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentRule.Get; using Microsoft.SelfService.Portal.Core.API.Models; namespace Microsoft.SelfService.Portal.Core.API.Controllers { [Route("api/deployment-rules")] [ApiController] [Authorize(Policy = ApiPolicies.DeploymentRead)] public class DeploymentRuleController : Controller { private readonly DataContext _context; public DeploymentRuleController(DataContext context) { _context = context; } [HttpGet] [ProducesResponseType(200, Type = typeof(IEnumerable))] public IActionResult GetDeploymentRules() { var rules = _context.DeploymentRules .AsNoTracking() .Include(rule => rule.Steps) .OrderBy(rule => rule.Name) .Select(rule => MapRule(rule)) .ToList(); return Ok(rules); } [HttpGet("{id}")] [ProducesResponseType(200, Type = typeof(GetDeploymentRuleDto))] [ProducesResponseType(404)] public IActionResult GetDeploymentRuleById(Guid id) { var rule = _context.DeploymentRules .AsNoTracking() .Include(entry => entry.Steps) .FirstOrDefault(entry => entry.Id == id); if (rule == null) return NotFound(); return Ok(MapRule(rule)); } [HttpPost] [Authorize(Policy = ApiPolicies.DeploymentWrite)] [ProducesResponseType(200, Type = typeof(Guid))] [ProducesResponseType(400)] public IActionResult AddDeploymentRule([FromBody] AddDeploymentRuleDto deploymentRule) { if (deploymentRule == null) return BadRequest(ModelState); var rule = new DeploymentRuleModel { Name = deploymentRule.Name, Description = deploymentRule.Description, IsActive = deploymentRule.IsActive }; _context.DeploymentRules.Add(rule); _context.SaveChanges(); foreach (var (step, index) in deploymentRule.Steps.Select((value, idx) => (value, idx))) { _context.DeploymentRuleSteps.Add(new DeploymentRuleStepModel { DeploymentRuleId = rule.Id, SortOrder = step.SortOrder > 0 ? step.SortOrder : index + 1, Name = step.Name, StepType = string.IsNullOrWhiteSpace(step.StepType) ? QueueJobStepType.Provision : step.StepType, RequiresApproval = step.RequiresApproval, MetadataJson = step.MetadataJson }); } _context.SaveChanges(); return Ok(rule.Id); } [HttpPut("{id}")] [Authorize(Policy = ApiPolicies.DeploymentWrite)] [ProducesResponseType(204)] [ProducesResponseType(404)] public IActionResult EditDeploymentRule(Guid id, [FromBody] AddDeploymentRuleDto deploymentRule) { var existingRule = _context.DeploymentRules .Include(rule => rule.Steps) .FirstOrDefault(rule => rule.Id == id); if (existingRule == null) return NotFound(); existingRule.Name = deploymentRule.Name; existingRule.Description = deploymentRule.Description; existingRule.IsActive = deploymentRule.IsActive; var existingSteps = _context.DeploymentRuleSteps.Where(step => step.DeploymentRuleId == id).ToList(); if (existingSteps.Count > 0) { _context.DeploymentRuleSteps.RemoveRange(existingSteps); } foreach (var (step, index) in deploymentRule.Steps.Select((value, idx) => (value, idx))) { _context.DeploymentRuleSteps.Add(new DeploymentRuleStepModel { DeploymentRuleId = id, SortOrder = step.SortOrder > 0 ? step.SortOrder : index + 1, Name = step.Name, StepType = string.IsNullOrWhiteSpace(step.StepType) ? QueueJobStepType.Provision : step.StepType, RequiresApproval = step.RequiresApproval, MetadataJson = step.MetadataJson }); } _context.SaveChanges(); return NoContent(); } [HttpDelete("{id}")] [Authorize(Policy = ApiPolicies.DeploymentWrite)] [ProducesResponseType(204)] [ProducesResponseType(404)] public IActionResult DeleteDeploymentRule(Guid id) { var existingRule = _context.DeploymentRules.FirstOrDefault(rule => rule.Id == id); if (existingRule == null) return NotFound(); var linkedTemplates = _context.Templates.Where(template => template.DeploymentRuleId == id).ToList(); foreach (var template in linkedTemplates) { template.DeploymentRuleId = null; } var steps = _context.DeploymentRuleSteps.Where(step => step.DeploymentRuleId == id).ToList(); if (steps.Count > 0) { _context.DeploymentRuleSteps.RemoveRange(steps); } _context.DeploymentRules.Remove(existingRule); _context.SaveChanges(); return NoContent(); } private static GetDeploymentRuleDto MapRule(DeploymentRuleModel rule) { return new GetDeploymentRuleDto { Id = rule.Id, Name = rule.Name, Description = rule.Description, IsActive = rule.IsActive, Created = rule.Created, CreatedBy = rule.CreatedBy, Modified = rule.Modified, ModifiedBy = rule.ModifiedBy, Steps = rule.Steps .OrderBy(step => step.SortOrder) .Select(step => new GetDeploymentRuleStepDto { Id = step.Id, SortOrder = step.SortOrder, Name = step.Name, StepType = step.StepType, RequiresApproval = step.RequiresApproval, MetadataJson = step.MetadataJson, Created = step.Created, CreatedBy = step.CreatedBy, Modified = step.Modified, ModifiedBy = step.ModifiedBy }) .ToList() }; } } }