mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-08-17 21:25:49 +02:00
Major features: - Add run registry for tracking active runs with PID management - Add API-based run cancellation with process termination - Add event trigger input vars syntax for multi-variable extraction - Add filter_functions with utility function support in triggers - Add event envelope injection for full event context in workflows - Add write coordinator for batched database operations API improvements: - Add logout endpoint and diffs endpoints for assets/vulnerabilities - Add step-results listing endpoint - Update schedule model with target, workspace, params fields - Change run_id to run_uuid across API responses Performance: - Add compiled JS program caching for 60-80% faster loop conditions - Add parallel shard rendering for 20-40% faster workflow startup - Add memory-mapped I/O for large file line counting - Add efficient output buffer combining in runners - Add mtime-based cache invalidation for workflow loader Other changes: - Rename trigger field from trigger to triggers in workflow YAML - Disable pongo2 HTML autoescape for shell command templates - Update JWT expiration default to 1440 minutes (1 day) - Change CORS default to reflect-origin for credentials support - Add source_type field to events (run, eval, api) - Skip copying core Unix tools to external-binaries
235 lines
5.3 KiB
Go
235 lines
5.3 KiB
Go
package lib
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/j3ssie/osmedeus/v5/internal/core"
|
|
)
|
|
|
|
// RunResult holds the result of a workflow execution
|
|
type RunResult struct {
|
|
// WorkflowName is the name of the executed workflow
|
|
WorkflowName string
|
|
|
|
// RunUUID is the unique identifier for this execution
|
|
RunUUID string
|
|
|
|
// Target is the scan target
|
|
Target string
|
|
|
|
// Status indicates the final execution status
|
|
// Values: "completed", "failed", "cancelled", "skipped"
|
|
Status string
|
|
|
|
// StartTime is when execution started
|
|
StartTime time.Time
|
|
|
|
// EndTime is when execution finished
|
|
EndTime time.Time
|
|
|
|
// Duration is the total execution time
|
|
Duration time.Duration
|
|
|
|
// Steps contains results for each executed step
|
|
Steps []*StepResult
|
|
|
|
// Exports are variables exported by steps during execution
|
|
Exports map[string]interface{}
|
|
|
|
// Artifacts are file paths of generated outputs
|
|
Artifacts []string
|
|
|
|
// Error contains the error if execution failed
|
|
Error error
|
|
|
|
// OutputPath is the workspace directory path
|
|
OutputPath string
|
|
|
|
// Message contains optional status message (e.g., for skipped status)
|
|
Message string
|
|
}
|
|
|
|
// IsSuccess returns true if the workflow completed successfully
|
|
func (r *RunResult) IsSuccess() bool {
|
|
return r.Status == "completed"
|
|
}
|
|
|
|
// IsFailed returns true if the workflow failed
|
|
func (r *RunResult) IsFailed() bool {
|
|
return r.Status == "failed"
|
|
}
|
|
|
|
// IsCancelled returns true if the workflow was cancelled
|
|
func (r *RunResult) IsCancelled() bool {
|
|
return r.Status == "cancelled"
|
|
}
|
|
|
|
// IsSkipped returns true if the workflow was skipped
|
|
func (r *RunResult) IsSkipped() bool {
|
|
return r.Status == "skipped"
|
|
}
|
|
|
|
// GetExport retrieves an exported variable by name
|
|
func (r *RunResult) GetExport(name string) (interface{}, bool) {
|
|
if r.Exports == nil {
|
|
return nil, false
|
|
}
|
|
v, ok := r.Exports[name]
|
|
return v, ok
|
|
}
|
|
|
|
// GetExportString retrieves an exported variable as a string
|
|
func (r *RunResult) GetExportString(name string) (string, bool) {
|
|
v, ok := r.GetExport(name)
|
|
if !ok {
|
|
return "", false
|
|
}
|
|
if s, ok := v.(string); ok {
|
|
return s, true
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
// GetExportBool retrieves an exported variable as a bool
|
|
func (r *RunResult) GetExportBool(name string) (bool, bool) {
|
|
v, ok := r.GetExport(name)
|
|
if !ok {
|
|
return false, false
|
|
}
|
|
if b, ok := v.(bool); ok {
|
|
return b, true
|
|
}
|
|
return false, false
|
|
}
|
|
|
|
// SuccessfulSteps returns the count of successful steps
|
|
func (r *RunResult) SuccessfulSteps() int {
|
|
count := 0
|
|
for _, step := range r.Steps {
|
|
if step.Status == "success" {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
// FailedSteps returns the count of failed steps
|
|
func (r *RunResult) FailedSteps() int {
|
|
count := 0
|
|
for _, step := range r.Steps {
|
|
if step.Status == "failed" {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
// SkippedSteps returns the count of skipped steps
|
|
func (r *RunResult) SkippedSteps() int {
|
|
count := 0
|
|
for _, step := range r.Steps {
|
|
if step.Status == "skipped" {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
// StepResult holds the result of a single step execution
|
|
type StepResult struct {
|
|
// Name is the step name from the workflow
|
|
Name string
|
|
|
|
// Type is the step type (bash, function, etc.)
|
|
Type string
|
|
|
|
// Status indicates the step execution status
|
|
// Values: "success", "failed", "skipped"
|
|
Status string
|
|
|
|
// Output is the captured stdout/stderr from the step
|
|
Output string
|
|
|
|
// Duration is how long the step took to execute
|
|
Duration time.Duration
|
|
|
|
// Error contains the error if the step failed
|
|
Error error
|
|
|
|
// Exports are variables exported by this step
|
|
Exports map[string]interface{}
|
|
}
|
|
|
|
// IsSuccess returns true if the step completed successfully
|
|
func (s *StepResult) IsSuccess() bool {
|
|
return s.Status == "success"
|
|
}
|
|
|
|
// IsFailed returns true if the step failed
|
|
func (s *StepResult) IsFailed() bool {
|
|
return s.Status == "failed"
|
|
}
|
|
|
|
// IsSkipped returns true if the step was skipped
|
|
func (s *StepResult) IsSkipped() bool {
|
|
return s.Status == "skipped"
|
|
}
|
|
|
|
// GetExport retrieves an exported variable by name
|
|
func (s *StepResult) GetExport(name string) (interface{}, bool) {
|
|
if s.Exports == nil {
|
|
return nil, false
|
|
}
|
|
v, ok := s.Exports[name]
|
|
return v, ok
|
|
}
|
|
|
|
// fromWorkflowResult converts an internal WorkflowResult to a RunResult
|
|
func fromWorkflowResult(result *core.WorkflowResult, outputPath string) *RunResult {
|
|
if result == nil {
|
|
return nil
|
|
}
|
|
|
|
runResult := &RunResult{
|
|
WorkflowName: result.WorkflowName,
|
|
RunUUID: result.RunUUID,
|
|
Target: result.Target,
|
|
Status: string(result.Status),
|
|
StartTime: result.StartTime,
|
|
EndTime: result.EndTime,
|
|
Duration: result.EndTime.Sub(result.StartTime),
|
|
Exports: result.Exports,
|
|
Artifacts: result.Artifacts,
|
|
Error: result.Error,
|
|
OutputPath: outputPath,
|
|
Message: result.Message,
|
|
}
|
|
|
|
// Convert step results
|
|
if len(result.Steps) > 0 {
|
|
runResult.Steps = make([]*StepResult, len(result.Steps))
|
|
for i, step := range result.Steps {
|
|
runResult.Steps[i] = fromStepResult(step)
|
|
}
|
|
}
|
|
|
|
return runResult
|
|
}
|
|
|
|
// fromStepResult converts an internal StepResult to a lib StepResult
|
|
func fromStepResult(step *core.StepResult) *StepResult {
|
|
if step == nil {
|
|
return nil
|
|
}
|
|
|
|
return &StepResult{
|
|
Name: step.StepName,
|
|
Type: "", // Type is not stored in core.StepResult
|
|
Status: string(step.Status),
|
|
Output: step.Output,
|
|
Duration: step.Duration,
|
|
Error: step.Error,
|
|
Exports: step.Exports,
|
|
}
|
|
}
|