Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Events.Interfaces;
|
||||
using Microsoft.SelfService.Portal.Core.API.Models;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
{
|
||||
public class AbstractController : Controller
|
||||
{
|
||||
private readonly IEventHandlerInterface _eventHandlerInterface;
|
||||
|
||||
private readonly string _class;
|
||||
private readonly string _method;
|
||||
|
||||
public AbstractController( string Class, string Method)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
ICollection<EventModel> GetEvents()
|
||||
{
|
||||
return _eventHandlerInterface.GetEvents(_class, _method);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Context;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentBatch.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentBatch.Edit;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentBatch.Get;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentComposition.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentComposition.Get;
|
||||
using Microsoft.SelfService.Portal.Core.API.Interfaces;
|
||||
using Microsoft.SelfService.Portal.Core.API.JsonDocuments;
|
||||
using Microsoft.SelfService.Portal.Core.API.Models;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
{
|
||||
[Route("api/deployment-batches")]
|
||||
[ApiController]
|
||||
public class DeploymentBatchController : Controller
|
||||
{
|
||||
private readonly IDeploymentBatchInterface _deploymentBatchInterface;
|
||||
private readonly DataContext _context;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public DeploymentBatchController(IDeploymentBatchInterface deploymentBatchInterface, DataContext context, IMapper mapper)
|
||||
{
|
||||
_deploymentBatchInterface = deploymentBatchInterface;
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200, Type = typeof(IEnumerable<GetDeploymentBatchDto>))]
|
||||
public IActionResult GetDeploymentBatches()
|
||||
{
|
||||
var deploymentBatches = _deploymentBatchInterface
|
||||
.GetDeploymentBatches()
|
||||
.Select(batch => new GetDeploymentBatchDto
|
||||
{
|
||||
Id = batch.Id,
|
||||
TemplateId = batch.TemplateId,
|
||||
DeploymentRuleId = batch.DeploymentRuleId,
|
||||
Status = batch.Status,
|
||||
Created = batch.Created,
|
||||
CreatedBy = batch.CreatedBy,
|
||||
Modified = batch.Modified,
|
||||
ModifiedBy = batch.ModifiedBy
|
||||
})
|
||||
.ToList();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(deploymentBatches);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[ProducesResponseType(200, Type = typeof(DeploymentGroupModel))]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult GetDeploymentBatchById(Guid id)
|
||||
{
|
||||
if (!_deploymentBatchInterface.CheckDeploymentBatchById(id))
|
||||
return NotFound();
|
||||
|
||||
var deploymentBatch = _mapper.Map<GetDeploymentBatchDetailsDto>(_deploymentBatchInterface.GetDeploymentBatchById(id));
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(deploymentBatch);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult AddDeploymentBatch([FromBody] AddDeploymentBatchDto deploymentBatch)
|
||||
{
|
||||
if (deploymentBatch == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var deploymentBatchMap = _mapper.Map<DeploymentGroupModel>(deploymentBatch);
|
||||
|
||||
if (!_deploymentBatchInterface.AddDeploymentBatchById(deploymentBatchMap, deploymentBatch.TargetIds))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return Ok(deploymentBatchMap.Id);
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult DeleteDeploymentBatchById(Guid id)
|
||||
{
|
||||
if (!_deploymentBatchInterface.CheckDeploymentBatchById(id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var deploymentBatch = _deploymentBatchInterface.GetDeploymentBatchById(id);
|
||||
|
||||
if (deploymentBatch == null)
|
||||
return NotFound();
|
||||
|
||||
if (!_deploymentBatchInterface.DeleteDeploymentBatchById(deploymentBatch))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while deleting");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult EditDeploymentBatchById(Guid id, [FromBody] EditDeploymentBatchDto deploymentBatch)
|
||||
{
|
||||
if (deploymentBatch == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!_deploymentBatchInterface.CheckDeploymentBatchById(id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var deploymentBatchMap = _mapper.Map<DeploymentGroupModel>(deploymentBatch);
|
||||
deploymentBatchMap.Id = id;
|
||||
|
||||
if (!_deploymentBatchInterface.EditDeploymentBatchById(deploymentBatchMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("{id}/composition")]
|
||||
[ProducesResponseType(200, Type = typeof(GetDeploymentCompositionDto))]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult GetDeploymentComposition(Guid id)
|
||||
{
|
||||
if (!_deploymentBatchInterface.CheckDeploymentBatchById(id))
|
||||
return NotFound();
|
||||
|
||||
return Ok(LoadComposition(id));
|
||||
}
|
||||
|
||||
[HttpPost("{id}/template-selections")]
|
||||
[ProducesResponseType(200, Type = typeof(Guid))]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult AddTemplateSelection(Guid id, [FromBody] AddDeploymentTemplateSelectionDto templateSelection)
|
||||
{
|
||||
if (!_deploymentBatchInterface.CheckDeploymentBatchById(id))
|
||||
return NotFound();
|
||||
|
||||
if (!_context.TemplateVersions.Any(version => version.Id == templateSelection.TemplateVersionId))
|
||||
{
|
||||
ModelState.AddModelError(nameof(templateSelection.TemplateVersionId), "Template version was not found.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
var sortOrder = templateSelection.SortOrder > 0
|
||||
? templateSelection.SortOrder
|
||||
: GetNextTemplateSelectionSortOrder(id);
|
||||
|
||||
if (_context.DeploymentTemplateSelections.Any(selection => selection.DeploymentGroupId == id && selection.SortOrder == sortOrder))
|
||||
{
|
||||
ModelState.AddModelError(nameof(templateSelection.SortOrder), "SortOrder already exists in this deployment batch.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
var model = _mapper.Map<DeploymentTemplateSelectionModel>(templateSelection);
|
||||
model.Id = Guid.NewGuid();
|
||||
model.DeploymentGroupId = id;
|
||||
model.SortOrder = sortOrder;
|
||||
|
||||
_context.DeploymentTemplateSelections.Add(model);
|
||||
_context.SaveChanges();
|
||||
|
||||
return Ok(model.Id);
|
||||
}
|
||||
|
||||
[HttpDelete("{id}/template-selections/{selectionId}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult DeleteTemplateSelection(Guid id, Guid selectionId)
|
||||
{
|
||||
var selection = _context.DeploymentTemplateSelections
|
||||
.FirstOrDefault(existing => existing.DeploymentGroupId == id && existing.Id == selectionId);
|
||||
|
||||
if (selection == null)
|
||||
return NotFound();
|
||||
|
||||
_context.DeploymentTemplateSelections.Remove(selection);
|
||||
_context.SaveChanges();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPost("{id}/parameter-values")]
|
||||
[ProducesResponseType(200, Type = typeof(Guid))]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult AddParameterValue(Guid id, [FromBody] AddDeploymentParameterValueDto parameterValue)
|
||||
{
|
||||
if (!_deploymentBatchInterface.CheckDeploymentBatchById(id))
|
||||
return NotFound();
|
||||
|
||||
if (parameterValue.DeploymentTemplateSelectionId.HasValue
|
||||
&& !_context.DeploymentTemplateSelections.Any(selection =>
|
||||
selection.DeploymentGroupId == id
|
||||
&& selection.Id == parameterValue.DeploymentTemplateSelectionId.Value))
|
||||
{
|
||||
ModelState.AddModelError(nameof(parameterValue.DeploymentTemplateSelectionId), "Template selection was not found in this deployment batch.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
if (_context.DeploymentParameterValues.Any(existing =>
|
||||
existing.DeploymentGroupId == id
|
||||
&& existing.DeploymentTemplateSelectionId == parameterValue.DeploymentTemplateSelectionId
|
||||
&& existing.Name == parameterValue.Name))
|
||||
{
|
||||
ModelState.AddModelError(nameof(parameterValue.Name), "Parameter value already exists in this scope.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
parameterValue.ValueJson = ConfigurationDocumentValidator.NormalizeAndValidate(
|
||||
parameterValue.ValueJson,
|
||||
ConfigurationDocumentKind.Metadata).JsonData;
|
||||
}
|
||||
catch (ConfigurationDocumentValidationException ex)
|
||||
{
|
||||
ModelState.AddModelError(nameof(parameterValue.ValueJson), ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
var model = _mapper.Map<DeploymentParameterValueModel>(parameterValue);
|
||||
model.Id = Guid.NewGuid();
|
||||
model.DeploymentGroupId = id;
|
||||
|
||||
_context.DeploymentParameterValues.Add(model);
|
||||
_context.SaveChanges();
|
||||
|
||||
return Ok(model.Id);
|
||||
}
|
||||
|
||||
[HttpDelete("{id}/parameter-values/{parameterValueId}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult DeleteParameterValue(Guid id, Guid parameterValueId)
|
||||
{
|
||||
var parameterValue = _context.DeploymentParameterValues
|
||||
.FirstOrDefault(existing => existing.DeploymentGroupId == id && existing.Id == parameterValueId);
|
||||
|
||||
if (parameterValue == null)
|
||||
return NotFound();
|
||||
|
||||
_context.DeploymentParameterValues.Remove(parameterValue);
|
||||
_context.SaveChanges();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPost("{id}/target-assignments")]
|
||||
[ProducesResponseType(200, Type = typeof(Guid))]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult AddTargetAssignment(Guid id, [FromBody] AddDeploymentTargetAssignmentDto targetAssignment)
|
||||
{
|
||||
if (!_deploymentBatchInterface.CheckDeploymentBatchById(id))
|
||||
return NotFound();
|
||||
|
||||
if (!_context.Targets.Any(target => target.Id == targetAssignment.TargetId))
|
||||
{
|
||||
ModelState.AddModelError(nameof(targetAssignment.TargetId), "Target target was not found.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
if (_context.DeploymentTargetAssignments.Any(existing =>
|
||||
existing.DeploymentGroupId == id
|
||||
&& existing.TargetId == targetAssignment.TargetId
|
||||
&& existing.RoleKey == targetAssignment.RoleKey))
|
||||
{
|
||||
ModelState.AddModelError(nameof(targetAssignment.TargetId), "Target assignment already exists for this role.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
targetAssignment.NodeDataJson = ConfigurationDocumentValidator.NormalizeAndValidate(
|
||||
targetAssignment.NodeDataJson,
|
||||
ConfigurationDocumentKind.Metadata).JsonData;
|
||||
}
|
||||
catch (ConfigurationDocumentValidationException ex)
|
||||
{
|
||||
ModelState.AddModelError(nameof(targetAssignment.NodeDataJson), ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
var sortOrder = targetAssignment.SortOrder > 0
|
||||
? targetAssignment.SortOrder
|
||||
: GetNextTargetAssignmentSortOrder(id);
|
||||
|
||||
var model = _mapper.Map<DeploymentTargetAssignmentModel>(targetAssignment);
|
||||
model.Id = Guid.NewGuid();
|
||||
model.DeploymentGroupId = id;
|
||||
model.SortOrder = sortOrder;
|
||||
|
||||
_context.DeploymentTargetAssignments.Add(model);
|
||||
_context.SaveChanges();
|
||||
|
||||
return Ok(model.Id);
|
||||
}
|
||||
|
||||
[HttpDelete("{id}/target-assignments/{targetAssignmentId}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult DeleteTargetAssignment(Guid id, Guid targetAssignmentId)
|
||||
{
|
||||
var targetAssignment = _context.DeploymentTargetAssignments
|
||||
.FirstOrDefault(existing => existing.DeploymentGroupId == id && existing.Id == targetAssignmentId);
|
||||
|
||||
if (targetAssignment == null)
|
||||
return NotFound();
|
||||
|
||||
_context.DeploymentTargetAssignments.Remove(targetAssignment);
|
||||
_context.SaveChanges();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
private GetDeploymentCompositionDto LoadComposition(Guid deploymentBatchId)
|
||||
{
|
||||
return new GetDeploymentCompositionDto
|
||||
{
|
||||
DeploymentBatchId = deploymentBatchId,
|
||||
TemplateSelections = _mapper.Map<List<GetDeploymentTemplateSelectionDto>>(
|
||||
_context.DeploymentTemplateSelections
|
||||
.AsNoTracking()
|
||||
.Include(selection => selection.TemplateVersion)
|
||||
.Where(selection => selection.DeploymentGroupId == deploymentBatchId)
|
||||
.OrderBy(selection => selection.SortOrder)
|
||||
.ToList()),
|
||||
ParameterValues = _mapper.Map<List<GetDeploymentParameterValueDto>>(
|
||||
_context.DeploymentParameterValues
|
||||
.AsNoTracking()
|
||||
.Where(parameterValue => parameterValue.DeploymentGroupId == deploymentBatchId)
|
||||
.OrderBy(parameterValue => parameterValue.Name)
|
||||
.ToList()),
|
||||
TargetAssignments = _mapper.Map<List<GetDeploymentTargetAssignmentDto>>(
|
||||
_context.DeploymentTargetAssignments
|
||||
.AsNoTracking()
|
||||
.Include(target => target.Target)
|
||||
.Where(target => target.DeploymentGroupId == deploymentBatchId)
|
||||
.OrderBy(target => target.SortOrder)
|
||||
.ToList())
|
||||
};
|
||||
}
|
||||
|
||||
private int GetNextTemplateSelectionSortOrder(Guid deploymentBatchId)
|
||||
{
|
||||
var maxSortOrder = _context.DeploymentTemplateSelections
|
||||
.Where(selection => selection.DeploymentGroupId == deploymentBatchId)
|
||||
.Select(selection => (int?)selection.SortOrder)
|
||||
.Max() ?? 0;
|
||||
|
||||
return maxSortOrder + 10;
|
||||
}
|
||||
|
||||
private int GetNextTargetAssignmentSortOrder(Guid deploymentBatchId)
|
||||
{
|
||||
var maxSortOrder = _context.DeploymentTargetAssignments
|
||||
.Where(target => target.DeploymentGroupId == deploymentBatchId)
|
||||
.Select(target => (int?)target.SortOrder)
|
||||
.Max() ?? 0;
|
||||
|
||||
return maxSortOrder + 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,8 @@ using Microsoft.SelfService.Portal.Core.API.Dto.Deployment.Edit;
|
||||
using Microsoft.SelfService.Portal.Core.API.Interfaces;
|
||||
using Microsoft.SelfService.Portal.Core.API.Models;
|
||||
using Microsoft.SelfService.Portal.Core.API.Context;
|
||||
|
||||
using Microsoft.SelfService.Portal.Core.API.Events.Interfaces;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Dynamic;
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.SelfService.Portal.Core.API.JsonDocuments;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
{
|
||||
@@ -24,20 +19,17 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
private readonly IQueueJobService _queueJobService;
|
||||
private readonly DataContext _context;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IEventHandlerInterface _eventHandlerInterface;
|
||||
|
||||
public DeploymentController(
|
||||
IDeploymentInterface deploymentInterface,
|
||||
IQueueJobService queueJobService,
|
||||
DataContext context,
|
||||
IMapper mapper,
|
||||
IEventHandlerInterface eventHandlerInterface)
|
||||
IMapper mapper)
|
||||
{
|
||||
_deploymentInterface = deploymentInterface;
|
||||
_queueJobService = queueJobService;
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
_eventHandlerInterface = eventHandlerInterface;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -83,10 +75,18 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
|
||||
var deploymentMap = _mapper.Map<DeploymentModel>(deployment);
|
||||
|
||||
if (!_deploymentInterface.AddDeploymentById(deploymentMap))
|
||||
try
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
if (!_deploymentInterface.AddDeploymentById(deploymentMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
}
|
||||
catch (ConfigurationDocumentValidationException ex)
|
||||
{
|
||||
ModelState.AddModelError(nameof(deployment.JsonData), ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
return Ok(deploymentMap.Id);
|
||||
@@ -100,9 +100,9 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
if (request == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (request.VirtualMachineIds == null || request.VirtualMachineIds.Count == 0)
|
||||
if (request.TargetIds == null || request.TargetIds.Count == 0)
|
||||
{
|
||||
ModelState.AddModelError("", "At least one VirtualMachine must be selected.");
|
||||
ModelState.AddModelError("", "At least one Target must be selected.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
{
|
||||
var queueJobId = _queueJobService.EnqueueDeploymentRequest(
|
||||
request.DeploymentGroupId,
|
||||
request.VirtualMachineIds,
|
||||
request.TargetIds,
|
||||
request.JsonData);
|
||||
|
||||
return Ok(queueJobId);
|
||||
@@ -123,6 +123,11 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
ModelState.AddModelError("", ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
catch (ConfigurationDocumentValidationException ex)
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.JsonData), ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("QueueJobs")]
|
||||
@@ -187,7 +192,7 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
Targets = queueJob.Targets.Select(target => new GetQueueJobTargetDto
|
||||
{
|
||||
Id = target.Id,
|
||||
VirtualMachineId = target.VirtualMachineId,
|
||||
TargetId = target.TargetId,
|
||||
DeploymentGroupId = target.DeploymentGroupId,
|
||||
TemplateId = target.TemplateId,
|
||||
Status = target.Status,
|
||||
@@ -271,6 +276,32 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("Batch/{deploymentBatchId}/Target/{targetId}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult DeleteDeploymentExecution(Guid deploymentBatchId, Guid targetId)
|
||||
{
|
||||
if (!_deploymentInterface.CheckDeploymentByCompositeId(deploymentBatchId, targetId))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var deployment = _deploymentInterface.GetDeploymentByCompositeId(deploymentBatchId, targetId);
|
||||
|
||||
if (deployment == null)
|
||||
return NotFound();
|
||||
|
||||
if (!_deploymentInterface.DeleteDeploymentById(deployment))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while deleting");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPut("{Id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
@@ -289,15 +320,22 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
var deploymentMap = _mapper.Map<DeploymentModel>(deployment);
|
||||
deploymentMap.Id = Id;
|
||||
|
||||
if (!_deploymentInterface.EditDeploymentById(deploymentMap))
|
||||
try
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
if (!_deploymentInterface.EditDeploymentById(deploymentMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
}
|
||||
catch (ConfigurationDocumentValidationException ex)
|
||||
{
|
||||
ModelState.AddModelError(nameof(deployment.jsonData), ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
_eventHandlerInterface.FireEvent(this.GetType().Name, MethodBase.GetCurrentMethod().Name, Id);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentGroup.Get;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentGroup.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.DeploymentGroup.Edit;
|
||||
using Microsoft.SelfService.Portal.Core.API.Interfaces;
|
||||
using Microsoft.SelfService.Portal.Core.API.Models;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
{
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class DeploymentGroupController : Controller
|
||||
{
|
||||
private readonly IDeploymentGroupInterface _deploymentgroupInterface;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public DeploymentGroupController(IDeploymentGroupInterface deploymentGroupInterface, IMapper mapper)
|
||||
{
|
||||
_deploymentgroupInterface = deploymentGroupInterface;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200, Type = typeof(IEnumerable<DomainModel>))]
|
||||
public IActionResult GetDeploymentGroups()
|
||||
{
|
||||
var deploymentgroups = _mapper.Map<List<GetDeploymentGroupDto>>(_deploymentgroupInterface.GetDeploymentGroups());
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(deploymentgroups);
|
||||
}
|
||||
|
||||
[HttpGet("{Id}")]
|
||||
[ProducesResponseType(200, Type = typeof(DeploymentGroupModel))]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult GetDeploymentGroupById(Guid Id)
|
||||
{
|
||||
|
||||
if (!_deploymentgroupInterface.CheckDeploymentGroupById(Id))
|
||||
return NotFound();
|
||||
|
||||
var deploymentgroup = _mapper.Map<GetDeploymentGroupDetailsDto>(_deploymentgroupInterface.GetDeploymentGroupById(Id));
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(deploymentgroup);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult AddDeploymentGroupById([FromBody] AddDeploymentGroupDto deploymentgroup)
|
||||
{
|
||||
|
||||
if (deploymentgroup == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var deploymentgroupMap = _mapper.Map<DeploymentGroupModel>(deploymentgroup);
|
||||
|
||||
if (!_deploymentgroupInterface.AddDeploymentGroupById(deploymentgroupMap, deploymentgroup.VirtualMachineIds))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
return Ok(deploymentgroupMap.Id);
|
||||
}
|
||||
|
||||
[HttpDelete("{Id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult DeleteDeploymentGroupById(Guid Id)
|
||||
{
|
||||
if (!_deploymentgroupInterface.CheckDeploymentGroupById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var deploymentgroup = _deploymentgroupInterface.GetDeploymentGroupById(Id);
|
||||
|
||||
if (!_deploymentgroupInterface.DeleteDeploymentGroupById(deploymentgroup))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while deleting");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPut("{Id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult EditDeploymentGroupById(Guid Id, [FromBody] EditDeploymentGroupDto deploymentgroup)
|
||||
{
|
||||
if (deploymentgroup == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!_deploymentgroupInterface.CheckDeploymentGroupById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var deploymentgroupMap = _mapper.Map<DeploymentGroupModel>(deploymentgroup);
|
||||
deploymentgroupMap.Id = Id;
|
||||
|
||||
if (!_deploymentgroupInterface.EditDeploymentGroupById(deploymentgroupMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
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]
|
||||
public class DeploymentRuleController : Controller
|
||||
{
|
||||
private readonly DataContext _context;
|
||||
|
||||
public DeploymentRuleController(DataContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200, Type = typeof(IEnumerable<GetDeploymentRuleDto>))]
|
||||
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]
|
||||
[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}")]
|
||||
[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}")]
|
||||
[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()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,16 +210,16 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("{Id}/VirtualMachines")]
|
||||
[HttpGet("{Id}/Targets")]
|
||||
[ProducesResponseType(200, Type = typeof(DomainModel))]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult GetVirtualMachinesByDomainId(Guid Id)
|
||||
public IActionResult GetTargetsByDomainId(Guid Id)
|
||||
{
|
||||
|
||||
if (!_domainInterface.CheckDomainById(Id))
|
||||
return NotFound();
|
||||
|
||||
var domain = _mapper.Map<GetDomainVirtualMachineDetailsDto>(_domainInterface.GetVirtualMachinesByDomainId(Id));
|
||||
var domain = _mapper.Map<GetDomainTargetDetailsDto>(_domainInterface.GetTargetsByDomainId(Id));
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
@@ -228,3 +228,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,10 +63,16 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
|
||||
if (_environmentInterface.CheckEnvironmentByName(environment.Name))
|
||||
{
|
||||
ModelState.AddModelError("", "Domain already exists");
|
||||
ModelState.AddModelError("", "Environment already exists");
|
||||
return StatusCode(422, ModelState);
|
||||
}
|
||||
|
||||
if (!IsValidEnvironmentStage(environment.EnvironmentType) || !IsValidHostingType(environment.HostingType))
|
||||
{
|
||||
ModelState.AddModelError("", "Invalid Environment Stage or Hosting Type.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
@@ -118,6 +124,12 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!IsValidEnvironmentStage(environment.EnvironmentType) || !IsValidHostingType(environment.HostingType))
|
||||
{
|
||||
ModelState.AddModelError("", "Invalid Environment Stage or Hosting Type.");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
var environmentMap = _mapper.Map<EnvironmentModel>(environment);
|
||||
environmentMap.Id = Id;
|
||||
|
||||
@@ -130,6 +142,21 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
private static bool IsValidEnvironmentStage(string? stage)
|
||||
{
|
||||
return stage == EnvironmentStages.Development
|
||||
|| stage == EnvironmentStages.Test
|
||||
|| stage == EnvironmentStages.QA
|
||||
|| stage == EnvironmentStages.Production;
|
||||
}
|
||||
|
||||
private static bool IsValidHostingType(string? hostingType)
|
||||
{
|
||||
return hostingType == EnvironmentHostingTypes.OnPrem
|
||||
|| hostingType == EnvironmentHostingTypes.AzureTenant
|
||||
|| hostingType == EnvironmentHostingTypes.M365Tenant;
|
||||
}
|
||||
|
||||
[HttpGet("{Id}/Domains")]
|
||||
[ProducesResponseType(200, Type = typeof(EnvironmentModel))]
|
||||
[ProducesResponseType(400)]
|
||||
@@ -161,3 +188,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Runbook.Get;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Runbook.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Interfaces;
|
||||
using Microsoft.SelfService.Portal.Core.API.Models;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class RunbookController : Controller
|
||||
{
|
||||
|
||||
private readonly IRunbookInterface _runbookInterface;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public RunbookController(IRunbookInterface runbookInterface, IMapper mapper)
|
||||
{
|
||||
_runbookInterface = runbookInterface;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200, Type = typeof(IEnumerable<RunbookModel>))]
|
||||
public IActionResult GetRunbooks()
|
||||
{
|
||||
var runbooks = _mapper.Map<List<GetRunbookDto>>(_runbookInterface.GetRunbooks());
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(runbooks);
|
||||
}
|
||||
|
||||
[HttpGet("{Id}")]
|
||||
[ProducesResponseType(200, Type = typeof(RunbookModel))]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult GetRunbookById(Guid Id)
|
||||
{
|
||||
|
||||
if (!_runbookInterface.CheckRunbookById(Id))
|
||||
return NotFound();
|
||||
|
||||
var runbook = _mapper.Map<GetRunbookDetailsDto>(_runbookInterface.GetRunbookById(Id));
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(runbook);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult AddRunbookById([FromBody] AddRunbookDto runbook)
|
||||
{
|
||||
|
||||
if (runbook == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (_runbookInterface.CheckRunbookByName(runbook.Name))
|
||||
{
|
||||
ModelState.AddModelError("", "Runbook already exists");
|
||||
return StatusCode(422, ModelState);
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
|
||||
var runbookMap = _mapper.Map<RunbookModel>(runbook);
|
||||
|
||||
if (!_runbookInterface.AddRunbookById(runbookMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return Ok("Successfully created");
|
||||
}
|
||||
|
||||
[HttpPut("{Id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult EditRunbookById(Guid Id, [FromBody] GetRunbookDetailsDto runbook)
|
||||
{
|
||||
if (runbook == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (Id != runbook.Id)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!_runbookInterface.CheckRunbookById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var runbookMap = _mapper.Map<RunbookModel>(runbook);
|
||||
|
||||
if (_runbookInterface.EditRunbookById(runbookMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using AutoMapper;
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Service.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Service.Edit;
|
||||
@@ -240,3 +240,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Target.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Target.Edit;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Target.Get;
|
||||
using Microsoft.SelfService.Portal.Core.API.Interfaces;
|
||||
using Microsoft.SelfService.Portal.Core.API.Models;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class TargetController : Controller
|
||||
{
|
||||
private readonly ITargetInterface _targetInterface;
|
||||
private readonly IDomainInterface _domainInterface;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public TargetController(ITargetInterface targetInterface, IDomainInterface domainInterface, IMapper mapper)
|
||||
{
|
||||
_targetInterface = targetInterface;
|
||||
_domainInterface = domainInterface;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200, Type = typeof(IEnumerable<TargetModel>))]
|
||||
public IActionResult GetTargets()
|
||||
{
|
||||
var targets = _mapper.Map<List<GetTargetDto>>(_targetInterface.GetTargets());
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(targets);
|
||||
}
|
||||
|
||||
[HttpGet("{Id}")]
|
||||
[ProducesResponseType(200, Type = typeof(TargetModel))]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult GetTargetById(Guid Id)
|
||||
{
|
||||
if (!_targetInterface.CheckTargetById(Id))
|
||||
return NotFound();
|
||||
|
||||
var target = _mapper.Map<GetTargetDetailsDto>(_targetInterface.GetTargetById(Id));
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(target);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult AddTargetById([FromBody] AddTargetDto target)
|
||||
{
|
||||
if (target == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (_targetInterface.CheckTargetByName(target.Name))
|
||||
{
|
||||
ModelState.AddModelError("", "Target already exists");
|
||||
return StatusCode(422, ModelState);
|
||||
}
|
||||
|
||||
if (target.DomainID.HasValue && !_domainInterface.CheckDomainById(target.DomainID.Value))
|
||||
{
|
||||
ModelState.AddModelError("", "Domain does not exist");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var targetMap = _mapper.Map<TargetModel>(target);
|
||||
|
||||
if (!_targetInterface.AddTargetById(targetMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return Ok(targetMap.Id);
|
||||
}
|
||||
|
||||
[HttpPut("{Id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult EditTargetById(Guid Id, [FromBody] EditTargetDto target)
|
||||
{
|
||||
if (target == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!_targetInterface.CheckTargetById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var existingTarget = _targetInterface.GetTargetById(Id);
|
||||
if (existingTarget == null)
|
||||
return NotFound();
|
||||
|
||||
existingTarget.Name = target.Name;
|
||||
existingTarget.TargetType = target.TargetType;
|
||||
existingTarget.ProviderType = target.ProviderType;
|
||||
existingTarget.ExternalId = target.ExternalId;
|
||||
existingTarget.MetadataJson = target.MetadataJson;
|
||||
|
||||
if (!_targetInterface.EditTargetById(existingTarget))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPost("{Id}/Domain/{domainId}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(409)]
|
||||
public IActionResult LinkTargetToDomain(Guid Id, Guid domainId)
|
||||
{
|
||||
if (!_targetInterface.CheckTargetById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!_domainInterface.CheckDomainById(domainId))
|
||||
return NotFound();
|
||||
|
||||
var existingTarget = _targetInterface.GetTargetById(Id);
|
||||
if (existingTarget == null)
|
||||
return NotFound();
|
||||
|
||||
if (existingTarget.DomainID.HasValue)
|
||||
return Conflict("Target is already linked to a domain. Unlink it first.");
|
||||
|
||||
existingTarget.DomainID = domainId;
|
||||
|
||||
if (!_targetInterface.EditTargetById(existingTarget))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("{Id}/Domain")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult UnlinkTargetFromDomain(Guid Id)
|
||||
{
|
||||
if (!_targetInterface.CheckTargetById(Id))
|
||||
return NotFound();
|
||||
|
||||
var existingTarget = _targetInterface.GetTargetById(Id);
|
||||
if (existingTarget == null)
|
||||
return NotFound();
|
||||
|
||||
if (!existingTarget.DomainID.HasValue)
|
||||
return NoContent();
|
||||
|
||||
existingTarget.DomainID = null;
|
||||
|
||||
if (!_targetInterface.EditTargetById(existingTarget))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("{Id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult DeleteTargetById(Guid Id)
|
||||
{
|
||||
if (!_targetInterface.CheckTargetById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var target = _targetInterface.GetTargetById(Id);
|
||||
|
||||
if (!_targetInterface.DeleteTargetById(target))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while deleting");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using AutoMapper;
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateCategory.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateCategory.Edit;
|
||||
@@ -128,3 +128,4 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using AutoMapper;
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Template.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Template.Edit;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.Template.Get;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateVersion.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateVersion.Get;
|
||||
using Microsoft.SelfService.Portal.Core.API.Interfaces;
|
||||
using Microsoft.SelfService.Portal.Core.API.JsonDocuments;
|
||||
using Microsoft.SelfService.Portal.Core.API.Models;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
@@ -73,10 +76,18 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
|
||||
var templateMap = _mapper.Map<TemplateModel>(template);
|
||||
|
||||
if (!_templateInterface.AddTemplateById(templateMap))
|
||||
try
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
if (!_templateInterface.AddTemplateById(templateMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
}
|
||||
catch (ConfigurationDocumentValidationException ex)
|
||||
{
|
||||
ModelState.AddModelError(nameof(template.JSONData), ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
return Ok(templateMap.Id);
|
||||
@@ -102,10 +113,18 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
var templateMap = _mapper.Map<TemplateModel>(template);
|
||||
templateMap.Id = Id;
|
||||
|
||||
if (!_templateInterface.EditTemplateById(templateMap))
|
||||
try
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
if (!_templateInterface.EditTemplateById(templateMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
}
|
||||
catch (ConfigurationDocumentValidationException ex)
|
||||
{
|
||||
ModelState.AddModelError(nameof(template.JSONData), ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
if (!string.Equals(existingTemplate.JSONData, template.JSONData, StringComparison.Ordinal))
|
||||
@@ -138,5 +157,82 @@ namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("{Id}/Versions")]
|
||||
[ProducesResponseType(200, Type = typeof(IEnumerable<GetTemplateVersionDto>))]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult GetTemplateVersions(Guid Id)
|
||||
{
|
||||
if (!_templateInterface.CheckTemplateById(Id))
|
||||
return NotFound();
|
||||
|
||||
var versions = _mapper.Map<List<GetTemplateVersionDto>>(_templateInterface.GetTemplateVersions(Id));
|
||||
return Ok(versions);
|
||||
}
|
||||
|
||||
[HttpGet("{Id}/Versions/{VersionId}")]
|
||||
[ProducesResponseType(200, Type = typeof(GetTemplateVersionDto))]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult GetTemplateVersionById(Guid Id, Guid VersionId)
|
||||
{
|
||||
var version = _templateInterface.GetTemplateVersionById(Id, VersionId);
|
||||
if (version == null)
|
||||
return NotFound();
|
||||
|
||||
return Ok(_mapper.Map<GetTemplateVersionDto>(version));
|
||||
}
|
||||
|
||||
[HttpPost("{Id}/Versions")]
|
||||
[ProducesResponseType(200, Type = typeof(Guid))]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult AddTemplateVersion(Guid Id, [FromBody] AddTemplateVersionDto templateVersion)
|
||||
{
|
||||
if (templateVersion == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!_templateInterface.CheckTemplateById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (_templateInterface.CheckTemplateVersionByVersion(Id, templateVersion.Version))
|
||||
{
|
||||
ModelState.AddModelError(nameof(templateVersion.Version), "Template version already exists");
|
||||
return StatusCode(422, ModelState);
|
||||
}
|
||||
|
||||
var version = _mapper.Map<TemplateVersionModel>(templateVersion);
|
||||
version.PublishedBy = templateVersion.PublishedBy ?? User?.Identity?.Name ?? "System";
|
||||
|
||||
try
|
||||
{
|
||||
if (!_templateInterface.AddTemplateVersion(Id, version, templateVersion.Publish))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving template version");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
}
|
||||
catch (ConfigurationDocumentValidationException ex)
|
||||
{
|
||||
ModelState.AddModelError(nameof(templateVersion.JsonData), ex.Message);
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
return Ok(version.Id);
|
||||
}
|
||||
|
||||
[HttpPost("{Id}/Versions/{VersionId}/Publish")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult PublishTemplateVersion(Guid Id, Guid VersionId)
|
||||
{
|
||||
if (!_templateInterface.PublishTemplateVersion(Id, VersionId, User?.Identity?.Name ?? "System"))
|
||||
return NotFound();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.VirtualMachine.Add;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.VirtualMachine.Edit;
|
||||
using Microsoft.SelfService.Portal.Core.API.Dto.VirtualMachine.Get;
|
||||
using Microsoft.SelfService.Portal.Core.API.Interfaces;
|
||||
using Microsoft.SelfService.Portal.Core.API.Models;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class VirtualMachineController : Controller
|
||||
{
|
||||
private readonly IVirtualMachineInterface _virtualmachineInterface;
|
||||
private readonly IDomainInterface _domainInterface;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public VirtualMachineController(IVirtualMachineInterface virtualmachineInterface, IDomainInterface domainInterface, IMapper mapper)
|
||||
{
|
||||
_virtualmachineInterface = virtualmachineInterface;
|
||||
_domainInterface = domainInterface;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200, Type = typeof(IEnumerable<VirtualMachineModel>))]
|
||||
public IActionResult GetVirtualMachines()
|
||||
{
|
||||
var virtualMachines = _mapper.Map<List<GetVirtualMachineDto>>(_virtualmachineInterface.GetVirtualMachines());
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(virtualMachines);
|
||||
}
|
||||
|
||||
[HttpGet("{Id}")]
|
||||
[ProducesResponseType(200, Type = typeof(VirtualMachineModel))]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult GetVirtualMachineById(Guid Id)
|
||||
{
|
||||
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
|
||||
return NotFound();
|
||||
|
||||
var virtualMachine = _mapper.Map<GetVirtualMachineDetailsDto>(_virtualmachineInterface.GetVirtualMachineById(Id));
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
return Ok(virtualMachine);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(400)]
|
||||
public IActionResult AddVirtualMachineById([FromBody] AddVirtualMachineDto virtualMachine)
|
||||
{
|
||||
if (virtualMachine == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (_virtualmachineInterface.CheckVirtualMachineByName(virtualMachine.Name))
|
||||
{
|
||||
ModelState.AddModelError("", "VirtualMachine already exists");
|
||||
return StatusCode(422, ModelState);
|
||||
}
|
||||
|
||||
if (virtualMachine.DomainID.HasValue && !_domainInterface.CheckDomainById(virtualMachine.DomainID.Value))
|
||||
{
|
||||
ModelState.AddModelError("", "Domain does not exist");
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var virtualMachineMap = _mapper.Map<VirtualMachineModel>(virtualMachine);
|
||||
|
||||
if (!_virtualmachineInterface.AddVirtualMachineById(virtualMachineMap))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while saving");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return Ok(virtualMachineMap.Id);
|
||||
}
|
||||
|
||||
[HttpPut("{Id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult EditVirtualMachineById(Guid Id, [FromBody] EditVirtualMachineDto virtualMachine)
|
||||
{
|
||||
if (virtualMachine == null)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var existingVirtualMachine = _virtualmachineInterface.GetVirtualMachineById(Id);
|
||||
if (existingVirtualMachine == null)
|
||||
return NotFound();
|
||||
|
||||
existingVirtualMachine.Name = virtualMachine.Name;
|
||||
existingVirtualMachine.ExternalId = virtualMachine.ExternalId;
|
||||
existingVirtualMachine.MetadataJson = virtualMachine.MetadataJson;
|
||||
|
||||
if (!_virtualmachineInterface.EditVirtualMachineById(existingVirtualMachine))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPost("{Id}/Domain/{domainId}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
[ProducesResponseType(409)]
|
||||
public IActionResult LinkVirtualMachineToDomain(Guid Id, Guid domainId)
|
||||
{
|
||||
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!_domainInterface.CheckDomainById(domainId))
|
||||
return NotFound();
|
||||
|
||||
var existingVirtualMachine = _virtualmachineInterface.GetVirtualMachineById(Id);
|
||||
if (existingVirtualMachine == null)
|
||||
return NotFound();
|
||||
|
||||
if (existingVirtualMachine.DomainID.HasValue)
|
||||
return Conflict("VirtualMachine is already linked to a domain. Unlink it first.");
|
||||
|
||||
existingVirtualMachine.DomainID = domainId;
|
||||
|
||||
if (!_virtualmachineInterface.EditVirtualMachineById(existingVirtualMachine))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("{Id}/Domain")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult UnlinkVirtualMachineFromDomain(Guid Id)
|
||||
{
|
||||
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
|
||||
return NotFound();
|
||||
|
||||
var existingVirtualMachine = _virtualmachineInterface.GetVirtualMachineById(Id);
|
||||
if (existingVirtualMachine == null)
|
||||
return NotFound();
|
||||
|
||||
if (!existingVirtualMachine.DomainID.HasValue)
|
||||
return NoContent();
|
||||
|
||||
existingVirtualMachine.DomainID = null;
|
||||
|
||||
if (!_virtualmachineInterface.EditVirtualMachineById(existingVirtualMachine))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("{Id}")]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(404)]
|
||||
public IActionResult DeleteVirtualMachineById(Guid Id)
|
||||
{
|
||||
if (!_virtualmachineInterface.CheckVirtualMachineById(Id))
|
||||
return NotFound();
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState);
|
||||
|
||||
var virtualMachine = _virtualmachineInterface.GetVirtualMachineById(Id);
|
||||
|
||||
if (!_virtualmachineInterface.DeleteVirtualMachineById(virtualMachine))
|
||||
{
|
||||
ModelState.AddModelError("", "Something went wrong while deleting");
|
||||
return StatusCode(500, ModelState);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user