diff --git a/openbas-api/src/main/java/io/openbas/scheduler/jobs/InjectsExecutionJob.java b/openbas-api/src/main/java/io/openbas/scheduler/jobs/InjectsExecutionJob.java index 257f702510..dfc58ae530 100644 --- a/openbas-api/src/main/java/io/openbas/scheduler/jobs/InjectsExecutionJob.java +++ b/openbas-api/src/main/java/io/openbas/scheduler/jobs/InjectsExecutionJob.java @@ -181,7 +181,7 @@ private void executeInject(ExecutableInject executableInject) { Inject inject = executableInject.getInjection().getInject(); // We are now checking if we depend on another inject and if it did not failed - Optional> errorMessages = null; + Optional> errorMessages = Optional.empty(); if (executableInject.getExercise() != null) { errorMessages = getErrorMessagesPreExecution(executableInject.getExercise().getId(), inject); } @@ -231,24 +231,19 @@ private void setInjectStatusAndExecuteInject(ExecutableInject executableInject, ExecutableInject newExecutableInject = executableInject; if (Boolean.TRUE.equals(injectorContract.getNeedsExecutor())) { // Status - InjectStatus statusSaved = - initializeInjectStatus(inject, ExecutionStatus.EXECUTING, null); + initializeInjectStatus(inject, ExecutionStatus.EXECUTING, null); try { newExecutableInject = this.executionExecutorService.launchExecutorContext(executableInject, inject); - } catch (Exception e) { - ExecutionTraceStatus traceStatus = - e.getMessage().startsWith("Asset error") - ? ExecutionTraceStatus.ASSET_INACTIVE - : ExecutionTraceStatus.ERROR; - - statusSaved - .getTraces() - .add(InjectStatusExecution.traceError(traceStatus, e.getMessage())); - statusSaved.setName(ExecutionStatus.ERROR); - injectStatusRepository.save(statusSaved); - throw new RuntimeException(e); + } catch (Exception e) { + InjectStatus injectStatus = + inject + .getStatus() + .orElseThrow(() -> new IllegalArgumentException("Status should exists")); + injectStatus.setName(ExecutionStatus.ERROR); + injectStatusRepository.save(injectStatus); + return; } } if (externalInjector.isExternal()) { @@ -264,7 +259,7 @@ private void setInjectStatusAndExecuteInject(ExecutableInject executableInject, InjectStatusExecution.traceError("Inject does not have a contract"))); } - private InjectStatus initializeInjectStatus( + private void initializeInjectStatus( Inject inject, ExecutionStatus status, @Nullable InjectStatusExecution trace) { InjectStatus injectStatus = inject @@ -282,7 +277,8 @@ private InjectStatus initializeInjectStatus( injectStatus.setName(status); injectStatus.setTrackingSentDate(Instant.now()); injectStatus.setCommandsLines(injectUtils.getCommandsLinesFromInject(inject)); - return injectStatusRepository.save(injectStatus); + injectStatusRepository.save(injectStatus); + inject.setStatus(injectStatus); } /** @@ -353,7 +349,9 @@ private Optional> getErrorMessagesPreExecution(String exerciseId, I injectDependencies.forEach( injectDependency -> { - injectDependency.getInjectDependencyCondition().getConditions().stream() + injectDependency + .getInjectDependencyCondition() + .getConditions() .forEach( condition -> { mapCondition.put(condition.getKey(), false); diff --git a/openbas-framework/src/main/java/io/openbas/execution/ExecutionExecutorException.java b/openbas-framework/src/main/java/io/openbas/execution/ExecutionExecutorException.java new file mode 100644 index 0000000000..9963800493 --- /dev/null +++ b/openbas-framework/src/main/java/io/openbas/execution/ExecutionExecutorException.java @@ -0,0 +1,7 @@ +package io.openbas.execution; + +public class ExecutionExecutorException extends RuntimeException { + public ExecutionExecutorException(String message) { + super(message); + } +} diff --git a/openbas-framework/src/main/java/io/openbas/execution/ExecutionExecutorService.java b/openbas-framework/src/main/java/io/openbas/execution/ExecutionExecutorService.java index a71d6b5d72..d5e3f434f5 100644 --- a/openbas-framework/src/main/java/io/openbas/execution/ExecutionExecutorService.java +++ b/openbas-framework/src/main/java/io/openbas/execution/ExecutionExecutorService.java @@ -1,70 +1,33 @@ package io.openbas.execution; import io.openbas.asset.AssetGroupService; -import io.openbas.database.model.Asset; +import io.openbas.database.model.*; import io.openbas.database.model.Executor; -import io.openbas.database.model.Inject; +import io.openbas.database.repository.InjectStatusRepository; import io.openbas.executors.caldera.config.CalderaExecutorConfig; import io.openbas.executors.caldera.service.CalderaExecutorContextService; import io.openbas.executors.openbas.service.OpenBASExecutorContextService; import io.openbas.executors.tanium.config.TaniumExecutorConfig; import io.openbas.executors.tanium.service.TaniumExecutorContextService; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.stream.Stream; import lombok.RequiredArgsConstructor; import lombok.extern.java.Log; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @RequiredArgsConstructor @Service @Log public class ExecutionExecutorService { - private AssetGroupService assetGroupService; - - private CalderaExecutorConfig calderaExecutorConfig; - - private CalderaExecutorContextService calderaExecutorContextService; - - private TaniumExecutorConfig taniumExecutorConfig; - - private TaniumExecutorContextService taniumExecutorContextService; - - private OpenBASExecutorContextService openBASExecutorContextService; - - @Autowired - public void setOpenBASExecutorContextService( - OpenBASExecutorContextService openBASExecutorContextService) { - this.openBASExecutorContextService = openBASExecutorContextService; - } - - @Autowired - public void setAssetGroupService(AssetGroupService assetGroupService) { - this.assetGroupService = assetGroupService; - } - - @Autowired - public void setCalderaExecutorConfig(CalderaExecutorConfig calderaExecutorConfig) { - this.calderaExecutorConfig = calderaExecutorConfig; - } - - @Autowired - public void setCalderaExecutorContextService( - CalderaExecutorContextService calderaExecutorContextService) { - this.calderaExecutorContextService = calderaExecutorContextService; - } - - @Autowired - public void setTaniumExecutorConfig(TaniumExecutorConfig taniumExecutorConfig) { - this.taniumExecutorConfig = taniumExecutorConfig; - } - - @Autowired - public void setTaniumExecutorContextService( - TaniumExecutorContextService taniumExecutorContextService) { - this.taniumExecutorContextService = taniumExecutorContextService; - } + private final AssetGroupService assetGroupService; + private final CalderaExecutorConfig calderaExecutorConfig; + private final CalderaExecutorContextService calderaExecutorContextService; + private final TaniumExecutorConfig taniumExecutorConfig; + private final TaniumExecutorContextService taniumExecutorContextService; + private final OpenBASExecutorContextService openBASExecutorContextService; + private final InjectStatusRepository injectStatusRepository; public ExecutableInject launchExecutorContext(ExecutableInject executableInject, Inject inject) throws InterruptedException { @@ -79,10 +42,32 @@ public ExecutableInject launchExecutorContext(ExecutableInject executableInject, .assetsFromAssetGroup(assetGroup.getId()) .stream())) .toList(); + InjectStatus injectStatus = + inject.getStatus().orElseThrow(() -> new IllegalArgumentException("Status should exists")); + AtomicBoolean atLeastOneExecution = new AtomicBoolean(false); assets.forEach( asset -> { - launchExecutorContextForAsset(inject, asset); + try { + launchExecutorContextForAsset(inject, asset); + atLeastOneExecution.set(true); + } catch (RuntimeException e) { + ExecutionTraceStatus traceStatus = + e.getMessage().startsWith("Asset error") + ? ExecutionTraceStatus.ASSET_INACTIVE + : ExecutionTraceStatus.ERROR; + + injectStatus + .getTraces() + .add(InjectStatusExecution.traceError(traceStatus, e.getMessage())); + this.injectStatusRepository.save(injectStatus); + } }); + // if launchExecutorContextForAsset fail for every assets we throw to manually set injectStatus + // to error + if (!atLeastOneExecution.get()) { + throw new ExecutionExecutorException("No asset executed"); + } + return executableInject; } @@ -106,12 +91,10 @@ private void launchExecutorContextForAsset(Inject inject, Asset asset) { } this.taniumExecutorContextService.launchExecutorSubprocess(inject, asset); } - case "openbas_agent" -> { - this.openBASExecutorContextService.launchExecutorSubprocess(inject, asset); - } - default -> { - throw new RuntimeException("Fatal error: Unsupported executor " + executor.getType()); - } + case "openbas_agent" -> + this.openBASExecutorContextService.launchExecutorSubprocess(inject, asset); + default -> + throw new RuntimeException("Fatal error: Unsupported executor " + executor.getType()); } } }