2020-05-27 05:11:20 +12:00
|
|
|
<?php
|
|
|
|
|
2022-11-22 03:24:52 +13:00
|
|
|
use Appwrite\Auth\Auth;
|
2021-11-25 17:59:38 +13:00
|
|
|
use Utopia\App;
|
2022-07-24 05:42:42 +12:00
|
|
|
use Utopia\Cache\Adapter\Filesystem;
|
|
|
|
use Utopia\Cache\Cache;
|
2021-07-14 07:24:52 +12:00
|
|
|
use Utopia\Database\Database;
|
|
|
|
use Utopia\Database\Document;
|
2021-07-13 09:57:37 +12:00
|
|
|
use Utopia\Database\Query;
|
2021-06-12 02:20:18 +12:00
|
|
|
use Appwrite\Resque\Worker;
|
2020-12-19 03:08:28 +13:00
|
|
|
use Utopia\Abuse\Abuse;
|
|
|
|
use Utopia\Abuse\Adapters\TimeLimit;
|
2020-12-05 09:47:02 +13:00
|
|
|
use Utopia\CLI\Console;
|
2020-12-18 04:15:47 +13:00
|
|
|
use Utopia\Audit\Audit;
|
2022-11-22 03:24:52 +13:00
|
|
|
use Utopia\Database\DateTime;
|
2020-05-27 05:11:20 +12:00
|
|
|
|
2021-11-20 05:46:10 +13:00
|
|
|
require_once __DIR__ . '/../init.php';
|
2020-12-19 21:08:03 +13:00
|
|
|
|
2021-01-15 19:02:48 +13:00
|
|
|
Console::title('Deletes V1 Worker');
|
2021-09-01 21:13:23 +12:00
|
|
|
Console::success(APP_NAME . ' deletes worker v1 has started' . "\n");
|
2020-12-19 21:08:03 +13:00
|
|
|
|
2021-06-12 02:20:18 +12:00
|
|
|
class DeletesV1 extends Worker
|
2020-05-27 05:11:20 +12:00
|
|
|
{
|
2022-05-16 21:58:17 +12:00
|
|
|
public function getName(): string
|
|
|
|
{
|
2021-11-24 03:24:25 +13:00
|
|
|
return "deletes";
|
|
|
|
}
|
|
|
|
|
2021-06-12 02:20:18 +12:00
|
|
|
public function init(): void
|
2020-05-27 05:11:20 +12:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-12 02:20:18 +12:00
|
|
|
public function run(): void
|
|
|
|
{
|
2022-04-14 00:39:31 +12:00
|
|
|
$project = new Document($this->args['project'] ?? []);
|
2021-06-12 22:07:26 +12:00
|
|
|
$type = $this->args['type'] ?? '';
|
2020-12-19 01:28:08 +13:00
|
|
|
switch (strval($type)) {
|
2020-12-19 03:05:15 +13:00
|
|
|
case DELETE_TYPE_DOCUMENT:
|
2021-11-20 05:46:10 +13:00
|
|
|
$document = new Document($this->args['document'] ?? []);
|
|
|
|
|
2021-06-12 22:07:26 +12:00
|
|
|
switch ($document->getCollection()) {
|
2022-06-22 22:51:49 +12:00
|
|
|
case DELETE_TYPE_DATABASES:
|
2022-08-13 19:57:04 +12:00
|
|
|
$this->deleteDatabase($document, $project);
|
2022-06-22 22:51:49 +12:00
|
|
|
break;
|
2021-10-26 13:14:55 +13:00
|
|
|
case DELETE_TYPE_COLLECTIONS:
|
2022-08-13 19:57:04 +12:00
|
|
|
$this->deleteCollection($document, $project);
|
2021-09-03 04:45:03 +12:00
|
|
|
break;
|
2021-10-26 13:14:55 +13:00
|
|
|
case DELETE_TYPE_PROJECTS:
|
2020-12-19 01:28:08 +13:00
|
|
|
$this->deleteProject($document);
|
|
|
|
break;
|
2021-10-26 13:14:55 +13:00
|
|
|
case DELETE_TYPE_FUNCTIONS:
|
2022-08-13 19:57:04 +12:00
|
|
|
$this->deleteFunction($document, $project);
|
2020-12-19 01:28:08 +13:00
|
|
|
break;
|
2022-01-28 12:36:30 +13:00
|
|
|
case DELETE_TYPE_DEPLOYMENTS:
|
2022-08-13 19:57:04 +12:00
|
|
|
$this->deleteDeployment($document, $project);
|
2022-01-28 12:36:30 +13:00
|
|
|
break;
|
2021-10-26 13:14:55 +13:00
|
|
|
case DELETE_TYPE_USERS:
|
2022-08-13 19:57:04 +12:00
|
|
|
$this->deleteUser($document, $project);
|
2020-12-19 01:28:08 +13:00
|
|
|
break;
|
2021-10-26 13:14:55 +13:00
|
|
|
case DELETE_TYPE_TEAMS:
|
2022-08-13 19:57:04 +12:00
|
|
|
$this->deleteMemberships($document, $project);
|
2023-04-11 23:49:45 +12:00
|
|
|
if ($project->getId() === 'console') {
|
|
|
|
$this->deleteProjectsByTeam($document);
|
|
|
|
}
|
2021-05-12 05:55:38 +12:00
|
|
|
break;
|
2021-11-07 18:54:28 +13:00
|
|
|
case DELETE_TYPE_BUCKETS:
|
2022-08-13 19:57:04 +12:00
|
|
|
$this->deleteBucket($document, $project);
|
2023-05-22 22:58:13 +12:00
|
|
|
break;
|
|
|
|
case DELETE_TYPE_INSTALLATIONS:
|
|
|
|
$this->deleteInstallation($document, $project);
|
|
|
|
break;
|
2023-03-10 20:42:52 +13:00
|
|
|
case DELETE_TYPE_RULES:
|
|
|
|
$this->deleteRule($document, $project);
|
2021-07-28 22:09:29 +12:00
|
|
|
break;
|
2020-12-19 01:28:08 +13:00
|
|
|
default:
|
2023-01-11 17:20:43 +13:00
|
|
|
if (\str_starts_with($document->getCollection(), 'database_')) {
|
2023-07-20 23:53:36 +12:00
|
|
|
$this->deleteCollection($document, $project);
|
2023-01-11 17:20:43 +13:00
|
|
|
break;
|
|
|
|
}
|
2021-09-01 21:13:23 +12:00
|
|
|
Console::error('No lazy delete operation available for document of type: ' . $document->getCollection());
|
2020-12-19 01:28:08 +13:00
|
|
|
break;
|
|
|
|
}
|
2020-12-15 10:26:37 +13:00
|
|
|
break;
|
2020-12-22 07:15:52 +13:00
|
|
|
|
2020-12-28 06:57:35 +13:00
|
|
|
case DELETE_TYPE_EXECUTIONS:
|
2022-07-12 03:12:41 +12:00
|
|
|
$this->deleteExecutionLogs($this->args['datetime']);
|
2020-12-22 07:15:52 +13:00
|
|
|
break;
|
|
|
|
|
2020-12-19 03:05:15 +13:00
|
|
|
case DELETE_TYPE_AUDIT:
|
2022-07-12 03:12:41 +12:00
|
|
|
$datetime = $this->args['datetime'] ?? null;
|
|
|
|
if (!empty($datetime)) {
|
|
|
|
$this->deleteAuditLogs($datetime);
|
2022-01-03 23:29:15 +13:00
|
|
|
}
|
|
|
|
|
2022-07-12 03:12:41 +12:00
|
|
|
$document = new Document($this->args['document'] ?? []);
|
|
|
|
|
2022-01-03 23:29:15 +13:00
|
|
|
if (!$document->isEmpty()) {
|
2022-08-13 19:57:04 +12:00
|
|
|
$this->deleteAuditLogsByResource('document/' . $document->getId(), $project);
|
2022-01-03 23:29:15 +13:00
|
|
|
}
|
|
|
|
|
2020-12-05 09:47:02 +13:00
|
|
|
break;
|
2020-12-19 01:28:08 +13:00
|
|
|
|
2020-12-19 03:05:15 +13:00
|
|
|
case DELETE_TYPE_ABUSE:
|
2022-07-12 03:12:41 +12:00
|
|
|
$this->deleteAbuseLogs($this->args['datetime']);
|
2020-05-27 05:11:20 +12:00
|
|
|
break;
|
2021-02-05 23:57:43 +13:00
|
|
|
|
2021-06-16 21:35:37 +12:00
|
|
|
case DELETE_TYPE_REALTIME:
|
2022-07-12 03:12:41 +12:00
|
|
|
$this->deleteRealtimeUsage($this->args['datetime']);
|
2021-06-16 21:35:37 +12:00
|
|
|
break;
|
|
|
|
|
2022-06-02 22:20:03 +12:00
|
|
|
case DELETE_TYPE_SESSIONS:
|
2022-11-22 03:24:52 +13:00
|
|
|
$this->deleteExpiredSessions();
|
2022-06-02 22:20:03 +12:00
|
|
|
break;
|
|
|
|
|
2021-09-16 03:28:40 +12:00
|
|
|
case DELETE_TYPE_USAGE:
|
2022-11-22 03:24:52 +13:00
|
|
|
$this->deleteUsageStats($this->args['hourlyUsageRetentionDatetime']);
|
2021-09-06 21:39:36 +12:00
|
|
|
break;
|
2022-07-03 21:36:59 +12:00
|
|
|
|
2022-08-15 21:05:41 +12:00
|
|
|
case DELETE_TYPE_CACHE_BY_RESOURCE:
|
2023-06-13 20:15:38 +12:00
|
|
|
$this->deleteCacheByResource($project, $this->args['resource']);
|
2022-08-15 21:05:41 +12:00
|
|
|
break;
|
|
|
|
case DELETE_TYPE_CACHE_BY_TIMESTAMP:
|
2023-06-13 20:15:38 +12:00
|
|
|
$this->deleteCacheByDate($this->args['datetime']);
|
2022-07-03 21:36:59 +12:00
|
|
|
break;
|
2022-11-17 01:51:43 +13:00
|
|
|
case DELETE_TYPE_SCHEDULES:
|
|
|
|
$this->deleteSchedules($this->args['datetime']);
|
|
|
|
break;
|
2023-03-15 00:13:03 +13:00
|
|
|
case DELETE_TYPE_RUNTIMES:
|
|
|
|
$function = $this->args['function'] == null ? null : new Document($this->args['function']);
|
|
|
|
$this->deleteRuntimes($function, $project);
|
|
|
|
break;
|
2020-12-19 21:08:03 +13:00
|
|
|
default:
|
2021-09-01 21:13:23 +12:00
|
|
|
Console::error('No delete operation for type: ' . $type);
|
2020-12-19 21:08:03 +13:00
|
|
|
break;
|
2021-09-01 21:13:23 +12:00
|
|
|
}
|
2020-05-27 05:11:20 +12:00
|
|
|
}
|
|
|
|
|
2021-06-12 02:20:18 +12:00
|
|
|
public function shutdown(): void
|
2020-05-27 05:11:20 +12:00
|
|
|
{
|
|
|
|
}
|
2021-09-01 21:13:23 +12:00
|
|
|
|
2022-11-17 01:51:43 +13:00
|
|
|
/**
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
protected function deleteSchedules(string $datetime): void
|
|
|
|
{
|
2022-12-14 21:44:40 +13:00
|
|
|
$this->listByGroup(
|
2022-11-17 03:31:49 +13:00
|
|
|
'schedules',
|
|
|
|
[
|
2022-11-17 01:51:43 +13:00
|
|
|
Query::equal('region', [App::getEnv('_APP_REGION', 'default')]),
|
|
|
|
Query::equal('resourceType', ['function']),
|
|
|
|
Query::lessThanEqual('resourceUpdatedAt', $datetime),
|
|
|
|
Query::equal('active', [false]),
|
2022-11-17 03:31:49 +13:00
|
|
|
],
|
|
|
|
$this->getConsoleDB(),
|
|
|
|
function (Document $document) {
|
|
|
|
$project = $this->getConsoleDB()->getDocument('projects', $document->getAttribute('projectId'));
|
2022-11-17 01:51:43 +13:00
|
|
|
|
|
|
|
if ($project->isEmpty()) {
|
2023-07-18 22:10:56 +12:00
|
|
|
$this->getConsoleDB()->deleteDocument('schedules', $document->getId());
|
|
|
|
Console::success('Deleted schedule for deleted project ' . $document->getAttribute('projectId'));
|
2022-11-17 03:31:49 +13:00
|
|
|
return;
|
2022-11-17 01:51:43 +13:00
|
|
|
}
|
|
|
|
|
2022-11-17 03:31:49 +13:00
|
|
|
$function = $this->getProjectDB($project)->getDocument('functions', $document->getAttribute('resourceId'));
|
2022-11-17 01:51:43 +13:00
|
|
|
|
|
|
|
if ($function->isEmpty()) {
|
2022-11-17 03:31:49 +13:00
|
|
|
$this->getConsoleDB()->deleteDocument('schedules', $document->getId());
|
2023-07-18 22:10:56 +12:00
|
|
|
Console::success('Deleted schedule for function ' . $document->getAttribute('resourceId'));
|
2022-11-17 01:51:43 +13:00
|
|
|
}
|
|
|
|
}
|
2022-11-17 03:31:49 +13:00
|
|
|
);
|
2022-11-17 01:51:43 +13:00
|
|
|
}
|
|
|
|
|
2022-07-03 21:36:59 +12:00
|
|
|
/**
|
2023-06-13 20:15:38 +12:00
|
|
|
* @param Document $project
|
2022-09-28 04:29:50 +13:00
|
|
|
* @param string $resource
|
2023-06-13 20:15:38 +12:00
|
|
|
* @throws Exception
|
2022-07-03 21:36:59 +12:00
|
|
|
*/
|
2023-06-13 20:15:38 +12:00
|
|
|
protected function deleteCacheByResource(Document $project, string $resource): void
|
2022-08-15 21:05:41 +12:00
|
|
|
{
|
2023-06-13 20:15:38 +12:00
|
|
|
$projectId = $project->getId();
|
2023-06-14 02:03:33 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2023-06-13 20:15:38 +12:00
|
|
|
$document = $dbForProject->findOne('cache', [Query::equal('resource', [$resource])]);
|
2022-08-15 21:05:41 +12:00
|
|
|
|
2023-06-13 22:41:54 +12:00
|
|
|
if ($document) {
|
|
|
|
$cache = new Cache(
|
|
|
|
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId)
|
|
|
|
);
|
2023-06-13 20:15:38 +12:00
|
|
|
|
2023-06-13 22:41:54 +12:00
|
|
|
$this->deleteById(
|
|
|
|
$document,
|
|
|
|
$dbForProject,
|
|
|
|
function ($document) use ($cache, $projectId) {
|
|
|
|
$path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId();
|
|
|
|
|
|
|
|
if ($cache->purge($document->getId())) {
|
|
|
|
Console::success('Deleting cache file: ' . $path);
|
|
|
|
} else {
|
|
|
|
Console::error('Failed to delete cache file: ' . $path);
|
|
|
|
}
|
2023-06-13 20:15:38 +12:00
|
|
|
}
|
2023-06-13 22:41:54 +12:00
|
|
|
);
|
|
|
|
}
|
2022-08-15 21:05:41 +12:00
|
|
|
}
|
|
|
|
|
2023-06-13 20:15:38 +12:00
|
|
|
/**
|
|
|
|
* @param string $datetime
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
protected function deleteCacheByDate(string $datetime): void
|
2022-07-03 21:36:59 +12:00
|
|
|
{
|
2023-06-14 02:03:33 +12:00
|
|
|
$this->deleteForProjectIds(function (Document $project) use ($datetime) {
|
2022-09-28 04:29:50 +13:00
|
|
|
$projectId = $project->getId();
|
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2022-07-24 05:42:42 +12:00
|
|
|
$cache = new Cache(
|
|
|
|
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId)
|
|
|
|
);
|
2022-07-03 21:36:59 +12:00
|
|
|
|
2023-06-13 20:15:38 +12:00
|
|
|
$query = [
|
|
|
|
Query::lessThan('accessedAt', $datetime),
|
|
|
|
];
|
|
|
|
|
2022-07-05 19:37:46 +12:00
|
|
|
$this->deleteByGroup(
|
2022-07-24 19:12:15 +12:00
|
|
|
'cache',
|
2022-08-15 21:05:41 +12:00
|
|
|
$query,
|
2022-07-05 19:37:46 +12:00
|
|
|
$dbForProject,
|
2022-07-24 05:42:42 +12:00
|
|
|
function (Document $document) use ($cache, $projectId) {
|
2022-07-27 00:50:33 +12:00
|
|
|
$path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId();
|
2022-07-24 05:42:42 +12:00
|
|
|
|
|
|
|
if ($cache->purge($document->getId())) {
|
2022-07-03 21:36:59 +12:00
|
|
|
Console::success('Deleting cache file: ' . $path);
|
|
|
|
} else {
|
2022-07-10 06:24:28 +12:00
|
|
|
Console::error('Failed to delete cache file: ' . $path);
|
2022-07-03 21:36:59 +12:00
|
|
|
}
|
2022-07-05 19:37:46 +12:00
|
|
|
}
|
|
|
|
);
|
2022-07-03 21:36:59 +12:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-06-13 20:15:38 +12:00
|
|
|
|
2022-06-22 22:51:49 +12:00
|
|
|
/**
|
|
|
|
* @param Document $document database document
|
2023-06-13 20:15:38 +12:00
|
|
|
* @param Document $project
|
2022-06-22 22:51:49 +12:00
|
|
|
*/
|
2022-08-13 19:57:04 +12:00
|
|
|
protected function deleteDatabase(Document $document, Document $project): void
|
2022-06-22 22:51:49 +12:00
|
|
|
{
|
|
|
|
$databaseId = $document->getId();
|
2022-08-13 19:57:04 +12:00
|
|
|
$projectId = $project->getId();
|
2022-06-22 22:51:49 +12:00
|
|
|
|
2022-08-13 19:57:04 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2022-06-22 22:51:49 +12:00
|
|
|
|
2022-09-28 04:29:50 +13:00
|
|
|
$this->deleteByGroup('database_' . $document->getInternalId(), [], $dbForProject, function ($document) use ($project) {
|
|
|
|
$this->deleteCollection($document, $project);
|
2022-06-22 22:51:49 +12:00
|
|
|
});
|
|
|
|
|
|
|
|
$dbForProject->deleteCollection('database_' . $document->getInternalId());
|
|
|
|
|
2022-09-28 04:29:50 +13:00
|
|
|
$this->deleteAuditLogsByResource('database/' . $databaseId, $project);
|
2022-06-22 22:51:49 +12:00
|
|
|
}
|
|
|
|
|
2021-09-03 04:45:03 +12:00
|
|
|
/**
|
|
|
|
* @param Document $document teams document
|
2022-08-13 19:57:04 +12:00
|
|
|
* @param Document $project
|
2021-09-03 04:45:03 +12:00
|
|
|
*/
|
2022-08-13 19:57:04 +12:00
|
|
|
protected function deleteCollection(Document $document, Document $project): void
|
2020-12-05 09:47:02 +13:00
|
|
|
{
|
|
|
|
$collectionId = $document->getId();
|
2023-06-23 23:52:19 +12:00
|
|
|
$collectionInternalId = $document->getInternalId();
|
2022-10-12 11:49:59 +13:00
|
|
|
$databaseId = $document->getAttribute('databaseId');
|
|
|
|
$databaseInternalId = $document->getAttribute('databaseInternalId');
|
2021-09-01 21:13:23 +12:00
|
|
|
|
2022-08-13 19:57:04 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2021-09-03 04:45:03 +12:00
|
|
|
|
2023-04-06 15:40:39 +12:00
|
|
|
$relationships = \array_filter(
|
|
|
|
$document->getAttribute('attributes'),
|
|
|
|
fn ($attribute) => $attribute['type'] === Database::VAR_RELATIONSHIP
|
|
|
|
);
|
|
|
|
|
|
|
|
foreach ($relationships as $relationship) {
|
|
|
|
if (!$relationship['twoWay']) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$relatedCollection = $dbForProject->getDocument('database_' . $databaseInternalId, $relationship['relatedCollection']);
|
|
|
|
$dbForProject->deleteDocument('attributes', $databaseInternalId . '_' . $relatedCollection->getInternalId() . '_' . $relationship['twoWayKey']);
|
|
|
|
$dbForProject->deleteCachedDocument('database_' . $databaseInternalId, $relatedCollection->getId());
|
|
|
|
$dbForProject->deleteCachedCollection('database_' . $databaseInternalId . '_collection_' . $relatedCollection->getInternalId());
|
|
|
|
}
|
|
|
|
|
2022-10-12 11:49:59 +13:00
|
|
|
$dbForProject->deleteCollection('database_' . $databaseInternalId . '_collection_' . $document->getInternalId());
|
2021-12-16 09:16:11 +13:00
|
|
|
|
2021-09-03 04:45:03 +12:00
|
|
|
$this->deleteByGroup('attributes', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('databaseInternalId', [$databaseInternalId]),
|
|
|
|
Query::equal('collectionInternalId', [$collectionInternalId])
|
2021-12-28 01:45:23 +13:00
|
|
|
], $dbForProject);
|
2021-09-03 04:45:03 +12:00
|
|
|
|
|
|
|
$this->deleteByGroup('indexes', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('databaseInternalId', [$databaseInternalId]),
|
|
|
|
Query::equal('collectionInternalId', [$collectionInternalId])
|
2021-12-28 01:45:23 +13:00
|
|
|
], $dbForProject);
|
2022-01-03 23:29:15 +13:00
|
|
|
|
2022-10-18 20:57:34 +13:00
|
|
|
$this->deleteAuditLogsByResource('database/' . $databaseId . '/collection/' . $collectionId, $project);
|
2020-12-05 09:47:02 +13:00
|
|
|
}
|
2020-05-27 05:11:20 +12:00
|
|
|
|
2021-08-27 23:37:52 +12:00
|
|
|
/**
|
2022-10-28 21:40:04 +13:00
|
|
|
* @param string $hourlyUsageRetentionDatetime
|
2023-01-11 19:37:06 +13:00
|
|
|
* @throws Exception
|
2021-08-27 23:37:52 +12:00
|
|
|
*/
|
2022-10-28 21:40:04 +13:00
|
|
|
protected function deleteUsageStats(string $hourlyUsageRetentionDatetime)
|
2021-09-01 21:13:23 +12:00
|
|
|
{
|
2022-10-31 19:49:37 +13:00
|
|
|
$this->deleteForProjectIds(function (Document $project) use ($hourlyUsageRetentionDatetime) {
|
2022-08-13 19:57:04 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2021-08-27 23:37:52 +12:00
|
|
|
// Delete Usage stats
|
|
|
|
$this->deleteByGroup('stats', [
|
2022-10-28 21:40:04 +13:00
|
|
|
Query::lessThan('time', $hourlyUsageRetentionDatetime),
|
2022-10-23 17:46:23 +13:00
|
|
|
Query::equal('period', ['1h']),
|
2021-12-28 01:45:23 +13:00
|
|
|
], $dbForProject);
|
2021-08-27 23:37:52 +12:00
|
|
|
});
|
|
|
|
}
|
2021-11-20 05:46:10 +13:00
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
|
|
|
* @param Document $document teams document
|
2022-08-13 19:57:04 +12:00
|
|
|
* @param Document $project
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2022-08-13 19:57:04 +12:00
|
|
|
protected function deleteMemberships(Document $document, Document $project): void
|
2021-08-27 16:37:15 +12:00
|
|
|
{
|
2023-07-18 11:42:46 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2023-06-23 23:52:19 +12:00
|
|
|
$teamInternalId = $document->getInternalId();
|
2021-07-14 04:08:52 +12:00
|
|
|
|
2021-05-12 05:55:38 +12:00
|
|
|
// Delete Memberships
|
2023-07-18 11:42:46 +12:00
|
|
|
$this->deleteByGroup(
|
|
|
|
'memberships',
|
|
|
|
[
|
|
|
|
Query::equal('teamInternalId', [$teamInternalId])
|
|
|
|
],
|
|
|
|
$dbForProject,
|
|
|
|
function (Document $membership) use ($dbForProject) {
|
|
|
|
$userId = $membership->getAttribute('userId');
|
|
|
|
$dbForProject->deleteCachedDocument('users', $userId);
|
|
|
|
}
|
|
|
|
);
|
2021-05-12 05:55:38 +12:00
|
|
|
}
|
|
|
|
|
2023-04-11 23:49:45 +12:00
|
|
|
/**
|
|
|
|
* @param \Utopia\Database\Document $document
|
|
|
|
* @return void
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
|
|
|
protected function deleteProjectsByTeam(Document $document): void
|
|
|
|
{
|
|
|
|
$dbForConsole = $this->getConsoleDB();
|
|
|
|
|
|
|
|
$projects = $dbForConsole->find('projects', [
|
|
|
|
Query::equal('teamInternalId', [$document->getInternalId()])
|
|
|
|
]);
|
|
|
|
|
|
|
|
foreach ($projects as $project) {
|
|
|
|
$this->deleteProject($project);
|
2023-07-28 13:29:23 +12:00
|
|
|
$dbForConsole->deleteDocument('projects', $project->getId());
|
2023-04-11 23:49:45 +12:00
|
|
|
}
|
2021-05-12 05:55:38 +12:00
|
|
|
}
|
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
|
|
|
* @param Document $document project document
|
2023-01-11 19:37:06 +13:00
|
|
|
* @throws Exception
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2021-08-27 16:37:15 +12:00
|
|
|
protected function deleteProject(Document $document): void
|
2020-05-27 05:11:20 +12:00
|
|
|
{
|
2021-07-14 06:44:45 +12:00
|
|
|
$projectId = $document->getId();
|
2023-04-28 03:37:14 +12:00
|
|
|
$projectInternalId = $document->getInternalId();
|
2021-11-20 05:46:10 +13:00
|
|
|
|
2023-04-28 03:37:14 +12:00
|
|
|
// Delete project certificates
|
2023-01-27 16:46:38 +13:00
|
|
|
$dbForConsole = $this->getConsoleDB();
|
|
|
|
|
|
|
|
$domains = $dbForConsole->find('domains', [
|
2023-04-28 03:37:14 +12:00
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
2023-01-27 16:46:38 +13:00
|
|
|
]);
|
|
|
|
|
|
|
|
foreach ($domains as $domain) {
|
|
|
|
$this->deleteCertificates($domain);
|
|
|
|
}
|
|
|
|
|
2023-01-11 19:37:06 +13:00
|
|
|
// Delete project tables
|
2023-07-20 23:53:36 +12:00
|
|
|
$dbForProject = $this->getProjectDB($document);
|
2023-01-11 19:37:06 +13:00
|
|
|
|
|
|
|
while (true) {
|
2023-01-17 17:31:14 +13:00
|
|
|
$collections = $dbForProject->listCollections();
|
2023-01-11 19:37:06 +13:00
|
|
|
|
|
|
|
if (empty($collections)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($collections as $collection) {
|
|
|
|
$dbForProject->deleteCollection($collection->getId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-28 03:37:14 +12:00
|
|
|
// Delete Platforms
|
|
|
|
$this->deleteByGroup('platforms', [
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
|
|
|
], $dbForConsole);
|
|
|
|
|
|
|
|
// Delete Domains
|
|
|
|
$this->deleteByGroup('domains', [
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
|
|
|
], $dbForConsole);
|
|
|
|
|
|
|
|
// Delete Keys
|
|
|
|
$this->deleteByGroup('keys', [
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
2023-04-28 03:41:14 +12:00
|
|
|
], $dbForConsole);
|
|
|
|
|
|
|
|
// Delete Webhooks
|
|
|
|
$this->deleteByGroup('webhooks', [
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
2023-04-28 03:37:14 +12:00
|
|
|
], $dbForConsole);
|
|
|
|
|
2023-01-11 19:37:06 +13:00
|
|
|
// Delete metadata tables
|
|
|
|
try {
|
|
|
|
$dbForProject->deleteCollection('_metadata');
|
|
|
|
} catch (Exception) {
|
|
|
|
// Ignore: deleteCollection tries to delete a metadata entry after the collection is deleted,
|
|
|
|
// which will throw an exception here because the metadata collection is already deleted.
|
|
|
|
}
|
2021-07-14 06:44:45 +12:00
|
|
|
|
|
|
|
// Delete all storage directories
|
2023-01-12 22:42:07 +13:00
|
|
|
$uploads = $this->getFilesDevice($projectId);
|
|
|
|
$functions = $this->getFunctionsDevice($projectId);
|
|
|
|
$builds = $this->getBuildsDevice($projectId);
|
|
|
|
$cache = $this->getCacheDevice($projectId);
|
2020-05-27 05:11:20 +12:00
|
|
|
|
2020-05-27 07:12:40 +12:00
|
|
|
$uploads->delete($uploads->getRoot(), true);
|
2023-01-12 22:42:07 +13:00
|
|
|
$functions->delete($functions->getRoot(), true);
|
|
|
|
$builds->delete($builds->getRoot(), true);
|
2020-05-27 07:12:40 +12:00
|
|
|
$cache->delete($cache->getRoot(), true);
|
2020-05-27 05:11:20 +12:00
|
|
|
}
|
2020-07-03 10:42:21 +12:00
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
|
|
|
* @param Document $document user document
|
2022-08-13 19:57:04 +12:00
|
|
|
* @param Document $project
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2022-08-13 19:57:04 +12:00
|
|
|
protected function deleteUser(Document $document, Document $project): void
|
2020-07-03 10:42:21 +12:00
|
|
|
{
|
2021-07-13 09:57:37 +12:00
|
|
|
$userId = $document->getId();
|
2023-06-23 23:52:19 +12:00
|
|
|
$userInternalId = $document->getInternalId();
|
2021-02-20 02:59:36 +13:00
|
|
|
|
2022-11-17 08:39:35 +13:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
|
|
|
|
2022-01-16 14:02:13 +13:00
|
|
|
// Delete all sessions of this user from the sessions table and update the sessions field of the user record
|
2022-01-16 12:24:38 +13:00
|
|
|
$this->deleteByGroup('sessions', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('userInternalId', [$userInternalId])
|
2022-11-17 08:39:35 +13:00
|
|
|
], $dbForProject);
|
2022-04-14 00:39:31 +12:00
|
|
|
|
2022-11-17 08:39:35 +13:00
|
|
|
$dbForProject->deleteCachedDocument('users', $userId);
|
2022-01-16 12:24:38 +13:00
|
|
|
|
2021-05-29 08:55:22 +12:00
|
|
|
// Delete Memberships and decrement team membership counts
|
2021-07-14 07:24:52 +12:00
|
|
|
$this->deleteByGroup('memberships', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('userInternalId', [$userInternalId])
|
2022-11-17 08:39:35 +13:00
|
|
|
], $dbForProject, function (Document $document) use ($dbForProject) {
|
2021-05-29 08:21:56 +12:00
|
|
|
if ($document->getAttribute('confirm')) { // Count only confirmed members
|
|
|
|
$teamId = $document->getAttribute('teamId');
|
2022-11-17 08:39:35 +13:00
|
|
|
$team = $dbForProject->getDocument('teams', $teamId);
|
2021-09-01 21:13:23 +12:00
|
|
|
if (!$team->isEmpty()) {
|
2022-11-17 08:39:35 +13:00
|
|
|
$team = $dbForProject->updateDocument(
|
|
|
|
'teams',
|
|
|
|
$teamId,
|
|
|
|
// Ensure that total >= 0
|
2023-05-22 22:58:13 +12:00
|
|
|
$team->setAttribute('total', \max($team->getAttribute('total', 0) - 1, 0))
|
2022-11-17 08:39:35 +13:00
|
|
|
);
|
2021-05-29 08:55:22 +12:00
|
|
|
}
|
2021-05-29 08:21:56 +12:00
|
|
|
}
|
|
|
|
});
|
2022-04-27 23:06:53 +12:00
|
|
|
|
|
|
|
// Delete tokens
|
|
|
|
$this->deleteByGroup('tokens', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('userInternalId', [$userInternalId])
|
2022-11-17 08:39:35 +13:00
|
|
|
], $dbForProject);
|
2020-12-05 09:47:02 +13:00
|
|
|
}
|
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
2022-07-12 03:12:41 +12:00
|
|
|
* @param string $datetime
|
2023-01-11 19:37:06 +13:00
|
|
|
* @throws Exception
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2022-07-12 03:12:41 +12:00
|
|
|
protected function deleteExecutionLogs(string $datetime): void
|
2020-12-15 10:26:37 +13:00
|
|
|
{
|
2022-09-28 04:29:50 +13:00
|
|
|
$this->deleteForProjectIds(function (Document $project) use ($datetime) {
|
2022-08-13 19:57:04 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2020-12-15 10:26:37 +13:00
|
|
|
// Delete Executions
|
2021-07-14 07:24:52 +12:00
|
|
|
$this->deleteByGroup('executions', [
|
2022-08-12 11:53:52 +12:00
|
|
|
Query::lessThan('$createdAt', $datetime)
|
2021-12-28 01:45:23 +13:00
|
|
|
], $dbForProject);
|
2020-12-23 03:04:09 +13:00
|
|
|
});
|
2020-12-15 10:26:37 +13:00
|
|
|
}
|
|
|
|
|
2022-11-22 03:24:52 +13:00
|
|
|
protected function deleteExpiredSessions(): void
|
2022-06-02 22:20:03 +12:00
|
|
|
{
|
2022-12-14 21:44:40 +13:00
|
|
|
$consoleDB = $this->getConsoleDB();
|
|
|
|
|
|
|
|
$this->deleteForProjectIds(function (Document $project) use ($consoleDB) {
|
2022-08-13 19:57:04 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2022-12-14 21:44:40 +13:00
|
|
|
|
|
|
|
$project = $consoleDB->getDocument('projects', $project->getId());
|
|
|
|
$duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
|
|
|
$expired = DateTime::addSeconds(new \DateTime(), -1 * $duration);
|
|
|
|
|
2022-06-02 22:20:03 +12:00
|
|
|
// Delete Sessions
|
|
|
|
$this->deleteByGroup('sessions', [
|
2022-11-22 03:24:52 +13:00
|
|
|
Query::lessThan('$createdAt', $expired)
|
2022-06-02 22:20:03 +12:00
|
|
|
], $dbForProject);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-11-20 05:46:10 +13:00
|
|
|
/**
|
2022-07-12 03:12:41 +12:00
|
|
|
* @param string $datetime
|
2023-01-11 19:37:06 +13:00
|
|
|
* @throws Exception
|
2021-11-20 05:46:10 +13:00
|
|
|
*/
|
2022-07-12 03:12:41 +12:00
|
|
|
protected function deleteRealtimeUsage(string $datetime): void
|
2021-11-20 05:46:10 +13:00
|
|
|
{
|
2022-09-28 04:29:50 +13:00
|
|
|
$this->deleteForProjectIds(function (Document $project) use ($datetime) {
|
2022-08-13 19:57:04 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2021-11-20 05:46:10 +13:00
|
|
|
// Delete Dead Realtime Logs
|
|
|
|
$this->deleteByGroup('realtime', [
|
2022-08-12 11:53:52 +12:00
|
|
|
Query::lessThan('timestamp', $datetime)
|
2021-12-28 01:45:23 +13:00
|
|
|
], $dbForProject);
|
2021-11-20 05:46:10 +13:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
2022-07-12 03:12:41 +12:00
|
|
|
* @param string $datetime
|
|
|
|
* @throws Exception
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2022-07-12 03:12:41 +12:00
|
|
|
protected function deleteAbuseLogs(string $datetime): void
|
2020-12-18 04:15:47 +13:00
|
|
|
{
|
2022-07-12 03:12:41 +12:00
|
|
|
if (empty($datetime)) {
|
|
|
|
throw new Exception('Failed to delete audit logs. No datetime provided');
|
2020-12-19 03:05:15 +13:00
|
|
|
}
|
2020-12-18 04:15:47 +13:00
|
|
|
|
2022-09-28 04:29:50 +13:00
|
|
|
$this->deleteForProjectIds(function (Document $project) use ($datetime) {
|
2022-08-13 19:57:04 +12:00
|
|
|
$projectId = $project->getId();
|
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2021-12-28 01:45:23 +13:00
|
|
|
$timeLimit = new TimeLimit("", 0, 1, $dbForProject);
|
2021-09-01 21:13:23 +12:00
|
|
|
$abuse = new Abuse($timeLimit);
|
2022-07-20 02:52:06 +12:00
|
|
|
$status = $abuse->cleanup($datetime);
|
2020-12-18 04:15:47 +13:00
|
|
|
if (!$status) {
|
2021-09-01 21:13:23 +12:00
|
|
|
throw new Exception('Failed to delete Abuse logs for project ' . $projectId);
|
2020-12-18 04:15:47 +13:00
|
|
|
}
|
2020-12-23 03:04:09 +13:00
|
|
|
});
|
2020-12-18 04:15:47 +13:00
|
|
|
}
|
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
2022-07-12 03:12:41 +12:00
|
|
|
* @param string $datetime
|
|
|
|
* @throws Exception
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2022-07-12 03:12:41 +12:00
|
|
|
protected function deleteAuditLogs(string $datetime): void
|
2020-12-18 04:15:47 +13:00
|
|
|
{
|
2022-07-12 03:12:41 +12:00
|
|
|
if (empty($datetime)) {
|
|
|
|
throw new Exception('Failed to delete audit logs. No datetime provided');
|
2020-12-19 03:05:15 +13:00
|
|
|
}
|
2022-07-12 03:12:41 +12:00
|
|
|
|
2022-09-28 04:29:50 +13:00
|
|
|
$this->deleteForProjectIds(function (Document $project) use ($datetime) {
|
2022-08-13 19:57:04 +12:00
|
|
|
$projectId = $project->getId();
|
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2021-12-28 01:45:23 +13:00
|
|
|
$audit = new Audit($dbForProject);
|
2022-07-20 02:52:06 +12:00
|
|
|
$status = $audit->cleanup($datetime);
|
2020-12-18 04:15:47 +13:00
|
|
|
if (!$status) {
|
2021-09-01 21:13:23 +12:00
|
|
|
throw new Exception('Failed to delete Audit logs for project' . $projectId);
|
2020-12-18 04:15:47 +13:00
|
|
|
}
|
2020-12-23 03:04:09 +13:00
|
|
|
});
|
2020-12-18 04:15:47 +13:00
|
|
|
}
|
|
|
|
|
2022-01-03 23:29:15 +13:00
|
|
|
/**
|
2022-07-12 03:12:41 +12:00
|
|
|
* @param string $resource
|
2022-08-13 19:57:04 +12:00
|
|
|
* @param Document $project
|
2022-01-03 23:29:15 +13:00
|
|
|
*/
|
2022-08-13 19:57:04 +12:00
|
|
|
protected function deleteAuditLogsByResource(string $resource, Document $project): void
|
2022-01-03 23:29:15 +13:00
|
|
|
{
|
2022-08-13 19:57:04 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2022-01-03 23:29:15 +13:00
|
|
|
|
|
|
|
$this->deleteByGroup(Audit::COLLECTION, [
|
2022-08-12 11:53:52 +12:00
|
|
|
Query::equal('resource', [$resource])
|
2022-01-03 23:29:15 +13:00
|
|
|
], $dbForProject);
|
|
|
|
}
|
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
|
|
|
* @param Document $document function document
|
2022-08-13 19:57:04 +12:00
|
|
|
* @param Document $project
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2022-08-13 19:57:04 +12:00
|
|
|
protected function deleteFunction(Document $document, Document $project): void
|
2020-12-05 09:47:02 +13:00
|
|
|
{
|
2022-08-13 19:57:04 +12:00
|
|
|
$projectId = $project->getId();
|
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2023-02-23 04:07:34 +13:00
|
|
|
$dbForConsole = $this->getConsoleDB();
|
2022-02-13 11:34:16 +13:00
|
|
|
$functionId = $document->getId();
|
2023-06-23 23:52:19 +12:00
|
|
|
$functionInternalId = $document->getInternalId();
|
2022-01-28 13:25:28 +13:00
|
|
|
|
2023-02-23 04:07:34 +13:00
|
|
|
/**
|
2023-07-31 18:47:47 +12:00
|
|
|
* Delete rules
|
2023-02-23 04:07:34 +13:00
|
|
|
*/
|
2023-07-31 18:47:47 +12:00
|
|
|
Console::info("Deleting rules for function " . $functionId);
|
2023-03-09 07:30:01 +13:00
|
|
|
$this->deleteByGroup('rules', [
|
2023-02-23 04:07:34 +13:00
|
|
|
Query::equal('resourceType', ['function']),
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('resourceInternalId', [$functionInternalId]),
|
2023-02-23 04:07:34 +13:00
|
|
|
Query::equal('projectInternalId', [$project->getInternalId()])
|
2023-03-15 08:31:23 +13:00
|
|
|
], $dbForConsole, function (Document $document) use ($project) {
|
2023-03-11 01:20:24 +13:00
|
|
|
$this->deleteRule($document, $project);
|
|
|
|
});
|
2023-02-23 04:07:34 +13:00
|
|
|
|
2022-09-19 23:53:34 +12:00
|
|
|
/**
|
|
|
|
* Delete Variables
|
|
|
|
*/
|
|
|
|
Console::info("Deleting variables for function " . $functionId);
|
|
|
|
$this->deleteByGroup('variables', [
|
2023-03-12 05:06:02 +13:00
|
|
|
Query::equal('resourceType', ['function']),
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('resourceInternalId', [$functionInternalId])
|
2022-09-19 23:53:34 +12:00
|
|
|
], $dbForProject);
|
|
|
|
|
2022-01-28 14:21:11 +13:00
|
|
|
/**
|
|
|
|
* Delete Deployments
|
|
|
|
*/
|
2022-02-13 11:34:16 +13:00
|
|
|
Console::info("Deleting deployments for function " . $functionId);
|
2022-11-12 02:54:05 +13:00
|
|
|
$storageFunctions = $this->getFunctionsDevice($projectId);
|
2023-06-23 23:52:19 +12:00
|
|
|
$deploymentInternalIds = [];
|
2022-01-28 14:29:20 +13:00
|
|
|
$this->deleteByGroup('deployments', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('resourceInternalId', [$functionInternalId])
|
|
|
|
], $dbForProject, function (Document $document) use ($storageFunctions, &$deploymentInternalIds) {
|
|
|
|
$deploymentInternalIds[] = $document->getInternalId();
|
2022-01-28 14:29:20 +13:00
|
|
|
if ($storageFunctions->delete($document->getAttribute('path', ''), true)) {
|
2022-02-01 12:44:55 +13:00
|
|
|
Console::success('Deleted deployment files: ' . $document->getAttribute('path', ''));
|
2022-01-28 14:29:20 +13:00
|
|
|
} else {
|
|
|
|
Console::error('Failed to delete deployment files: ' . $document->getAttribute('path', ''));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete builds
|
|
|
|
*/
|
2022-02-13 11:34:16 +13:00
|
|
|
Console::info("Deleting builds for function " . $functionId);
|
2022-11-12 02:54:05 +13:00
|
|
|
$storageBuilds = $this->getBuildsDevice($projectId);
|
2023-06-23 23:52:19 +12:00
|
|
|
foreach ($deploymentInternalIds as $deploymentInternalId) {
|
2022-01-29 13:52:06 +13:00
|
|
|
$this->deleteByGroup('builds', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('deploymentInternalId', [$deploymentInternalId])
|
|
|
|
], $dbForProject, function (Document $document) use ($storageBuilds) {
|
2022-12-18 20:35:16 +13:00
|
|
|
if ($storageBuilds->delete($document->getAttribute('path', ''), true)) {
|
|
|
|
Console::success('Deleted build files: ' . $document->getAttribute('path', ''));
|
2022-01-29 13:52:06 +13:00
|
|
|
} else {
|
2022-12-18 20:35:16 +13:00
|
|
|
Console::error('Failed to delete build files: ' . $document->getAttribute('path', ''));
|
2022-01-29 13:52:06 +13:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2022-01-28 14:29:20 +13:00
|
|
|
|
2022-05-24 02:54:50 +12:00
|
|
|
/**
|
2022-02-13 11:34:16 +13:00
|
|
|
* Delete Executions
|
2022-05-16 21:58:17 +12:00
|
|
|
*/
|
2022-02-13 11:34:16 +13:00
|
|
|
Console::info("Deleting executions for function " . $functionId);
|
2022-01-28 14:29:20 +13:00
|
|
|
$this->deleteByGroup('executions', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('functionInternalId', [$functionInternalId])
|
2022-01-28 14:29:20 +13:00
|
|
|
], $dbForProject);
|
|
|
|
|
2023-03-15 00:13:03 +13:00
|
|
|
/**
|
|
|
|
* Request executor to delete all deployment containers
|
|
|
|
*/
|
|
|
|
Console::info("Requesting executor to delete all deployment containers for function " . $functionId);
|
|
|
|
$this->deleteRuntimes($document, $project);
|
2022-01-28 14:29:20 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Document $document deployment document
|
2022-08-13 19:57:04 +12:00
|
|
|
* @param Document $project
|
2022-01-28 14:29:20 +13:00
|
|
|
*/
|
2022-08-13 19:57:04 +12:00
|
|
|
protected function deleteDeployment(Document $document, Document $project): void
|
2022-01-28 14:29:20 +13:00
|
|
|
{
|
2022-08-13 19:57:04 +12:00
|
|
|
$projectId = $project->getId();
|
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2022-02-06 23:00:44 +13:00
|
|
|
$deploymentId = $document->getId();
|
2023-06-23 23:52:19 +12:00
|
|
|
$deploymentInternalId = $document->getInternalId();
|
2022-01-28 14:29:20 +13:00
|
|
|
|
|
|
|
/**
|
2022-01-29 13:00:25 +13:00
|
|
|
* Delete deployment files
|
2022-01-28 14:29:20 +13:00
|
|
|
*/
|
2022-02-13 11:34:16 +13:00
|
|
|
Console::info("Deleting deployment files for deployment " . $deploymentId);
|
2022-11-12 02:54:05 +13:00
|
|
|
$storageFunctions = $this->getFunctionsDevice($projectId);
|
2022-01-28 14:32:56 +13:00
|
|
|
if ($storageFunctions->delete($document->getAttribute('path', ''), true)) {
|
2022-02-01 12:44:55 +13:00
|
|
|
Console::success('Deleted deployment files: ' . $document->getAttribute('path', ''));
|
2022-01-28 14:32:56 +13:00
|
|
|
} else {
|
|
|
|
Console::error('Failed to delete deployment files: ' . $document->getAttribute('path', ''));
|
|
|
|
}
|
2020-12-05 09:47:02 +13:00
|
|
|
|
2022-01-28 14:21:11 +13:00
|
|
|
/**
|
|
|
|
* Delete builds
|
|
|
|
*/
|
2022-02-13 11:34:16 +13:00
|
|
|
Console::info("Deleting builds for deployment " . $deploymentId);
|
2022-11-12 02:54:05 +13:00
|
|
|
$storageBuilds = $this->getBuildsDevice($projectId);
|
2022-01-28 12:36:30 +13:00
|
|
|
$this->deleteByGroup('builds', [
|
2023-06-23 23:52:19 +12:00
|
|
|
Query::equal('deploymentInternalId', [$deploymentInternalId])
|
2022-02-15 13:58:12 +13:00
|
|
|
], $dbForProject, function (Document $document) use ($storageBuilds) {
|
2022-12-18 20:35:16 +13:00
|
|
|
if ($storageBuilds->delete($document->getAttribute('path', ''), true)) {
|
|
|
|
Console::success('Deleted build files: ' . $document->getAttribute('path', ''));
|
2021-09-01 21:13:23 +12:00
|
|
|
} else {
|
2022-12-18 20:35:16 +13:00
|
|
|
Console::error('Failed to delete build files: ' . $document->getAttribute('path', ''));
|
2020-12-05 09:47:02 +13:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-03-15 00:13:03 +13:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Request executor to delete all deployment containers
|
|
|
|
*/
|
|
|
|
Console::info("Requesting executor to delete deployment container for deployment " . $deploymentId);
|
|
|
|
$this->deleteRuntimes($document, $project);
|
2020-12-05 09:47:02 +13:00
|
|
|
}
|
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Document $document to be deleted
|
|
|
|
* @param Database $database to delete it from
|
2023-01-11 19:37:06 +13:00
|
|
|
* @param callable|null $callback to perform after document is deleted
|
2021-07-14 07:24:52 +12:00
|
|
|
*
|
|
|
|
* @return bool
|
2023-01-11 19:37:06 +13:00
|
|
|
* @throws \Utopia\Database\Exception\Authorization
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2020-12-05 09:47:02 +13:00
|
|
|
protected function deleteById(Document $document, Database $database, callable $callback = null): bool
|
|
|
|
{
|
2021-11-20 05:46:10 +13:00
|
|
|
if ($database->deleteDocument($document->getCollection(), $document->getId())) {
|
2021-09-01 21:13:23 +12:00
|
|
|
Console::success('Deleted document "' . $document->getId() . '" successfully');
|
2020-12-05 09:47:02 +13:00
|
|
|
|
2021-09-01 21:13:23 +12:00
|
|
|
if (is_callable($callback)) {
|
2020-12-05 09:47:02 +13:00
|
|
|
$callback($document);
|
2020-07-03 10:42:21 +12:00
|
|
|
}
|
2020-12-05 09:47:02 +13:00
|
|
|
|
|
|
|
return true;
|
2021-09-01 21:13:23 +12:00
|
|
|
} else {
|
|
|
|
Console::error('Failed to delete document: ' . $document->getId());
|
2020-12-05 09:47:02 +13:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
|
|
|
* @param callable $callback
|
2023-01-11 19:37:06 +13:00
|
|
|
* @throws Exception
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2021-08-27 16:37:15 +12:00
|
|
|
protected function deleteForProjectIds(callable $callback): void
|
2020-12-22 07:15:52 +13:00
|
|
|
{
|
2022-12-14 21:44:40 +13:00
|
|
|
// TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document
|
2020-12-23 03:04:09 +13:00
|
|
|
$count = 0;
|
|
|
|
$chunk = 0;
|
|
|
|
$limit = 50;
|
|
|
|
$projects = [];
|
|
|
|
$sum = $limit;
|
2020-12-22 07:15:52 +13:00
|
|
|
|
2020-12-23 03:04:09 +13:00
|
|
|
$executionStart = \microtime(true);
|
2021-09-01 21:13:23 +12:00
|
|
|
|
|
|
|
while ($sum === $limit) {
|
2022-08-12 11:53:52 +12:00
|
|
|
$projects = $this->getConsoleDB()->find('projects', [Query::limit($limit), Query::offset($chunk * $limit)]);
|
2020-12-23 03:04:09 +13:00
|
|
|
|
2021-08-27 16:37:15 +12:00
|
|
|
$chunk++;
|
|
|
|
|
2021-11-20 05:46:10 +13:00
|
|
|
/** @var string[] $projectIds */
|
2020-12-23 03:04:09 +13:00
|
|
|
$sum = count($projects);
|
|
|
|
|
2021-09-01 21:13:23 +12:00
|
|
|
Console::info('Executing delete function for chunk #' . $chunk . '. Found ' . $sum . ' projects');
|
2022-09-28 04:29:50 +13:00
|
|
|
foreach ($projects as $project) {
|
|
|
|
$callback($project);
|
2020-12-23 03:04:09 +13:00
|
|
|
$count++;
|
|
|
|
}
|
|
|
|
}
|
2020-12-22 07:15:52 +13:00
|
|
|
|
2020-12-23 03:04:09 +13:00
|
|
|
$executionEnd = \microtime(true);
|
|
|
|
Console::info("Found {$count} projects " . ($executionEnd - $executionStart) . " seconds");
|
2020-12-22 07:15:52 +13:00
|
|
|
}
|
|
|
|
|
2023-05-22 22:58:13 +12:00
|
|
|
/**
|
|
|
|
* @param string $collection collectionID
|
2023-01-11 19:37:06 +13:00
|
|
|
* @param array $queries
|
2023-05-22 22:58:13 +12:00
|
|
|
* @param Database $database
|
2023-01-11 19:37:06 +13:00
|
|
|
* @param callable|null $callback
|
|
|
|
* @throws Exception
|
2023-05-22 22:58:13 +12:00
|
|
|
*/
|
2021-08-27 16:37:15 +12:00
|
|
|
protected function deleteByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
|
2023-05-22 22:58:13 +12:00
|
|
|
{
|
|
|
|
$count = 0;
|
|
|
|
$chunk = 0;
|
|
|
|
$limit = 50;
|
|
|
|
$results = [];
|
|
|
|
$sum = $limit;
|
|
|
|
|
|
|
|
$executionStart = \microtime(true);
|
|
|
|
|
2023-06-13 06:44:49 +12:00
|
|
|
try {
|
|
|
|
while ($sum === $limit) {
|
|
|
|
$chunk++;
|
2023-05-22 22:58:13 +12:00
|
|
|
|
2023-06-13 06:44:49 +12:00
|
|
|
$results = $database->find($collection, \array_merge([Query::limit($limit)], $queries));
|
2023-05-22 22:58:13 +12:00
|
|
|
|
2023-06-13 06:44:49 +12:00
|
|
|
$sum = count($results);
|
2023-05-22 22:58:13 +12:00
|
|
|
|
2023-06-13 06:44:49 +12:00
|
|
|
Console::info('Deleting chunk #' . $chunk . '. Found ' . $sum . ' documents in collection ' . $database->getNamespace() . '_' . $collection);
|
2023-05-22 22:58:13 +12:00
|
|
|
|
2023-06-13 06:44:49 +12:00
|
|
|
foreach ($results as $document) {
|
|
|
|
$this->deleteById($document, $database, $callback);
|
|
|
|
$count++;
|
|
|
|
}
|
2023-05-22 22:58:13 +12:00
|
|
|
}
|
2023-06-13 06:44:49 +12:00
|
|
|
} catch (\Exception $e) {
|
|
|
|
Console::error($e->getMessage());
|
2023-05-22 22:58:13 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
$executionEnd = \microtime(true);
|
|
|
|
|
2020-12-05 09:47:02 +13:00
|
|
|
Console::info("Deleted {$count} document by group in " . ($executionEnd - $executionStart) . " seconds");
|
2023-05-22 22:58:13 +12:00
|
|
|
}
|
|
|
|
|
2021-07-13 09:57:37 +12:00
|
|
|
/**
|
|
|
|
* @param string $collection collectionID
|
|
|
|
* @param Query[] $queries
|
2021-07-14 07:24:52 +12:00
|
|
|
* @param Database $database
|
2021-07-13 09:57:37 +12:00
|
|
|
* @param callable $callback
|
|
|
|
*/
|
2022-12-14 21:44:40 +13:00
|
|
|
protected function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
|
2020-12-05 09:47:02 +13:00
|
|
|
{
|
|
|
|
$count = 0;
|
|
|
|
$chunk = 0;
|
|
|
|
$limit = 50;
|
|
|
|
$results = [];
|
|
|
|
$sum = $limit;
|
2023-07-19 13:32:11 +12:00
|
|
|
$cursor = null;
|
2020-12-05 09:47:02 +13:00
|
|
|
|
|
|
|
$executionStart = \microtime(true);
|
2021-09-01 21:13:23 +12:00
|
|
|
|
|
|
|
while ($sum === $limit) {
|
2020-12-05 09:47:02 +13:00
|
|
|
$chunk++;
|
|
|
|
|
2023-07-19 13:32:11 +12:00
|
|
|
$mergedQueries = \array_merge([Query::limit($limit)], $queries);
|
|
|
|
if ($cursor instanceof Document) {
|
|
|
|
$mergedQueries[] = Query::cursorAfter($cursor);
|
|
|
|
}
|
|
|
|
|
|
|
|
$results = $database->find($collection, $mergedQueries);
|
2022-01-29 13:52:06 +13:00
|
|
|
|
2020-12-05 09:47:02 +13:00
|
|
|
$sum = count($results);
|
|
|
|
|
2023-07-19 13:32:11 +12:00
|
|
|
if ($sum > 0) {
|
|
|
|
$cursor = $results[$sum - 1];
|
|
|
|
}
|
2020-12-05 09:47:02 +13:00
|
|
|
|
|
|
|
foreach ($results as $document) {
|
2022-12-14 21:44:40 +13:00
|
|
|
if (is_callable($callback)) {
|
|
|
|
$callback($document);
|
|
|
|
}
|
|
|
|
|
2020-12-05 09:47:02 +13:00
|
|
|
$count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$executionEnd = \microtime(true);
|
|
|
|
|
2022-12-14 21:44:40 +13:00
|
|
|
Console::info("Listed {$count} document by group in " . ($executionEnd - $executionStart) . " seconds");
|
2020-12-05 09:47:02 +13:00
|
|
|
}
|
|
|
|
|
2021-07-14 07:24:52 +12:00
|
|
|
/**
|
2023-03-10 20:42:52 +13:00
|
|
|
* @param Document $document rule document
|
|
|
|
* @param Document $project project document
|
2021-07-14 07:24:52 +12:00
|
|
|
*/
|
2023-03-10 20:42:52 +13:00
|
|
|
protected function deleteRule(Document $document, Document $project): void
|
2021-02-05 22:05:26 +13:00
|
|
|
{
|
2022-03-24 04:05:50 +13:00
|
|
|
$consoleDB = $this->getConsoleDB();
|
|
|
|
|
2021-02-05 23:57:43 +13:00
|
|
|
$domain = $document->getAttribute('domain');
|
2021-02-05 22:05:26 +13:00
|
|
|
$directory = APP_STORAGE_CERTIFICATES . '/' . $domain;
|
2021-02-06 00:18:12 +13:00
|
|
|
$checkTraversal = realpath($directory) === $directory;
|
2021-02-05 22:05:26 +13:00
|
|
|
|
2023-03-10 20:42:52 +13:00
|
|
|
if ($checkTraversal && is_dir($directory)) {
|
2022-03-24 03:54:25 +13:00
|
|
|
// Delete files, so Traefik is aware of change
|
2021-09-01 21:13:23 +12:00
|
|
|
array_map('unlink', glob($directory . '/*.*'));
|
2021-02-05 22:05:26 +13:00
|
|
|
rmdir($directory);
|
2021-02-05 23:57:43 +13:00
|
|
|
Console::info("Deleted certificate files for {$domain}");
|
|
|
|
} else {
|
|
|
|
Console::info("No certificate files found for {$domain}");
|
2021-02-05 22:05:26 +13:00
|
|
|
}
|
2023-03-10 20:42:52 +13:00
|
|
|
|
|
|
|
// Delete certificate document, so Appwrite is aware of change
|
|
|
|
if (isset($document['certificateId'])) {
|
|
|
|
$consoleDB->deleteDocument('certificates', $document['certificateId']);
|
|
|
|
}
|
2021-02-05 22:05:26 +13:00
|
|
|
}
|
2021-07-18 19:03:48 +12:00
|
|
|
|
2022-08-13 19:57:04 +12:00
|
|
|
protected function deleteBucket(Document $document, Document $project)
|
2021-07-18 19:03:48 +12:00
|
|
|
{
|
2022-08-13 19:57:04 +12:00
|
|
|
$projectId = $project->getId();
|
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2022-02-18 14:36:25 +13:00
|
|
|
$dbForProject->deleteCollection('bucket_' . $document->getInternalId());
|
2021-07-28 22:14:47 +12:00
|
|
|
|
2022-11-12 02:54:05 +13:00
|
|
|
$device = $this->getFilesDevice($projectId);
|
2022-05-24 02:54:50 +12:00
|
|
|
|
2022-02-18 14:36:25 +13:00
|
|
|
$device->deletePath($document->getId());
|
2021-07-18 19:03:48 +12:00
|
|
|
}
|
2023-03-15 00:13:03 +13:00
|
|
|
|
2023-05-22 22:58:13 +12:00
|
|
|
protected function deleteInstallation(Document $document, Document $project)
|
|
|
|
{
|
2023-06-08 03:50:32 +12:00
|
|
|
$dbForProject = $this->getProjectDB($project);
|
2023-05-22 22:58:13 +12:00
|
|
|
$dbForConsole = $this->getConsoleDB();
|
|
|
|
|
|
|
|
$this->listByGroup('functions', [
|
2023-07-30 21:51:13 +12:00
|
|
|
Query::equal('installationInternalId', [$document->getInternalId()])
|
2023-05-22 22:58:13 +12:00
|
|
|
], $dbForProject, function ($function) use ($dbForProject, $dbForConsole) {
|
2023-07-31 07:10:25 +12:00
|
|
|
$dbForConsole->deleteDocument('repositories', $function->getAttribute('repositoryId'));
|
2023-05-22 22:58:13 +12:00
|
|
|
|
|
|
|
$function = $function
|
2023-07-30 21:51:13 +12:00
|
|
|
->setAttribute('installationId', '')
|
|
|
|
->setAttribute('installationInternalId', '')
|
|
|
|
->setAttribute('providerRepositoryId', '')
|
|
|
|
->setAttribute('providerBranch', '')
|
|
|
|
->setAttribute('providerSilentMode', false)
|
|
|
|
->setAttribute('providerRootDirectory', '')
|
|
|
|
->setAttribute('repositoryId', '')
|
|
|
|
->setAttribute('repositoryInternalId', '');
|
2023-05-22 22:58:13 +12:00
|
|
|
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-03-15 08:31:23 +13:00
|
|
|
protected function deleteRuntimes(?Document $function, Document $project)
|
|
|
|
{
|
2023-03-15 00:13:03 +13:00
|
|
|
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
|
|
|
|
2023-03-15 08:31:23 +13:00
|
|
|
$deleteByFunction = function (Document $function) use ($project, $executor) {
|
2023-03-15 00:13:03 +13:00
|
|
|
$this->listByGroup(
|
|
|
|
'deployments',
|
|
|
|
[
|
|
|
|
Query::equal('resourceInternalId', [$function->getInternalId()]),
|
|
|
|
Query::equal('resourceType', ['functions']),
|
|
|
|
],
|
|
|
|
$this->getProjectDB($project),
|
|
|
|
function (Document $deployment) use ($project, $executor) {
|
|
|
|
$deploymentId = $deployment->getId();
|
|
|
|
|
|
|
|
try {
|
|
|
|
$executor->deleteRuntime($project->getId(), $deploymentId);
|
|
|
|
Console::info("Runtime for deployment {$deploymentId} deleted.");
|
|
|
|
} catch (Throwable $th) {
|
|
|
|
Console::warning("Runtime for deployment {$deploymentId} skipped:");
|
|
|
|
Console::error('[Error] Type: ' . get_class($th));
|
|
|
|
Console::error('[Error] Message: ' . $th->getMessage());
|
|
|
|
Console::error('[Error] File: ' . $th->getFile());
|
|
|
|
Console::error('[Error] Line: ' . $th->getLine());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2023-03-15 08:31:23 +13:00
|
|
|
if ($function !== null) {
|
2023-03-15 00:13:03 +13:00
|
|
|
// Delete function runtimes
|
|
|
|
$deleteByFunction($function);
|
|
|
|
} else {
|
|
|
|
// Delete all project runtimes
|
|
|
|
$this->listByGroup(
|
|
|
|
'functions',
|
|
|
|
[],
|
|
|
|
$this->getProjectDB($project),
|
|
|
|
function (Document $function) use ($deleteByFunction) {
|
|
|
|
$deleteByFunction($function);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2021-09-01 21:13:23 +12:00
|
|
|
}
|