feat: sync all workspaces (#4353)

This commit is contained in:
Jérémy M
2024-03-07 15:40:09 +01:00
committed by GitHub
parent eabece6918
commit c3a024b047
5 changed files with 80 additions and 49 deletions

View File

@ -9,6 +9,16 @@ import { kebabCase } from 'src/utils/kebab-case';
export class CommandLogger { export class CommandLogger {
constructor(private readonly className: string) {} constructor(private readonly className: string) {}
async createSubDirectory(subDirectory: string): Promise<void> {
const path = `./logs/${kebabCase(this.className)}/${subDirectory}`;
if (existsSync(path) === false) {
await fs.mkdir(path, { recursive: true });
}
return;
}
async writeLog( async writeLog(
fileName: string, fileName: string,
data: unknown, data: unknown,

View File

@ -64,4 +64,10 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
return workspace; return workspace;
} }
async getWorkspaceIds() {
return this.workspaceRepository
.find()
.then((workspaces) => workspaces.map((workspace) => workspace.id));
}
} }

View File

@ -13,66 +13,70 @@ export class SyncWorkspaceLoggerService {
constructor() {} constructor() {}
async saveLogs( async saveLogs(
workspaceId: string,
storage: WorkspaceSyncStorage, storage: WorkspaceSyncStorage,
workspaceMigrations: WorkspaceMigrationEntity[], workspaceMigrations: WorkspaceMigrationEntity[],
) { ) {
// Create sub directory
await this.commandLogger.createSubDirectory(workspaceId);
// Save workspace migrations // Save workspace migrations
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'workspace-migrations', `${workspaceId}/workspace-migrations`,
workspaceMigrations, workspaceMigrations,
); );
// Save object metadata create collection // Save object metadata create collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'object-metadata-create-collection', `${workspaceId}/object-metadata-create-collection`,
storage.objectMetadataCreateCollection, storage.objectMetadataCreateCollection,
); );
// Save object metadata update collection // Save object metadata update collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'object-metadata-update-collection', `${workspaceId}/object-metadata-update-collection`,
storage.objectMetadataUpdateCollection, storage.objectMetadataUpdateCollection,
); );
// Save object metadata delete collection // Save object metadata delete collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'object-metadata-delete-collection', `${workspaceId}/object-metadata-delete-collection`,
storage.objectMetadataDeleteCollection, storage.objectMetadataDeleteCollection,
); );
// Save field metadata create collection // Save field metadata create collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'field-metadata-create-collection', `${workspaceId}/field-metadata-create-collection`,
storage.fieldMetadataCreateCollection, storage.fieldMetadataCreateCollection,
); );
// Save field metadata update collection // Save field metadata update collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'field-metadata-update-collection', `${workspaceId}/field-metadata-update-collection`,
storage.fieldMetadataUpdateCollection, storage.fieldMetadataUpdateCollection,
); );
// Save field metadata delete collection // Save field metadata delete collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'field-metadata-delete-collection', `${workspaceId}/field-metadata-delete-collection`,
storage.fieldMetadataDeleteCollection, storage.fieldMetadataDeleteCollection,
); );
// Save relation metadata create collection // Save relation metadata create collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'relation-metadata-create-collection', `${workspaceId}/relation-metadata-create-collection`,
storage.relationMetadataCreateCollection, storage.relationMetadataCreateCollection,
); );
// Save relation metadata update collection // Save relation metadata update collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'relation-metadata-update-collection', `${workspaceId}/relation-metadata-update-collection`,
storage.relationMetadataUpdateCollection, storage.relationMetadataUpdateCollection,
); );
// Save relation metadata delete collection // Save relation metadata delete collection
await this.commandLogger.writeLog( await this.commandLogger.writeLog(
'relation-metadata-delete-collection', `${workspaceId}/relation-metadata-delete-collection`,
storage.relationMetadataDeleteCollection, storage.relationMetadataDeleteCollection,
); );
} }

View File

