diff --git a/docs/releases/2.20.0.md b/docs/releases/2.20.0.md new file mode 100644 index 0000000000..9d679251f5 --- /dev/null +++ b/docs/releases/2.20.0.md @@ -0,0 +1,12 @@ +#### Release Links + +!!! Info + This version has not been released yet + +## Upgrades +There are no required actions or considerations with this release. As always, we suggest upgrading all minor versions. + +## Deprecations + +### Deleted Backups +* When a backup is deleted via the webhook, it will now actually removed from the API rather than being flagged as deleted. The `Backup` type field `deleted` is deprecated, and will be removed in a future release. Additionally, `includeDeleted` if requested when querying backups will not change the result as there will be no deleted backups to include. diff --git a/services/api/database/migrations/20240507000000_delete_orphaned_backup_resources.js b/services/api/database/migrations/20240507000000_delete_orphaned_backup_resources.js new file mode 100644 index 0000000000..37ad583535 --- /dev/null +++ b/services/api/database/migrations/20240507000000_delete_orphaned_backup_resources.js @@ -0,0 +1,29 @@ +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = function(knex) { + // remove any deleted environment backups that are flagged as deleted + // or where the environment/project are deleted or no longer exist + return knex.schema + .raw(`DELETE eb + FROM environment_backup eb + LEFT JOIN environment e ON eb.environment = e.id + WHERE eb.deleted != '0000-00-00 00:00:00' OR e.id IS NULL OR e.deleted != '0000-00-00 00:00:00' OR e.project NOT IN (SELECT id FROM project) + `) + // drop the deleted column + .alterTable('environment_backup', (table) => { + table.dropColumn('deleted'); + }); + }; + + /** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ + exports.down = function(knex) { + return knex.schema + .alterTable('environment_backup', (table) => { + table.timestamp('deleted').notNullable().defaultTo('0000-00-00 00:00:00'); + }); + }; diff --git a/services/api/src/resources/backup/resolvers.ts b/services/api/src/resources/backup/resolvers.ts index 309a33ede4..a4924d1227 100644 --- a/services/api/src/resources/backup/resolvers.ts +++ b/services/api/src/resources/backup/resolvers.ts @@ -124,7 +124,7 @@ const getRestoreLocation = async (backupId, restoreLocation, sqlClientPool) => { export const getBackupsByEnvironmentId: ResolverFn = async ( { id: environmentId }, - { includeDeleted, limit }, + { limit }, { sqlClientPool, hasPermission, adminScopes } ) => { const environment = await environmentHelpers( @@ -142,10 +142,6 @@ export const getBackupsByEnvironmentId: ResolverFn = async ( .orderBy('created', 'desc') .orderBy('id', 'desc'); - if (!includeDeleted) { - queryBuilder = queryBuilder.where('deleted', '0000-00-00 00:00:00'); - } - if (limit) { queryBuilder = queryBuilder.limit(limit); } diff --git a/services/api/src/resources/backup/sql.ts b/services/api/src/resources/backup/sql.ts index 1af63dc86f..1edaf3ae50 100644 --- a/services/api/src/resources/backup/sql.ts +++ b/services/api/src/resources/backup/sql.ts @@ -13,24 +13,6 @@ export const Sql = { knex('env_vars') .where('project', projectId) .toString(), - selectBackupsByEnvironmentId: ({ - environmentId, - includeDeleted - }: { - environmentId: number; - includeDeleted: boolean; - }) => { - const query = knex('environment_backup') - .where('environment', environmentId) - .orderBy('created', 'desc') - .orderBy('id', 'desc'); - - if (includeDeleted) { - return query.toString(); - } - - return query.where('deleted', '=', '0000-00-00 00:00:00').toString(); - }, insertBackup: ({ id, environment, @@ -56,7 +38,7 @@ export const Sql = { deleteBackup: (backupId: string) => knex('environment_backup') .where('backup_id', backupId) - .update({ deleted: knex.fn.now() }) + .delete() .toString(), truncateBackup: () => knex('environment_backup') diff --git a/services/api/src/typeDefs.js b/services/api/src/typeDefs.js index c10f70919f..59a4dc97d5 100644 --- a/services/api/src/typeDefs.js +++ b/services/api/src/typeDefs.js @@ -965,7 +965,7 @@ const typeDefs = gql` source: String backupId: String created: String - deleted: String + deleted: String @deprecated(reason: "This will be removed in a future release.") restore: Restore }