- Added ApiClientModel and ApiTokenModel for managing API clients and tokens. - Introduced ConfigurationDefinitionModel and ConfigurationValueModel for configuration management. - Created CredentialSecretModel for storing credential secrets. - Developed DeploymentArtifactModel and DeploymentBatchModel for deployment management. - Enhanced DeploymentTargetModel and DeploymentTemplateSelectionModel to support template revisions. - Added TemplateRevisionModel and TemplateVersionModel for versioning templates. - Implemented ApiClientSecretHasher for secure secret hashing. - Created ApiTokenService for generating and validating JWT tokens. - Updated QueueJobService to handle deployment requests with artifacts. - Configured authentication settings in appsettings.json for JWT and Negotiate authentication.
313 lines
12 KiB
C#
313 lines
12 KiB
C#
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.ConfigurationDefinition.Get;
|
|
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateRevision.Add;
|
|
using Microsoft.SelfService.Portal.Core.API.Dto.TemplateRevision.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
|
|
{
|
|
[Route("api/[controller]")]
|
|
[ApiController]
|
|
public class TemplateController : Controller
|
|
{
|
|
private readonly ITemplateInterface _templateInterface;
|
|
private readonly IQueueJobService _queueJobService;
|
|
private readonly IMapper _mapper;
|
|
|
|
public TemplateController(
|
|
ITemplateInterface templateInterface,
|
|
IQueueJobService queueJobService,
|
|
IMapper mapper)
|
|
{
|
|
_templateInterface = templateInterface;
|
|
_queueJobService = queueJobService;
|
|
_mapper = mapper;
|
|
}
|
|
|
|
[HttpGet]
|
|
[ProducesResponseType(200, Type = typeof(IEnumerable<TemplateModel>))]
|
|
public IActionResult GetTemplates()
|
|
{
|
|
var templates = _mapper.Map<List<GetTemplateDto>>(_templateInterface.GetTemplates());
|
|
|
|
if (!ModelState.IsValid)
|
|
return BadRequest(ModelState);
|
|
|
|
return Ok(templates);
|
|
}
|
|
|
|
[HttpGet("{Id}")]
|
|
[ProducesResponseType(200, Type = typeof(TemplateModel))]
|
|
[ProducesResponseType(404)]
|
|
public IActionResult GetTemplateById(Guid Id)
|
|
{
|
|
if (!_templateInterface.CheckTemplateById(Id))
|
|
return NotFound();
|
|
|
|
var template = _mapper.Map<GetTemplateDetailsDto>(_templateInterface.GetTemplateById(Id));
|
|
|
|
if (!ModelState.IsValid)
|
|
return BadRequest(ModelState);
|
|
|
|
return Ok(template);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ProducesResponseType(200)]
|
|
[ProducesResponseType(400)]
|
|
public IActionResult AddTemplateById([FromBody] AddTemplateDto template)
|
|
{
|
|
if (template == null)
|
|
return BadRequest(ModelState);
|
|
|
|
if (_templateInterface.CheckTemplateByName(template.Name))
|
|
{
|
|
ModelState.AddModelError("", "Template already exists");
|
|
return StatusCode(422, ModelState);
|
|
}
|
|
|
|
if (!ModelState.IsValid)
|
|
return BadRequest(ModelState);
|
|
|
|
var templateMap = _mapper.Map<TemplateModel>(template);
|
|
|
|
try
|
|
{
|
|
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);
|
|
}
|
|
|
|
[HttpPut("{Id}")]
|
|
[ProducesResponseType(204)]
|
|
[ProducesResponseType(400)]
|
|
[ProducesResponseType(404)]
|
|
public IActionResult EditTemplateById(Guid Id, [FromBody] EditTemplateDto template)
|
|
{
|
|
if (template == null)
|
|
return BadRequest(ModelState);
|
|
|
|
if (!_templateInterface.CheckTemplateById(Id))
|
|
return NotFound();
|
|
|
|
var existingTemplate = _templateInterface.GetTemplateById(Id);
|
|
|
|
if (!ModelState.IsValid)
|
|
return BadRequest(ModelState);
|
|
|
|
var templateMap = _mapper.Map<TemplateModel>(template);
|
|
templateMap.Id = Id;
|
|
|
|
try
|
|
{
|
|
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))
|
|
{
|
|
_queueJobService.EnqueueTemplateJsonChanged(Id, existingTemplate.JSONData, template.JSONData);
|
|
}
|
|
|
|
return NoContent();
|
|
}
|
|
|
|
[HttpDelete("{Id}")]
|
|
[ProducesResponseType(204)]
|
|
[ProducesResponseType(400)]
|
|
[ProducesResponseType(404)]
|
|
public IActionResult DeleteTemplateById(Guid Id)
|
|
{
|
|
if (!_templateInterface.CheckTemplateById(Id))
|
|
return NotFound();
|
|
|
|
if (!ModelState.IsValid)
|
|
return BadRequest(ModelState);
|
|
|
|
var template = _templateInterface.GetTemplateById(Id);
|
|
|
|
if (!_templateInterface.DeleteTemplateById(template))
|
|
{
|
|
ModelState.AddModelError("", "Something went wrong while deleting");
|
|
return StatusCode(500, ModelState);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
[HttpGet("{Id}/Versions/{VersionId}/Revisions")]
|
|
[ProducesResponseType(200, Type = typeof(IEnumerable<GetTemplateRevisionDto>))]
|
|
[ProducesResponseType(404)]
|
|
public IActionResult GetTemplateRevisions(Guid Id, Guid VersionId)
|
|
{
|
|
if (!_templateInterface.CheckTemplateVersionById(Id, VersionId))
|
|
return NotFound();
|
|
|
|
return Ok(_mapper.Map<List<GetTemplateRevisionDto>>(_templateInterface.GetTemplateRevisions(Id, VersionId)));
|
|
}
|
|
|
|
[HttpGet("{Id}/Versions/{VersionId}/Revisions/{RevisionId}")]
|
|
[ProducesResponseType(200, Type = typeof(GetTemplateRevisionDto))]
|
|
[ProducesResponseType(404)]
|
|
public IActionResult GetTemplateRevisionById(Guid Id, Guid VersionId, Guid RevisionId)
|
|
{
|
|
var revision = _templateInterface.GetTemplateRevisionById(Id, VersionId, RevisionId);
|
|
if (revision == null)
|
|
return NotFound();
|
|
|
|
return Ok(_mapper.Map<GetTemplateRevisionDto>(revision));
|
|
}
|
|
|
|
[HttpGet("{Id}/Versions/{VersionId}/Revisions/{RevisionId}/Definitions")]
|
|
[ProducesResponseType(200, Type = typeof(IEnumerable<GetConfigurationDefinitionDto>))]
|
|
[ProducesResponseType(404)]
|
|
public IActionResult GetTemplateRevisionDefinitions(Guid Id, Guid VersionId, Guid RevisionId)
|
|
{
|
|
var revision = _templateInterface.GetTemplateRevisionById(Id, VersionId, RevisionId);
|
|
if (revision == null)
|
|
return NotFound();
|
|
|
|
return Ok(_mapper.Map<List<GetConfigurationDefinitionDto>>(revision.ConfigurationDefinitions));
|
|
}
|
|
|
|
[HttpPost("{Id}/Versions/{VersionId}/Revisions")]
|
|
[ProducesResponseType(200, Type = typeof(Guid))]
|
|
[ProducesResponseType(400)]
|
|
[ProducesResponseType(404)]
|
|
public IActionResult AddTemplateRevision(Guid Id, Guid VersionId, [FromBody] AddTemplateRevisionDto templateRevision)
|
|
{
|
|
if (templateRevision == null)
|
|
return BadRequest(ModelState);
|
|
|
|
if (!_templateInterface.CheckTemplateVersionById(Id, VersionId))
|
|
return NotFound();
|
|
|
|
if (!ModelState.IsValid)
|
|
return BadRequest(ModelState);
|
|
|
|
var revision = _mapper.Map<TemplateRevisionModel>(templateRevision);
|
|
revision.PublishedBy = templateRevision.PublishedBy ?? User?.Identity?.Name ?? "System";
|
|
|
|
try
|
|
{
|
|
if (!_templateInterface.AddTemplateRevision(Id, VersionId, revision, templateRevision.Publish))
|
|
{
|
|
ModelState.AddModelError("", "Something went wrong while saving template revision");
|
|
return StatusCode(500, ModelState);
|
|
}
|
|
}
|
|
catch (ConfigurationDocumentValidationException ex)
|
|
{
|
|
ModelState.AddModelError(nameof(templateRevision.JsonData), ex.Message);
|
|
return BadRequest(ModelState);
|
|
}
|
|
|
|
var savedRevision = _templateInterface.GetCurrentTemplateRevision(VersionId);
|
|
return Ok(savedRevision?.Id ?? revision.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();
|
|
}
|
|
}
|
|
}
|
|
|