- 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.
270 lines
10 KiB
C#
270 lines
10 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.SelfService.Portal.Core.API.Context;
|
|
using Microsoft.SelfService.Portal.Core.API.Interfaces;
|
|
using Microsoft.SelfService.Portal.Core.API.Models;
|
|
using System.Text.Json;
|
|
|
|
namespace Microsoft.SelfService.Portal.Core.API.Repository
|
|
{
|
|
public class DeploymentBatchRepository : IDeploymentBatchInterface
|
|
{
|
|
private readonly DataContext _context;
|
|
|
|
public DeploymentBatchRepository(DataContext context)
|
|
{
|
|
_context = context;
|
|
}
|
|
|
|
public ICollection<DeploymentGroupModel> GetDeploymentBatches()
|
|
{
|
|
return _context.DeploymentGroups
|
|
.Include(batch => batch.TemplateSelections)
|
|
.ThenInclude(selection => selection.TemplateVersion)
|
|
.ThenInclude(version => version.Template)
|
|
.Include(batch => batch.TargetAssignments)
|
|
.ToList();
|
|
}
|
|
|
|
public DeploymentGroupModel? GetDeploymentBatchById(Guid id)
|
|
{
|
|
return _context.DeploymentGroups
|
|
.Include(t => t.Template)
|
|
.ThenInclude(tc => tc.TemplateCategory)
|
|
.ThenInclude(s => s.Service)
|
|
.Include(d => d.Deployments)
|
|
.ThenInclude(vm => vm.Target)
|
|
.Include(batch => batch.TemplateSelections)
|
|
.ThenInclude(selection => selection.TemplateVersion)
|
|
.Include(batch => batch.ParameterValues)
|
|
.Include(batch => batch.TargetAssignments)
|
|
.ThenInclude(target => target.Target)
|
|
.Where(dg => dg.Id == id).FirstOrDefault();
|
|
}
|
|
|
|
public bool AddDeploymentBatchById(DeploymentGroupModel deploymentBatch, ICollection<Guid>? targetIds)
|
|
{
|
|
if (deploymentBatch.Id == Guid.Empty)
|
|
{
|
|
deploymentBatch.Id = Guid.NewGuid();
|
|
}
|
|
|
|
var requestedTemplateVersionId = deploymentBatch.TemplateSelections
|
|
.OrderBy(selection => selection.SortOrder)
|
|
.Select(selection => (Guid?)selection.TemplateVersionId)
|
|
.FirstOrDefault();
|
|
|
|
var templateVersion = requestedTemplateVersionId.HasValue
|
|
? _context.TemplateVersions
|
|
.Include(version => version.TemplateRevisions)
|
|
.Include(version => version.Template)
|
|
.ThenInclude(template => template.TemplateCategory)
|
|
.ThenInclude(category => category.Service)
|
|
.FirstOrDefault(version => version.Id == requestedTemplateVersionId.Value)
|
|
: null;
|
|
|
|
var template = templateVersion?.Template
|
|
?? _context.Templates
|
|
.Include(existing => existing.TemplateCategory)
|
|
.ThenInclude(existing => existing.Service)
|
|
.Include(existing => existing.TemplateVersions)
|
|
.ThenInclude(version => version.TemplateRevisions)
|
|
.FirstOrDefault(existing => existing.Id == deploymentBatch.TemplateId);
|
|
|
|
if (template == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
deploymentBatch.TemplateId = template.Id;
|
|
|
|
if (deploymentBatch.DeploymentRuleId.HasValue)
|
|
{
|
|
var ruleExists = _context.DeploymentRules.Any(existing => existing.Id == deploymentBatch.DeploymentRuleId.Value);
|
|
if (!ruleExists)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
var isCloudService = template.TemplateCategory.Service.IsCloudService;
|
|
var selectedTargetIds = (targetIds ?? Array.Empty<Guid>())
|
|
.Concat(deploymentBatch.TargetAssignments.Select(assignment => assignment.TargetId))
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
if (!isCloudService && selectedTargetIds.Count == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (selectedTargetIds.Count > 0)
|
|
{
|
|
var existingTargetIds = _context.Targets
|
|
.Where(existing => selectedTargetIds.Contains(existing.Id))
|
|
.Select(existing => existing.Id)
|
|
.ToHashSet();
|
|
|
|
if (existingTargetIds.Count != selectedTargetIds.Count)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
_context.Add(deploymentBatch);
|
|
|
|
if (deploymentBatch.TemplateSelections.Count == 0)
|
|
{
|
|
templateVersion ??= template.TemplateVersions?
|
|
.OrderByDescending(version => version.IsPublished)
|
|
.ThenByDescending(version => version.PublishedAt)
|
|
.ThenByDescending(version => version.Created)
|
|
.FirstOrDefault();
|
|
|
|
if (templateVersion == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
deploymentBatch.TemplateSelections.Add(new DeploymentTemplateSelectionModel
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
DeploymentGroupId = deploymentBatch.Id,
|
|
TemplateVersionId = templateVersion.Id,
|
|
TemplateRevisionId = templateVersion.TemplateRevisions?.FirstOrDefault(revision => revision.IsCurrent)?.Id,
|
|
TemplateRole = "Service",
|
|
SortOrder = 10,
|
|
Alias = template.Name
|
|
});
|
|
}
|
|
else
|
|
{
|
|
foreach (var selection in deploymentBatch.TemplateSelections)
|
|
{
|
|
if (selection.TemplateRevisionId.HasValue)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var selectedVersion = selection.TemplateVersionId == templateVersion?.Id
|
|
? templateVersion
|
|
: _context.TemplateVersions
|
|
.Include(version => version.TemplateRevisions)
|
|
.FirstOrDefault(version => version.Id == selection.TemplateVersionId);
|
|
|
|
selection.TemplateRevisionId = selectedVersion?.TemplateRevisions
|
|
?.FirstOrDefault(revision => revision.IsCurrent)
|
|
?.Id;
|
|
}
|
|
}
|
|
|
|
if (deploymentBatch.TargetAssignments.Count == 0)
|
|
{
|
|
var sortOrder = 10;
|
|
foreach (var targetId in selectedTargetIds)
|
|
{
|
|
var targetName = _context.Targets
|
|
.Where(target => target.Id == targetId)
|
|
.Select(target => target.Name)
|
|
.FirstOrDefault();
|
|
|
|
deploymentBatch.TargetAssignments.Add(new DeploymentTargetAssignmentModel
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
DeploymentGroupId = deploymentBatch.Id,
|
|
TargetId = targetId,
|
|
RoleKey = "Node",
|
|
SortOrder = sortOrder,
|
|
NodeDataJson = JsonSerializer.Serialize(new { nodeName = targetName ?? targetId.ToString() })
|
|
});
|
|
sortOrder += 10;
|
|
}
|
|
}
|
|
|
|
if (!SaveChanges())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!isCloudService)
|
|
{
|
|
foreach (var targetId in selectedTargetIds)
|
|
{
|
|
_context.Deployments.Add(new DeploymentModel
|
|
{
|
|
DeploymentGroupId = deploymentBatch.Id,
|
|
TargetId = targetId,
|
|
TemplateRevisionId = deploymentBatch.TemplateSelections
|
|
.OrderBy(selection => selection.SortOrder)
|
|
.Select(selection => selection.TemplateRevisionId)
|
|
.FirstOrDefault(),
|
|
Status = QueueJobStatus.Pending,
|
|
JSONData = "{}"
|
|
});
|
|
}
|
|
|
|
return SaveChanges();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool DeleteDeploymentBatchById(DeploymentGroupModel deploymentBatch)
|
|
{
|
|
var templateSelections = _context.DeploymentTemplateSelections
|
|
.Where(existing => existing.DeploymentGroupId == deploymentBatch.Id)
|
|
.ToList();
|
|
var parameterValues = _context.DeploymentParameterValues
|
|
.Where(existing => existing.DeploymentGroupId == deploymentBatch.Id)
|
|
.ToList();
|
|
var targetAssignments = _context.DeploymentTargetAssignments
|
|
.Where(existing => existing.DeploymentGroupId == deploymentBatch.Id)
|
|
.ToList();
|
|
var deployments = _context.Deployments
|
|
.Where(existing => existing.DeploymentGroupId == deploymentBatch.Id)
|
|
.ToList();
|
|
|
|
if (parameterValues.Count > 0)
|
|
{
|
|
_context.DeploymentParameterValues.RemoveRange(parameterValues);
|
|
}
|
|
|
|
if (targetAssignments.Count > 0)
|
|
{
|
|
_context.DeploymentTargetAssignments.RemoveRange(targetAssignments);
|
|
}
|
|
|
|
if (templateSelections.Count > 0)
|
|
{
|
|
_context.DeploymentTemplateSelections.RemoveRange(templateSelections);
|
|
}
|
|
|
|
if (deployments.Count > 0)
|
|
{
|
|
_context.Deployments.RemoveRange(deployments);
|
|
}
|
|
|
|
_context.Remove(deploymentBatch);
|
|
return SaveChanges();
|
|
}
|
|
|
|
public bool EditDeploymentBatchById(DeploymentGroupModel deploymentBatch)
|
|
{
|
|
_context.Update(deploymentBatch);
|
|
return SaveChanges();
|
|
}
|
|
|
|
public bool CheckDeploymentBatchById(Guid id)
|
|
{
|
|
return _context.DeploymentGroups
|
|
.Any(d => d.Id == id);
|
|
}
|
|
|
|
public bool SaveChanges()
|
|
{
|
|
var saved = _context.SaveChanges();
|
|
return saved > 0 ? true : false;
|
|
}
|
|
}
|
|
}
|
|
|