@ -5,12 +5,13 @@ import { Command, CommandRunner, Option } from 'nest-commander';
import { DataSourceService } from 'src/metadata/data-source/data-source.service'; import { DataSourceService } from 'src/metadata/data-source/data-source.service';
import { WorkspaceSyncMetadataService } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.service'; import { WorkspaceSyncMetadataService } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.service';
import { WorkspaceHealthService } from 'src/workspace/workspace-health/workspace-health.service'; import { WorkspaceHealthService } from 'src/workspace/workspace-health/workspace-health.service';
import { WorkspaceService } from 'src/core/workspace/services/workspace.service';
import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.service'; import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.service';
// TODO: implement dry-run // TODO: implement dry-run
interface RunWorkspaceMigrationsOptions { interface RunWorkspaceMigrationsOptions {
workspaceId: string; workspaceId?: string;
dryRun?: boolean; dryRun?: boolean;
force?: boolean; force?: boolean;
} }
@ -27,6 +28,7 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
private readonly workspaceHealthService: WorkspaceHealthService, private readonly workspaceHealthService: WorkspaceHealthService,
private readonly dataSourceService: DataSourceService, private readonly dataSourceService: DataSourceService,
private readonly syncWorkspaceLoggerService: SyncWorkspaceLoggerService, private readonly syncWorkspaceLoggerService: SyncWorkspaceLoggerService,
private readonly workspaceService: WorkspaceService,
) { ) {
super(); super();
} }
@ -35,56 +37,63 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
_passedParam: string[], _passedParam: string[],
options: RunWorkspaceMigrationsOptions, options: RunWorkspaceMigrationsOptions,
): Promise<void> { ): Promise<void> {
const issues = await this.workspaceHealthService.healthCheck( const workspaceIds = options.workspaceId
options.workspaceId, ? [options.workspaceId]
); : await this.workspaceService.getWorkspaceIds();
// Security: abort if there are issues. for (const workspaceId of workspaceIds) {
if (issues.length > 0) { const issues = await this.workspaceHealthService.healthCheck(workspaceId);
if (!options.force) {
this.logger.error( // Security: abort if there are issues.
`Workspace contains ${issues.length} issues, aborting.`, if (issues.length > 0) {
if (!options.force) {
this.logger.error(
`Workspace contains ${issues.length} issues, aborting.`,
);
this.logger.log(
'If you want to force the migration, use --force flag',
);
this.logger.log(
'Please use `workspace:health` command to check issues and fix them before running this command.',
);
return;
}
this.logger.warn(
`Workspace contains ${issues.length} issues, sync has been forced.`,
); );
this.logger.log('If you want to force the migration, use --force flag');
this.logger.log(
'Please use `workspace:health` command to check issues and fix them before running this command.',
);
return;
} }
this.logger.warn( const dataSourceMetadata =
`Workspace contains ${issues.length} issues, sync has been forced.`, await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
); workspaceId,
} );
const dataSourceMetadata = const { storage, workspaceMigrations } =
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail( await this.workspaceSyncMetadataService.syncStandardObjectsAndFieldsMetadata(
options.workspaceId, {
); workspaceId,
dataSourceId: dataSourceMetadata.id,
},
{ applyChanges: !options.dryRun },
);
const { storage, workspaceMigrations } = if (options.dryRun) {
await this.workspaceSyncMetadataService.syncStandardObjectsAndFieldsMetadata( await this.syncWorkspaceLoggerService.saveLogs(
{ workspaceId,
workspaceId: options.workspaceId, storage,
dataSourceId: dataSourceMetadata.id, workspaceMigrations,
}, );
{ applyChanges: !options.dryRun }, }
);
if (options.dryRun) {
await this.syncWorkspaceLoggerService.saveLogs(
storage,
workspaceMigrations,
);
} }
} }
@Option({ @Option({
flags: '-w, --workspace-id [workspace_id]', flags: '-w, --workspace-id [workspace_id]',
description: 'workspace id', description: 'workspace id',
required: true, required: false,
}) })
parseWorkspaceId(value: string): string { parseWorkspaceId(value: string): string {
return value; return value;

View File

@ -3,6 +3,7 @@ import { Module } from '@nestjs/common';
import { DataSourceModule } from 'src/metadata/data-source/data-source.module'; import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
import { WorkspaceSyncMetadataModule } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.module'; import { WorkspaceSyncMetadataModule } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.module';
import { WorkspaceHealthModule } from 'src/workspace/workspace-health/workspace-health.module'; import { WorkspaceHealthModule } from 'src/workspace/workspace-health/workspace-health.module';
import { WorkspaceModule } from 'src/core/workspace/workspace.module';
import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command'; import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command';
@ -12,6 +13,7 @@ import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.ser
imports: [ imports: [
WorkspaceSyncMetadataModule, WorkspaceSyncMetadataModule,
WorkspaceHealthModule, WorkspaceHealthModule,
WorkspaceModule,
DataSourceModule, DataSourceModule,
], ],
providers: [SyncWorkspaceMetadataCommand, SyncWorkspaceLoggerService], providers: [SyncWorkspaceMetadataCommand, SyncWorkspaceLoggerService],