Refactor code structure for improved readability and maintainability

This commit is contained in:
Torsten Brendgen
2026-07-07 23:27:57 +02:00
parent 96a3e98109
commit bbe521b38d
1632 changed files with 27313 additions and 54917 deletions
-27
View File
@@ -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);
}
}
}
+394
View File
@@ -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;
}
}
}
+60 -22
View File
@@ -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();
}
}
}
-125
View File
@@ -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();
}
}
}
+184
View File
@@ -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()
};
}
}
}
+4 -3
View File
@@ -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
}
}
}
+29 -1
View File
@@ -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
}
}
}
-113
View File
@@ -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();
}
}
}
+2 -1
View File
@@ -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
}
}
}
+203
View File
@@ -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();
}
}
}
+2 -1
View File
@@ -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
}
}
}
+103 -7
View File
@@ -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();
}
}
}
-200
View File
@@ -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();
}
}
}