Skip to content

Commit

Permalink
[frontend/backend] add a start now for scenario (#1368)
Browse files Browse the repository at this point in the history
Co-authored-by: Romuald Lemesle <romuald.lemesle@filigran.io>
  • Loading branch information
guillaumejparis and RomuDeuxfois authored Sep 12, 2024
1 parent 71df858 commit 8d75ef9
Show file tree
Hide file tree
Showing 23 changed files with 806 additions and 699 deletions.
10 changes: 5 additions & 5 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ steps:
- name: frontend-tests
image: node:20-alpine
volumes:
- name: cache-node-frontend
path: /drone/src/openbas-front/node_modules
- name: cache-node-frontend
path: /drone/src/openbas-front/node_modules
commands:
- cd openbas-front
- yarn install
- yarn build
- yarn check-ts
- yarn lint
# - yarn i18n-checker
- yarn i18n-checker
- NODE_OPTIONS=--max_old_space_size=8192 yarn test

- name: app-e2e
Expand Down Expand Up @@ -66,8 +66,8 @@ steps:
- name: frontend-e2e-tests
image: node:20.16.0
volumes:
- name: cache-node-frontend-e2e
path: /drone/src/openbas-front/node_modules
- name: cache-node-frontend-e2e
path: /drone/src/openbas-front/node_modules
commands:
- apt update
- apt -y install netcat-traditional
Expand Down
476 changes: 243 additions & 233 deletions openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ private void createExercisesFromScenarios() {
validScenarios.stream()
.filter(scenario -> !alreadyExistIds.contains(scenario.getId()))
// Create simulation with start date provided by cron
.forEach(scenario -> this.scenarioToExerciseService.toExercise(scenario, cronToDate(scenario.getRecurrence())));
.forEach(scenario -> this.scenarioToExerciseService.toExercise(scenario, cronToDate(scenario.getRecurrence()),
false));
}

private void cleanOutdatedRecurringScenario() {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import static io.openbas.utils.fixtures.InjectFixture.getInjectForEmailContract;
import static io.openbas.utils.fixtures.ObjectiveFixture.OBJECTIVE_NAME;
import static io.openbas.utils.fixtures.ObjectiveFixture.getObjective;
import static io.openbas.utils.fixtures.ScenarioFixture.getScenario;
import static io.openbas.utils.fixtures.TagFixture.getTag;
import static io.openbas.utils.fixtures.TeamFixture.getTeam;
import static io.openbas.utils.fixtures.UserFixture.getUser;
Expand Down Expand Up @@ -220,7 +219,7 @@ void scenarioToExerciseTest() {
VARIABLE_ID = variableSaved.getId();

// -- EXECUTE --
Exercise exercise = this.scenarioToExerciseService.toExercise(scenario, null);
Exercise exercise = this.scenarioToExerciseService.toExercise(scenario, null, false);
EXERCISE_ID = exercise.getId();
Exercise exerciseSaved = this.loadService.exercise(EXERCISE_ID);

Expand Down
16 changes: 11 additions & 5 deletions openbas-front/i18n-checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const checkLanguageSupport = (lang) => {
const match = (filePath) => {
try {
const data = fs.readFileSync(filePath, { encoding: 'utf8' });
const regexp = /t\('([\w\s]+)'\)/g;
const regexp = /(?<![a-zA-Z])t\('([\w\s]+)'\)/g;
const matches = [...data.matchAll(regexp)];
matches.forEach((m) => {
const regexWithQuote = `'${m[1]}':`;
Expand Down Expand Up @@ -57,16 +57,22 @@ const checkLanguageSupport = (lang) => {

const run = () => {
const languages = ['fr', 'zh'];
const _missingKeys = {};
const missingKeys = {};

languages.forEach((lang) => {
const keys = checkLanguageSupport(lang);
if (keys.length > 0) {
_missingKeys[lang] = keys;
missingKeys[lang] = keys;
}
});

return _missingKeys;
if (Object.keys(missingKeys).length) {
// eslint-disable-next-line no-console
console.error('Missing keys :', missingKeys);
process.exit(1);
} else {
process.exit(0);
}
};

const _missingKeys = run();
run();
5 changes: 0 additions & 5 deletions openbas-front/src/actions/Inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ export const fetchInject = (injectId) => (dispatch) => {
return getReferential(schema.inject, uri)(dispatch);
};

export const tryInject = (injectId) => (dispatch) => {
const uri = `/api/injects/try/${injectId}`;
return getReferential(null, uri, null)(dispatch);
};

// -- EXERCISES --

export const fetchExerciseInjects = (exerciseId) => (dispatch) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const fetchInjectResultDto = (injectId: string) => {

export const deleteAtomicTesting = (injectId: string) => {
const uri = `${ATOMIC_TESTING_URI}/${injectId}`;
return simpleDelCall(uri, injectId);
return simpleDelCall(uri);
};

export const updateAtomicTesting = (injectId: string, data: AtomicTestingInput) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ export const fetchInjectTestStatus = (testId: string | undefined) => {

export const deleteInjectTest = (testId: string | undefined) => {
const uri = `/api/injects/test/${testId}`;
return simpleDelCall(uri, testId);
return simpleDelCall(uri);
};
6 changes: 5 additions & 1 deletion openbas-front/src/actions/injects/inject-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Dispatch } from 'redux';
import { getReferential, simpleCall, simplePostCall } from '../../utils/Action';
import type { Exercise, Scenario, SearchPaginationInput } from '../../utils/api-types';
import * as schema from '../Schema';
import { MESSAGING$ } from '../../utils/Environment';

export const testInject = (injectId: string) => {
const uri = `/api/injects/${injectId}/test`;
Expand All @@ -11,7 +12,10 @@ export const testInject = (injectId: string) => {
export const bulkTestInjects = (injectIds: string[]) => {
const data = injectIds;
const uri = '/api/injects/bulk/test';
return simplePostCall(uri, data, "Can't be tested");
return simplePostCall(uri, data, false).catch((error) => {
MESSAGING$.notifyError('Can\'t be tested');
throw error;
});
};

// -- EXERCISES --
Expand Down
2 changes: 1 addition & 1 deletion openbas-front/src/actions/mapper/mapper-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const fetchMapper = (mapperId: string) => {

export const deleteMapper = (mapperId: RawPaginationImportMapper['import_mapper_id']) => {
const uri = `${XLS_MAPPER_URI}/${mapperId}`;
return simpleDelCall(uri, mapperId);
return simpleDelCall(uri);
};

export const createMapper = (data: ImportMapperAddInput) => {
Expand Down
7 changes: 7 additions & 0 deletions openbas-front/src/actions/scenarios/scenario-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ export const duplicateScenario = (scenarioId: string) => (dispatch: Dispatch) =>
return postReferential(scenario, uri, null)(dispatch);
};

// -- SCENARIO TO EXERCISE

export const createRunningExerciseFromScenario = (scenarioId: string) => {
const uri = `${SCENARIO_URI}/${scenarioId}/exercise/running`;
return simplePostCall(uri);
};

// -- TEAMS --

export const fetchScenarioTeams = (scenarioId: Scenario['scenario_id']) => (dispatch: Dispatch) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { FunctionComponent, useContext, useState } from 'react';
import { Link } from 'react-router-dom';
import { Alert, Button, Dialog, DialogActions, DialogContent, DialogContentText, IconButton, Menu, MenuItem, Table, TableBody, TableCell, TableRow } from '@mui/material';
import { Button, Dialog, DialogActions, DialogContent, DialogContentText, IconButton, Menu, MenuItem, Table, TableBody, TableCell, TableRow } from '@mui/material';
import { MoreVert } from '@mui/icons-material';
import { useFormatter } from '../../../../components/i18n';
import Transition from '../../../../components/common/Transition';
import { InjectContext, PermissionsContext } from '../Context';
import type { Inject, InjectStatus, InjectStatusExecution, InjectTestStatus } from '../../../../utils/api-types';
import { duplicateInjectForExercise, duplicateInjectForScenario, tryInject } from '../../../../actions/Inject';
import { duplicateInjectForExercise, duplicateInjectForScenario } from '../../../../actions/Inject';
import { testInject } from '../../../../actions/injects/inject-action';
import { useAppDispatch } from '../../../../utils/hooks';
import DialogDuplicate from '../../../../components/common/DialogDuplicate';
Expand Down Expand Up @@ -62,7 +62,6 @@ const InjectPopover: FunctionComponent<Props> = ({

const [openDelete, setOpenDelete] = useState(false);
const [duplicate, setDuplicate] = useState(false);
const [openTry, setOpenTry] = useState(false);
const [openTest, setOpenTest] = useState(false);
const [openEnable, setOpenEnable] = useState(false);
const [openDisable, setOpenDisable] = useState(false);
Expand Down Expand Up @@ -114,22 +113,11 @@ const InjectPopover: FunctionComponent<Props> = ({
});
};

const handleCloseTry = () => setOpenTry(false);

const handleCloseResult = () => {
setOpenResult(false);
setInjectResult(null);
};

const submitTry = () => {
// FIXME: remove try possibility
dispatch(tryInject(inject.inject_id)).then((payload: InjectStatus) => {
setInjectResult(payload);
setOpenResult(true);
});
handleCloseTry();
};

const handleOpenTest = () => {
setOpenTest(true);
handlePopoverClose();
Expand Down Expand Up @@ -254,15 +242,6 @@ const InjectPopover: FunctionComponent<Props> = ({
{t('Trigger now')}
</MenuItem>
)}
{/* TODO create an atomic testing when using this button */}
{/* {inject.inject_type !== 'openbas_manual' && ( */}
{/* <MenuItem */}
{/* onClick={handleOpenTry} */}
{/* disabled={isDisabled} */}
{/* > */}
{/* {t('Try the inject')} */}
{/* </MenuItem> */}
{/* )} */}
{inject.inject_enabled ? (
<MenuItem
onClick={handleOpenDisable}
Expand Down Expand Up @@ -328,29 +307,6 @@ const InjectPopover: FunctionComponent<Props> = ({
</Button>
</DialogActions>
</Dialog>
<Dialog
TransitionComponent={Transition}
open={openTry}
onClose={handleCloseTry}
PaperProps={{ elevation: 1 }}
>
<DialogContent>
<DialogContentText>
<p>{t(`Do you want to try this inject: ${inject.inject_title}?`)}</p>
<Alert severity="info">
{t('The inject will only be sent to you.')}
</Alert>
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseTry}>
{t('Cancel')}
</Button>
<Button color="secondary" onClick={submitTry}>
{t('Try')}
</Button>
</DialogActions>
</Dialog>
<DialogTest
open={openTest}
handleClose={handleCloseTest}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const IndexScenarioComponent: FunctionComponent<{ scenario: ScenarioStore }> = (
tabValue = `/admin/scenarios/${scenario.scenario_id}/tests`;
}
const [openScenarioRecurringFormDialog, setOpenScenarioRecurringFormDialog] = useState<boolean>(false);
const [openInstantiateSimulationAndStart, setOpenInstantiateSimulationAndStart] = useState<boolean>(false);
const [selectRecurring, setSelectRecurring] = useState('noRepeat');
const [cronExpression, setCronExpression] = useState<string | null>(scenario.scenario_recurrence || null);
const [parsedCronExpression, setParsedCronExpression] = useState<ParsedCron | null>(scenario.scenario_recurrence ? parseCron(scenario.scenario_recurrence) : null);
Expand All @@ -74,7 +75,7 @@ const IndexScenarioComponent: FunctionComponent<{ scenario: ScenarioStore }> = (
if (!cronExpression || !parsedCronExpression) {
return null;
}
let sentence = '';
let sentence: string;
if (noRepeat) {
sentence = `${fld(scenario.scenario_recurrence_start)} ${t('recurrence_at')} ${ft(new Date().setUTCHours(parsedCronExpression.h, parsedCronExpression.m, 0))}`;
} else {
Expand Down Expand Up @@ -110,6 +111,8 @@ const IndexScenarioComponent: FunctionComponent<{ scenario: ScenarioStore }> = (
selectRecurring={selectRecurring}
setOpenScenarioRecurringFormDialog={setOpenScenarioRecurringFormDialog}
openScenarioRecurringFormDialog={openScenarioRecurringFormDialog}
setOpenInstantiateSimulationAndStart={setOpenInstantiateSimulationAndStart}
openInstantiateSimulationAndStart={openInstantiateSimulationAndStart}
noRepeat={noRepeat}
/>
<Box
Expand Down Expand Up @@ -175,7 +178,7 @@ const IndexScenarioComponent: FunctionComponent<{ scenario: ScenarioStore }> = (
</Box>
<Suspense fallback={<Loader />}>
<Routes>
<Route path="" element={errorWrapper(Scenario)({ setOpenScenarioRecurringFormDialog })} />
<Route path="" element={errorWrapper(Scenario)({ setOpenInstantiateSimulationAndStart })} />
<Route path="definition" element={errorWrapper(ScenarioDefinition)()} />
<Route path="injects" element={errorWrapper(Injects)()} />
<Route path="tests/:statusId?" element={errorWrapper(Tests)()} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const useStyles = makeStyles(() => ({
},
}));

const Scenario = ({ setOpenScenarioRecurringFormDialog }: { setOpenScenarioRecurringFormDialog: React.Dispatch<React.SetStateAction<boolean>> }) => {
const Scenario = ({ setOpenInstantiateSimulationAndStart }: { setOpenInstantiateSimulationAndStart: React.Dispatch<React.SetStateAction<boolean>> }) => {
// Standard hooks
const classes = useStyles();
const theme = useTheme<Theme>();
Expand Down Expand Up @@ -245,9 +245,9 @@ const Scenario = ({ setOpenScenarioRecurringFormDialog }: { setOpenScenarioRecur
variant="contained"
color="primary"
size="large"
onClick={() => setOpenScenarioRecurringFormDialog(true)}
onClick={() => setOpenInstantiateSimulationAndStart(true)}
>
{t('Simulate Now')}
{t('Launch simulation now')}
</Button>
</div>
)}
Expand Down
Loading

0 comments on commit 8d75ef9

Please sign in to comment.