Modularize prepareDatabasse into initSecretVersioning

This commit is contained in:
Tuan Dang
2023-01-02 14:52:08 +07:00
14 changed files with 837 additions and 356 deletions
+64 -4
View File
@@ -1,7 +1,8 @@
import { Types } from 'mongoose';
import * as Sentry from '@sentry/node';
import {
Secret
Secret,
ISecret
} from '../../models';
import {
SecretSnapshot,
@@ -10,17 +11,19 @@ import {
} from '../models';
/**
* Save a copy of the current state of secrets in workspace with id
* Save a secret snapshot that is a copy of the current state of secrets in workspace with id
* [workspaceId] under a new snapshot with incremented version under the
* secretsnapshots collection.
* @param {Object} obj
* @param {String} obj.workspaceId
* @returns {SecretSnapshot} secretSnapshot - new secret snapshot
*/
const takeSecretSnapshotHelper = async ({
workspaceId
}: {
workspaceId: string;
}) => {
let secretSnapshot;
try {
const secrets = await Secret.find({
workspace: workspaceId
@@ -42,7 +45,7 @@ import {
}
// case: snapshots exist for workspace
await new SecretSnapshot({
secretSnapshot = await new SecretSnapshot({
workspace: workspaceId,
version: latestSecretSnapshot.version + 1,
secrets
@@ -53,8 +56,16 @@ import {
Sentry.captureException(err);
throw new Error('Failed to take a secret snapshot');
}
return secretSnapshot;
}
/**
* Add secret versions [secretVersions] to the SecretVersion collection.
* @param {Object} obj
* @param {Object[]} obj.secretVersions
* @returns {SecretVersion[]} newSecretVersions - new secret versions
*/
const addSecretVersionsHelper = async ({
secretVersions
}: {
@@ -92,8 +103,57 @@ const markDeletedSecretVersionsHelper = async ({
}
}
/**
* Initialize secret versioning by setting previously unversioned
* secrets to version 1 and begin populating secret versions.
*/
const initSecretVersioningHelper = async () => {
try {
await Secret.updateMany(
{ version: { $exists: false } },
{ $set: { version: 1 } }
);
const unversionedSecrets: ISecret[] = await Secret.aggregate([
{
$lookup: {
from: 'secretversions',
localField: '_id',
foreignField: 'secret',
as: 'versions',
},
},
{
$match: {
versions: { $size: 0 },
},
},
]);
if (unversionedSecrets.length > 0) {
await addSecretVersionsHelper({
secretVersions: unversionedSecrets.map((s, idx) => ({
...s,
secret: s._id,
version: s.version ? s.version : 1,
isDeleted: false,
workspace: s.workspace,
environment: s.environment
}))
});
}
} catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to ensure secrets are versioned');
}
}
export {
takeSecretSnapshotHelper,
addSecretVersionsHelper,
markDeletedSecretVersionsHelper
markDeletedSecretVersionsHelper,
initSecretVersioningHelper
}
+16 -4
View File
@@ -3,7 +3,8 @@ import { ISecretVersion } from '../models';
import {
takeSecretSnapshotHelper,
addSecretVersionsHelper,
markDeletedSecretVersionsHelper
markDeletedSecretVersionsHelper,
initSecretVersioningHelper
} from '../helpers/secret';
import EELicenseService from './EELicenseService';
@@ -13,12 +14,13 @@ import EELicenseService from './EELicenseService';
class EESecretService {
/**
* Save a copy of the current state of secrets in workspace with id
* Save a secret snapshot that is a copy of the current state of secrets in workspace with id
* [workspaceId] under a new snapshot with incremented version under the
* SecretSnapshot collection.
* Requires a valid license key [licenseKey]
* @param {Object} obj
* @param {String} obj.workspaceId
* @returns {SecretSnapshot} secretSnapshot - new secret snpashot
*/
static async takeSecretSnapshot({
workspaceId
@@ -26,13 +28,14 @@ class EESecretService {
workspaceId: string;
}) {
if (!EELicenseService.isLicenseValid) return;
await takeSecretSnapshotHelper({ workspaceId });
return await takeSecretSnapshotHelper({ workspaceId });
}
/**
* Add secret versions [secretVersions] to the SecretVersion collection.
* @param {Object} obj
* @param {SecretVersion} obj.secretVersions
* @param {Object[]} obj.secretVersions
* @returns {SecretVersion[]} newSecretVersions - new secret versions
*/
static async addSecretVersions({
secretVersions
@@ -61,6 +64,15 @@ class EESecretService {
secretIds
});
}
/**
* Initialize secret versioning by setting previously unversioned
* secrets to version 1 and begin populating secret versions.
*/
static async initSecretVersioning() {
if (!EELicenseService.isLicenseValid) return;
await initSecretVersioningHelper();
}
}
export default EESecretService;
+1 -48
View File
@@ -18,7 +18,7 @@ const initDatabaseHelper = async ({
await mongoose.connect(mongoURL);
getLogger("database").info("Database connection established");
await prepareDatabase();
await EESecretService.initSecretVersioning();
} catch (err) {
getLogger("database").error(`Unable to establish Database connection due to the error.\n${err}`);
}
@@ -26,53 +26,6 @@ const initDatabaseHelper = async ({
return mongoose.connection;
}
/**
* Prepare database by:
* - Setting unversioned secrets to version 1
* - Initializing secret versions for unversioned secrets
*/
const prepareDatabase = async () => {
try {
// set previously unversioned secrets in Secret to version 1
await Secret.updateMany(
{ version: { $exists: false } },
{ $set: { version: 1 } }
);
// initialize secret versions for unversioned secrets
const unversionedSecrets: ISecret[] = await Secret.aggregate([
{
$lookup: {
from: 'secretversions',
localField: '_id',
foreignField: 'secret',
as: 'versions',
},
},
{
$match: {
versions: { $size: 0 },
},
},
]);
if (unversionedSecrets.length > 0) {
await EESecretService.addSecretVersions({
secretVersions: unversionedSecrets.map((s, idx) => ({
...s,
secret: s._id,
version: s.version ? s.version : 1,
isDeleted: false,
workspace: s.workspace,
environment: s.environment
}))
});
}
} catch (err) {
getLogger('database').error('Failed to prepare database');
}
}
export {
initDatabaseHelper
}