mirror of
https://github.com/bitwarden/server.git
synced 2026-06-01 01:55:55 -05:00
* Use Quartz-based hosted service to clear old play data
We need to stop possible bloat of databases should users of a seeded data fail to appropriately clean up after themselves.
Using the hosted services present in other projects, this adds an alive job and play data delete job to the SeederApi
* Trigger play data delete frequently enough for dev servers
Development servers are unlikely to be running at midnight UTC, so we need to delete more frequently to ensure data is cleaned up. The Job still deletes things older than a day, it just checks much more frequently, now.
* Fixup sonarqube
* Fixup parallel test issues with jobs hosted services
* Remove alive job and unneeded fixme
* Revert "Remove alive job and unneeded fixme"
This reverts commit 0c10e4a675.
* Simplify alive job
Used the wrong job as a template, the api alive job is much more like what we want.
* Update readme to callout ephemeral data
108 lines
3.3 KiB
C#
108 lines
3.3 KiB
C#
using Bit.SeederApi.Commands.Interfaces;
|
|
using Bit.SeederApi.Execution;
|
|
using Bit.SeederApi.Models.Request;
|
|
using Bit.SeederApi.Queries.Interfaces;
|
|
using Bit.SeederApi.Services;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace Bit.SeederApi.Controllers;
|
|
|
|
[Authorize]
|
|
[Route("seed")]
|
|
public class SeedController(
|
|
ILogger<SeedController> logger,
|
|
ISceneExecutor sceneExecutor,
|
|
IDestroySceneCommand destroySceneCommand,
|
|
IDestroyBatchScenesCommand destroyBatchScenesCommand,
|
|
IGetAllPlayIdsQuery getAllPlayIdsQuery) : Controller
|
|
{
|
|
[HttpPost]
|
|
public async Task<IActionResult> SeedAsync([FromBody] SeedRequestModel request)
|
|
{
|
|
logger.LogInformation("Received seed request with template: {Template}", request.Template);
|
|
|
|
try
|
|
{
|
|
var response = await sceneExecutor.ExecuteAsync(request.Template, request.Arguments);
|
|
|
|
return Json(response);
|
|
}
|
|
catch (SceneNotFoundException ex)
|
|
{
|
|
return NotFound(new { Error = ex.Message });
|
|
}
|
|
catch (SceneExecutionException ex)
|
|
{
|
|
logger.LogError(ex, "Error executing scene: {Template}", request.Template);
|
|
return BadRequest(new { Error = ex.Message, Details = ex.InnerException?.Message });
|
|
}
|
|
}
|
|
|
|
[HttpDelete("batch")]
|
|
public async Task<IActionResult> DeleteBatchAsync([FromBody] List<string> playIds)
|
|
{
|
|
logger.LogInformation("Deleting batch of seeded data with IDs: {PlayIds}", string.Join(", ", playIds));
|
|
|
|
try
|
|
{
|
|
await destroyBatchScenesCommand.DestroyAsync(playIds);
|
|
return Ok(new { Message = "Batch delete completed successfully" });
|
|
}
|
|
catch (AggregateException ex)
|
|
{
|
|
return BadRequest(new
|
|
{
|
|
Error = ex.Message,
|
|
Details = ex.InnerExceptions.Select(e => e.Message).ToList()
|
|
});
|
|
}
|
|
}
|
|
|
|
[HttpDelete("{playId}")]
|
|
public async Task<IActionResult> DeleteAsync([FromRoute] string playId)
|
|
{
|
|
logger.LogInformation("Deleting seeded data with ID: {PlayId}", playId);
|
|
|
|
try
|
|
{
|
|
var result = await destroySceneCommand.DestroyAsync(playId);
|
|
|
|
return Json(result);
|
|
}
|
|
catch (SceneExecutionException ex)
|
|
{
|
|
logger.LogError(ex, "Error deleting seeded data: {PlayId}", playId);
|
|
return BadRequest(new { Error = ex.Message, Details = ex.InnerException?.Message });
|
|
}
|
|
}
|
|
|
|
[HttpDelete]
|
|
public async Task<IActionResult> DeleteAllAsync([FromBody] DateTime? olderThanRequest)
|
|
{
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return BadRequest(ModelState);
|
|
}
|
|
|
|
var olderThan = olderThanRequest?.ToUniversalTime() ?? DateTime.UtcNow.AddDays(-1);
|
|
logger.LogInformation("Deleting all seeded data older than {OlderThan} UTC", olderThan);
|
|
|
|
var playIds = getAllPlayIdsQuery.GetAllPlayIds(olderThan: olderThan);
|
|
|
|
try
|
|
{
|
|
await destroyBatchScenesCommand.DestroyAsync(playIds);
|
|
return NoContent();
|
|
}
|
|
catch (AggregateException ex)
|
|
{
|
|
return BadRequest(new
|
|
{
|
|
Error = ex.Message,
|
|
Details = ex.InnerExceptions.Select(e => e.Message).ToList()
|
|
});
|
|
}
|
|
}
|
|
}
|