feat: 持久化运维审计日志

This commit is contained in:
湛兮
2026-06-11 22:57:05 +08:00
parent 2181fc7389
commit 588caa4209
8 changed files with 243 additions and 61 deletions
+10 -10
View File
@@ -42,7 +42,7 @@ export class DeployExecutionService {
);
let currentStep: string | undefined;
this.auditService.record({
await this.auditService.record({
action: 'DEPLOY_EXECUTION_STARTED',
resourceType: 'deploy_run',
resourceId: currentRun.id,
@@ -95,7 +95,7 @@ export class DeployExecutionService {
}),
);
this.auditService.record({
await this.auditService.record({
action: 'DEPLOY_SUCCEEDED',
resourceType: 'deploy_run',
resourceId: currentRun.id,
@@ -132,7 +132,7 @@ export class DeployExecutionService {
currentRun = await this.advanceNotification(currentRun, 'failed');
this.auditService.record({
await this.auditService.record({
action: 'DEPLOY_FAILED',
resourceType: 'deploy_run',
resourceId: currentRun.id,
@@ -197,7 +197,7 @@ export class DeployExecutionService {
`Jenkins build #${queueItem.buildNumber} is running.`,
);
this.auditService.record({
await this.auditService.record({
action: 'JENKINS_BUILD_STARTED',
resourceType: 'deploy_run',
resourceId: currentRun.id,
@@ -268,7 +268,7 @@ export class DeployExecutionService {
'success',
);
this.auditService.record({
await this.auditService.record({
action: 'JENKINS_DRY_RUN_COMPLETED',
resourceType: 'deploy_run',
resourceId: run.id,
@@ -316,7 +316,7 @@ export class DeployExecutionService {
: `Jenkins queue ${queueItem.queueId} accepted.`,
);
this.auditService.record({
await this.auditService.record({
action: 'JENKINS_BUILD_TRIGGERED',
resourceType: 'deploy_run',
resourceId: run.id,
@@ -352,7 +352,7 @@ export class DeployExecutionService {
notification.status === 'sent' ? undefined : notification.reason,
);
this.auditService.record({
await this.auditService.record({
action: `DEPLOY_NOTIFICATION_${notification.status.toUpperCase()}`,
resourceType: 'deploy_run',
resourceId: run.id,
@@ -393,7 +393,7 @@ export class DeployExecutionService {
}),
);
this.auditService.record({
await this.auditService.record({
action: 'DEPLOY_SUCCEEDED',
resourceType: 'deploy_run',
resourceId: currentRun.id,
@@ -429,7 +429,7 @@ export class DeployExecutionService {
})) ?? currentRun;
currentRun = await this.advanceNotification(currentRun, 'failed');
this.auditService.record({
await this.auditService.record({
action: 'DEPLOY_FAILED',
resourceType: 'deploy_run',
resourceId: currentRun.id,
@@ -538,7 +538,7 @@ export class DeployExecutionService {
const notification =
await this.deployNotificationService.sendDeployRunEvent(run, event);
this.auditService.record({
await this.auditService.record({
action: `DEPLOY_NOTIFICATION_${notification.status.toUpperCase()}`,
resourceType: 'deploy_run',
resourceId: run.id,
+16 -13
View File
@@ -61,10 +61,10 @@ export class DeployRunsService {
}
const project = await this.projectsService.getProject(input.projectKey);
this.validateReleaseRequest(input, project);
await this.validateReleaseRequest(input, project);
const run = await this.deployRunRepository.create(input);
this.auditService.record({
await this.auditService.record({
action: 'DEPLOY_REQUESTED',
resourceType: 'deploy_run',
resourceId: run.id,
@@ -94,7 +94,7 @@ export class DeployRunsService {
);
}
this.auditService.record({
await this.auditService.record({
action: 'DEPLOY_CANCELED',
resourceType: 'deploy_run',
resourceId: run.id,
@@ -150,7 +150,7 @@ export class DeployRunsService {
}
}
this.auditService.record({
await this.auditService.record({
action: 'JENKINS_SYNC_SWEEP_COMPLETED',
resourceType: 'deploy_run',
after: {
@@ -175,7 +175,7 @@ export class DeployRunsService {
const notification =
await this.deployNotificationService.sendDeployRunEvent(run, event);
this.auditService.record({
await this.auditService.record({
action: `DEPLOY_NOTIFICATION_${notification.status.toUpperCase()}`,
resourceType: 'deploy_run',
resourceId: run.id,
@@ -194,12 +194,12 @@ export class DeployRunsService {
);
}
private validateReleaseRequest(
private async validateReleaseRequest(
input: CreateDeployRunInput,
project: ProjectSummary,
): ProjectEnvironmentSummary {
): Promise<ProjectEnvironmentSummary> {
if (project.status !== 'active') {
this.recordDeployRejected(input, 'Project is archived');
await this.recordDeployRejected(input, 'Project is archived');
throw new AppError(
'VALIDATION_FAILED',
`Project ${project.key} is archived and cannot be deployed`,
@@ -213,7 +213,7 @@ export class DeployRunsService {
);
if (!environment) {
this.recordDeployRejected(input, 'Environment is not configured');
await this.recordDeployRejected(input, 'Environment is not configured');
throw new AppError(
'VALIDATION_FAILED',
`Project ${project.key} does not expose ${input.environment} environment`,
@@ -223,7 +223,10 @@ export class DeployRunsService {
}
if (!new RegExp(environment.refPattern).test(input.ref)) {
this.recordDeployRejected(input, 'Ref does not match release policy');
await this.recordDeployRejected(
input,
'Ref does not match release policy',
);
throw new AppError(
'VALIDATION_FAILED',
`Ref ${input.ref} does not match ${environment.releasePolicy} release policy`,
@@ -241,11 +244,11 @@ export class DeployRunsService {
return environment;
}
private recordDeployRejected(
private async recordDeployRejected(
input: CreateDeployRunInput,
reason: string,
): void {
this.auditService.record({
): Promise<void> {
await this.auditService.record({
action: 'DEPLOY_REJECTED',
resourceType: 'deploy_run',
actorName: input.operator,
@@ -54,7 +54,7 @@ export class JenkinsSyncSchedulerService
try {
const summary = await this.deployRunsService.syncJenkinsRuns();
this.auditService.record({
await this.auditService.record({
action: 'JENKINS_AUTO_SYNC_TICK_COMPLETED',
resourceType: 'deploy_run',
after: {
@@ -67,7 +67,7 @@ export class JenkinsSyncSchedulerService
const message =
error instanceof Error ? error.message : 'Jenkins auto sync failed';
this.auditService.record({
await this.auditService.record({
action: 'JENKINS_AUTO_SYNC_TICK_FAILED',
resourceType: 'deploy_run',
after: {