Class: Archsight::Analysis::Executor

Inherits:
Object
  • Object
show all
Defined in:
lib/archsight/analysis/executor.rb

Overview

Executor runs Analysis scripts in a sandboxed environment with timeout enforcement

Constant Summary collapse

DEFAULT_TIMEOUT =

Default timeout in seconds

30
DURATION_PATTERNS =

Duration parsing patterns

{
  /^(\d+)s$/ => 1,
  /^(\d+)m$/ => 60,
  /^(\d+)h$/ => 3600
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(database) ⇒ Executor

Returns a new instance of Executor.

Parameters:



24
25
26
# File 'lib/archsight/analysis/executor.rb', line 24

def initialize(database)
  @database = database
end

Instance Attribute Details

#databaseObject (readonly)

Returns the value of attribute database.



21
22
23
# File 'lib/archsight/analysis/executor.rb', line 21

def database
  @database
end

Instance Method Details

#execute(analysis) ⇒ Archsight::Analysis::Result

Execute an Analysis resource

Parameters:

Returns:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/archsight/analysis/executor.rb', line 31

def execute(analysis)
  script = analysis.annotations["analysis/script"]
  timeout_seconds = parse_timeout(analysis.annotations["analysis/timeout"])

  return Result.new(analysis, success: false, error: "No script defined") if script.nil? || script.empty?

  sandbox = Sandbox.new(@database)
  sandbox._set_analysis(analysis)

  start_time = Time.now
  begin
    Timeout.timeout(timeout_seconds) do
      # Execute script in sandbox context
      # Using instance_eval ensures script only has access to sandbox methods
      sandbox.instance_eval(script, "analysis:#{analysis.name}", 1)
    end

    duration = Time.now - start_time
    Result.new(
      analysis,
      success: true,
      sections: sandbox.sections,
      duration: duration
    )
  rescue Timeout::Error
    Result.new(
      analysis,
      success: false,
      error: "Execution timed out after #{timeout_seconds}s",
      sections: sandbox.sections
    )
  rescue StandardError, SyntaxError => e
    Result.new(
      analysis,
      success: false,
      error: "#{e.class}: #{e.message}",
      error_backtrace: e.backtrace&.first(5),
      sections: sandbox.sections
    )
  end
end

#execute_all(filter: nil) ⇒ Array<Archsight::Analysis::Result>

Execute all enabled Analysis resources

Parameters:

  • filter (Regexp, nil) (defaults to: nil)

    Optional filter for analysis names

Returns:



76
77
78
79
80
81
82
83
# File 'lib/archsight/analysis/executor.rb', line 76

def execute_all(filter: nil)
  analyses = @database.instances_by_kind("Analysis").values

  # Filter by name pattern if provided
  analyses = analyses.select { |a| filter.match?(a.name) } if filter

  analyses.map { |analysis| execute(analysis) }
end