Skip to content

Commit 2941d04

Browse files
authored
[Security Solution][Auto migrations] Realign process status names (#223901)
## Summary This PR re-aligns the names used to maintain consistency across the codebase: - **SiemMigrationTaskStatus**: - New `INTERRUPTED` status for when the process was automatically aborted (server shutdown scenario). - Use the `STOPPED` status for when the user manually aborts the process (`/stop` API route via `Stop` button in the UI) - Avoid using the `ABORTED` as a status since it's confusing. Both of the scenarios above end up aborting the process. - **last_execution**: - `is_aborted` renamed to `is_stopped` for consistency with `SiemMigrationTaskStatus.STOPPED`. - `ended_at` renamed to `finished_at` for consistency with `SiemMigrationTaskStatus.FINISHED`. There shouldn't be any change in the behaviour.
1 parent 37fceaf commit 2941d04

File tree

17 files changed

+127
-186
lines changed

17 files changed

+127
-186
lines changed

x-pack/solutions/security/plugins/security_solution/common/siem_migrations/constants.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ export enum SiemMigrationTaskStatus {
4141
READY = 'ready',
4242
/** The Migration is in progress */
4343
RUNNING = 'running',
44-
/** The Migration process has been stopped for some reason unrelated to the user, usually a server restart. */
44+
/** The Migration is explicitly stopped by user */
4545
STOPPED = 'stopped',
46-
/** The Migration is completed without any issues */
46+
/** The Migration process has been interrupted, usually a server restart. */
47+
INTERRUPTED = 'interrupted',
48+
/** The Migration process is finished */
4749
FINISHED = 'finished',
48-
/** The Migration is explicitly aborted by user */
49-
ABORTED = 'aborted',
5050
}
5151

5252
export enum SiemMigrationStatus {

x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.gen.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ export const RuleMigrationLastExecution = z.object({
151151
*/
152152
started_at: z.string().optional(),
153153
/**
154-
* The moment the last execution ended.
154+
* The moment the last execution finished.
155155
*/
156-
ended_at: z.string().nullable().optional(),
156+
finished_at: z.string().nullable().optional(),
157157
/**
158158
* The connector ID used for the last execution.
159159
*/
@@ -163,9 +163,9 @@ export const RuleMigrationLastExecution = z.object({
163163
*/
164164
error: z.string().nullable().optional(),
165165
/**
166-
* Indicates if the last execution was aborted by the user.
166+
* Indicates if the last execution was stopped by the user.
167167
*/
168-
is_aborted: z.boolean().optional(),
168+
is_stopped: z.boolean().optional(),
169169
/**
170170
* Indicates if the last execution skipped pre-built rule matching.
171171
*/
@@ -314,7 +314,7 @@ export const RuleMigrationTaskStatus = z.enum([
314314
'running',
315315
'stopped',
316316
'finished',
317-
'aborted',
317+
'interrupted',
318318
]);
319319
export type RuleMigrationTaskStatusEnum = typeof RuleMigrationTaskStatus.enum;
320320
export const RuleMigrationTaskStatusEnum = RuleMigrationTaskStatus.enum;

x-pack/solutions/security/plugins/security_solution/common/siem_migrations/model/rule_migration.schema.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ components:
261261
- running
262262
- stopped
263263
- finished
264-
- aborted
264+
- interrupted
265265

266266
RuleMigrationTranslationStats:
267267
type: object
@@ -478,20 +478,20 @@ components:
478478
started_at:
479479
type: string
480480
description: The moment the last execution started.
481-
ended_at:
481+
finished_at:
482482
type: string
483483
nullable: true
484-
description: The moment the last execution ended.
484+
description: The moment the last execution finished.
485485
connector_id:
486486
type: string
487487
description: The connector ID used for the last execution.
488488
error:
489489
type: string
490490
nullable: true
491491
description: The error message if the last execution failed.
492-
is_aborted:
492+
is_stopped:
493493
type: boolean
494-
description: Indicates if the last execution was aborted by the user.
494+
description: Indicates if the last execution was stopped by the user.
495495
skip_prebuilt_rules_matching:
496496
type: boolean
497497
description: Indicates if the last execution skipped pre-built rule matching.

x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/siem_migrations/start_migration/rule_migrations_panels.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ export const RuleMigrationsPanels = React.memo<RuleMigrationsPanelsProps>(
7575
>
7676
{[
7777
SiemMigrationTaskStatus.READY,
78+
SiemMigrationTaskStatus.INTERRUPTED,
7879
SiemMigrationTaskStatus.STOPPED,
79-
SiemMigrationTaskStatus.ABORTED,
8080
].includes(migrationStats.status) && (
8181
<MigrationReadyPanel migrationStats={migrationStats} />
8282
)}

x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/migration_status_panels/migration_ready_panel.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ const mockMigrationStateWithError = {
4848
number: 1,
4949
};
5050

51-
const mockMigrationStatsAborted = {
52-
status: SiemMigrationTaskStatus.ABORTED,
51+
const mockMigrationStatsStopped = {
52+
status: SiemMigrationTaskStatus.STOPPED,
5353
id: 'c44d2c7d-0de1-4231-8b82-0dcfd67a9fe3',
5454
rules: { total: 6, pending: 6, processing: 0, completed: 0, failed: 0 },
5555
created_at: '2025-05-27T12:12:17.563Z',
@@ -126,14 +126,14 @@ describe('MigrationReadyPanel', () => {
126126

127127
describe('Aborted Migration', () => {
128128
it('should render aborted migration message', () => {
129-
render(<MigrationReadyPanel migrationStats={mockMigrationStatsAborted} />);
129+
render(<MigrationReadyPanel migrationStats={mockMigrationStatsStopped} />);
130130
expect(screen.getByTestId('ruleMigrationDescription')).toHaveTextContent(
131131
'Migration of 6 rules was stopped. You can resume it any time.'
132132
);
133133
});
134134

135135
it('should render correct start migration button for aborted migration', () => {
136-
render(<MigrationReadyPanel migrationStats={mockMigrationStatsAborted} />);
136+
render(<MigrationReadyPanel migrationStats={mockMigrationStatsStopped} />);
137137
expect(screen.getByTestId('startMigrationButton')).toHaveTextContent('Resume translation');
138138
});
139139
});

x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/migration_status_panels/migration_ready_panel.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ export const MigrationReadyPanel = React.memo<MigrationReadyPanelProps>(({ migra
4040
});
4141
}, [openFlyout, migrationStats, telemetry, missingResources.length]);
4242

43-
const isAborted = useMemo(
44-
() => migrationStats.status === SiemMigrationTaskStatus.ABORTED,
43+
const isStopped = useMemo(
44+
() => migrationStats.status === SiemMigrationTaskStatus.STOPPED,
4545
[migrationStats.status]
4646
);
4747

@@ -50,12 +50,12 @@ export const MigrationReadyPanel = React.memo<MigrationReadyPanelProps>(({ migra
5050
return i18n.RULE_MIGRATION_ERROR_DESCRIPTION(migrationStats.rules.total);
5151
}
5252

53-
if (isAborted) {
54-
return i18n.RULE_MIGRATION_ABORTED_DESCRIPTION(migrationStats.rules.total);
53+
if (isStopped) {
54+
return i18n.RULE_MIGRATION_STOPPED_DESCRIPTION(migrationStats.rules.total);
5555
}
5656

5757
return i18n.RULE_MIGRATION_READY_DESCRIPTION(migrationStats.rules.total);
58-
}, [migrationStats.last_execution?.error, migrationStats.rules.total, isAborted]);
58+
}, [migrationStats.last_execution?.error, migrationStats.rules.total, isStopped]);
5959

6060
return (
6161
<EuiPanel hasShadow={false} hasBorder paddingSize="m">
@@ -95,7 +95,7 @@ export const MigrationReadyPanel = React.memo<MigrationReadyPanelProps>(({ migra
9595
{i18n.RULE_MIGRATION_UPLOAD_BUTTON}
9696
</EuiButton>
9797
) : (
98-
<StartTranslationButton migrationId={migrationStats.id} isAborted={isAborted} />
98+
<StartTranslationButton migrationId={migrationStats.id} isStopped={isStopped} />
9999
)}
100100
</EuiFlexItem>
101101
)}
@@ -111,8 +111,8 @@ export const MigrationReadyPanel = React.memo<MigrationReadyPanelProps>(({ migra
111111
});
112112
MigrationReadyPanel.displayName = 'MigrationReadyPanel';
113113

114-
const StartTranslationButton = React.memo<{ migrationId: string; isAborted: boolean }>(
115-
({ migrationId, isAborted }) => {
114+
const StartTranslationButton = React.memo<{ migrationId: string; isStopped: boolean }>(
115+
({ migrationId, isStopped }) => {
116116
const { startMigration, isLoading } = useStartMigration();
117117
const onStartMigration = useCallback(() => {
118118
startMigration(migrationId);
@@ -126,7 +126,7 @@ const StartTranslationButton = React.memo<{ migrationId: string; isAborted: bool
126126
isLoading={isLoading}
127127
size="s"
128128
>
129-
{isAborted
129+
{isStopped
130130
? i18n.RULE_MIGRATION_RESTART_TRANSLATION_BUTTON
131131
: i18n.RULE_MIGRATION_START_TRANSLATION_BUTTON}
132132
</EuiButton>

x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/components/migration_status_panels/translations.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ export const RULE_MIGRATION_ERROR_DESCRIPTION = (totalRules: number) => {
2222
});
2323
};
2424

25-
export const RULE_MIGRATION_ABORTED_DESCRIPTION = (totalRules: number) => {
26-
return i18n.translate('xpack.securitySolution.siemMigrations.rules.panel.aborted.description', {
25+
export const RULE_MIGRATION_STOPPED_DESCRIPTION = (totalRules: number) => {
26+
return i18n.translate('xpack.securitySolution.siemMigrations.rules.panel.stopped.description', {
2727
defaultMessage: 'Migration of {totalRules} rules was stopped. You can resume it any time.',
2828
values: { totalRules },
2929
});

x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/pages/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ export const MigrationRulesPage: React.FC<MigrationRulesPageProps> = React.memo(
118118
)}
119119
{[
120120
SiemMigrationTaskStatus.READY,
121+
SiemMigrationTaskStatus.INTERRUPTED,
121122
SiemMigrationTaskStatus.STOPPED,
122-
SiemMigrationTaskStatus.ABORTED,
123123
].includes(migrationStats.status) && (
124124
<MigrationReadyPanel migrationStats={migrationStats} />
125125
)}

x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.test.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ describe('SiemRulesMigrationsService', () => {
281281

282282
service.getRuleMigrationsStats = getStatsMock;
283283

284-
// Ensure a valid connector is present (so that a STOPPED migration would be resumed, if needed)
284+
// Ensure a valid connector is present (so that a INTERRUPTED migration would be resumed, if needed)
285285
jest.spyOn(service.connectorIdStorage, 'get').mockReturnValue('connector-123');
286286

287287
// Start polling
@@ -306,12 +306,12 @@ describe('SiemRulesMigrationsService', () => {
306306
jest.useRealTimers();
307307
});
308308

309-
describe('when a stopped migration is found', () => {
310-
it('should not start a stopped migration if migration had errors', async () => {
309+
describe('when a interrupted migration is found', () => {
310+
it('should not start a interrupted migration if migration had errors', async () => {
311311
jest.useFakeTimers();
312-
const stoppedMigration = {
312+
const interruptedMigration = {
313313
id: 'mig-1',
314-
status: SiemMigrationTaskStatus.STOPPED,
314+
status: SiemMigrationTaskStatus.INTERRUPTED,
315315
last_execution: {
316316
error: 'some failure',
317317
},
@@ -321,7 +321,7 @@ describe('SiemRulesMigrationsService', () => {
321321
service.getRuleMigrationsStats = jest
322322
.fn()
323323
.mockResolvedValue([finishedMigration])
324-
.mockResolvedValueOnce([stoppedMigration]);
324+
.mockResolvedValueOnce([interruptedMigration]);
325325

326326
jest.spyOn(service.connectorIdStorage, 'get').mockReturnValue('connector-123');
327327
jest.spyOn(service, 'hasMissingCapabilities').mockReturnValueOnce(false);
@@ -343,15 +343,15 @@ describe('SiemRulesMigrationsService', () => {
343343
jest.useRealTimers();
344344
});
345345

346-
it('should not start a stopped migration if no connector configured', async () => {
346+
it('should not start a interrupted migration if no connector configured', async () => {
347347
jest.useFakeTimers();
348-
const stoppedMigration = { id: 'mig-1', status: SiemMigrationTaskStatus.STOPPED };
348+
const interruptedMigration = { id: 'mig-1', status: SiemMigrationTaskStatus.INTERRUPTED };
349349
const finishedMigration = { id: 'mig-1', status: SiemMigrationTaskStatus.FINISHED };
350350

351351
service.getRuleMigrationsStats = jest
352352
.fn()
353353
.mockResolvedValue([finishedMigration])
354-
.mockResolvedValueOnce([stoppedMigration]);
354+
.mockResolvedValueOnce([interruptedMigration]);
355355

356356
jest.spyOn(service.connectorIdStorage, 'get').mockReturnValue(undefined);
357357
jest.spyOn(service, 'hasMissingCapabilities').mockReturnValueOnce(false);
@@ -374,23 +374,23 @@ describe('SiemRulesMigrationsService', () => {
374374
jest.useRealTimers();
375375
});
376376

377-
it('should not start a stopped migration if user is missing capabilities', async () => {
377+
it('should not start a interrupted migration if user is missing capabilities', async () => {
378378
// Use fake timers to simulate delays inside the polling loop.
379379
jest.useFakeTimers();
380-
// Simulate a migration that is first reported as STOPPED and then FINISHED.
381-
const stoppedMigration = { id: 'mig-1', status: SiemMigrationTaskStatus.STOPPED };
380+
// Simulate a migration that is first reported as INTERRUPTED and then FINISHED.
381+
const interruptedMigration = { id: 'mig-1', status: SiemMigrationTaskStatus.INTERRUPTED };
382382
const finishedMigration = { id: 'mig-1', status: SiemMigrationTaskStatus.FINISHED };
383383

384384
// Override getRuleMigrationsStats to return our sequence:
385-
// First call: stopped, then finished, then empty array.
385+
// First call: interrupted, then finished, then empty array.
386386
const getStatsMock = jest
387387
.fn()
388388
.mockResolvedValue([finishedMigration])
389-
.mockResolvedValueOnce([stoppedMigration]);
389+
.mockResolvedValueOnce([interruptedMigration]);
390390

391391
service.getRuleMigrationsStats = getStatsMock;
392392

393-
// Ensure a valid connector is present (so that a STOPPED migration would be resumed, if needed)
393+
// Ensure a valid connector is present (so that a INTERRUPTED migration would be resumed, if needed)
394394
jest.spyOn(service.connectorIdStorage, 'get').mockReturnValue('connector-123');
395395
jest.spyOn(service, 'hasMissingCapabilities').mockReturnValueOnce(true);
396396

@@ -412,11 +412,11 @@ describe('SiemRulesMigrationsService', () => {
412412
jest.useRealTimers();
413413
});
414414

415-
it('should automatically start the stopped migration with last_execution values', async () => {
415+
it('should automatically start the interrupted migration with last_execution values', async () => {
416416
jest.useFakeTimers();
417-
const stoppedMigration = {
417+
const interruptedMigration = {
418418
id: 'mig-1',
419-
status: SiemMigrationTaskStatus.STOPPED,
419+
status: SiemMigrationTaskStatus.INTERRUPTED,
420420
last_execution: {
421421
connector_id: 'connector-last',
422422
skip_prebuilt_rules_matching: true,
@@ -427,7 +427,7 @@ describe('SiemRulesMigrationsService', () => {
427427
service.getRuleMigrationsStats = jest
428428
.fn()
429429
.mockResolvedValue([finishedMigration])
430-
.mockResolvedValueOnce([stoppedMigration]);
430+
.mockResolvedValueOnce([interruptedMigration]);
431431

432432
jest.spyOn(service.connectorIdStorage, 'get').mockReturnValue('connector-123');
433433
jest.spyOn(service, 'hasMissingCapabilities').mockReturnValueOnce(false);

x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,17 @@ export class SiemRulesMigrationsService {
274274
pendingMigrationIds.push(result.id);
275275
}
276276

277-
// automatically resume stopped migrations when all conditions are met
278-
if (result.status === SiemMigrationTaskStatus.STOPPED && !result.last_execution?.error) {
277+
// automatically resume interrupted migrations when the proper conditions are met
278+
if (
279+
result.status === SiemMigrationTaskStatus.INTERRUPTED &&
280+
!result.last_execution?.error
281+
) {
279282
const connectorId = result.last_execution?.connector_id ?? this.connectorIdStorage.get();
280283
const skipPrebuiltRulesMatching = result.last_execution?.skip_prebuilt_rules_matching;
281284
if (connectorId && !this.hasMissingCapabilities('all')) {
282285
await api.startRuleMigration({
283286
migrationId: result.id,
284-
settings: {
285-
connectorId,
286-
skipPrebuiltRulesMatching,
287-
},
287+
settings: { connectorId, skipPrebuiltRulesMatching },
288288
});
289289
pendingMigrationIds.push(result.id);
290290
}

0 commit comments

Comments
 (0)