Class: Archsight::Analysis::Sandbox
- Inherits:
-
Object
- Object
- Archsight::Analysis::Sandbox
- Defined in:
- lib/archsight/analysis/sandbox.rb
Overview
Sandbox provides a safe execution context for Analysis scripts. Scripts are evaluated via instance_eval with access only to explicitly defined methods.
Instance Attribute Summary collapse
-
#sections ⇒ Object
readonly
Output sections collected during script execution.
Instance Method Summary collapse
-
#_set_analysis(analysis) ⇒ Object
private
Set the current analysis being executed (called by Executor).
-
#annotation(inst, key) ⇒ Object?
Get an annotation value from an instance.
-
#annotations(inst) ⇒ Hash
Get all annotations from an instance (frozen copy).
-
#avg(values) ⇒ Float?
Calculate average.
-
#code(content, lang: "") ⇒ Object
Add a code block.
-
#collect(items, key = nil) {|item| ... } ⇒ Array
Collect values into array.
-
#config(key) ⇒ Object?
Get a configuration value from the analysis.
-
#count(items) ⇒ Integer
Count items.
-
#each_instance(kind) {|instance| ... } ⇒ Object
Iterate over all instances of a kind.
-
#error(message) ⇒ Object
Log an error message.
-
#group_by(items) {|item| ... } ⇒ Hash
Group items by a key.
-
#heading(text, level: 0) ⇒ Object
Add a heading.
-
#incoming(inst, kind = nil) ⇒ Array
Get direct incoming relations (instances that reference this one).
-
#incoming_transitive(inst, kind = nil, max_depth: 10) ⇒ Array
Get transitive incoming relations.
-
#info(message) ⇒ Object
Log an info message.
-
#initialize(database) ⇒ Sandbox
constructor
A new instance of Sandbox.
-
#instance(kind, name) ⇒ Object?
Get a specific instance by kind and name.
-
#instances(kind) ⇒ Array
Get all instances of a kind.
-
#kind(inst) ⇒ String
Get the kind of an instance.
-
#list(items) ⇒ Object
Add a bullet list.
-
#max(values) ⇒ Numeric?
Find maximum value.
-
#min(values) ⇒ Numeric?
Find minimum value.
-
#name(inst) ⇒ String
Get the name of an instance.
-
#outgoing(inst, kind = nil) ⇒ Array
Get direct outgoing relations.
-
#outgoing_transitive(inst, kind = nil, max_depth: 10) ⇒ Array
Get transitive outgoing relations.
-
#query(query_string) ⇒ Array
Execute a query string.
-
#report(data, title: nil) ⇒ Object
Report findings (legacy method - creates appropriate section based on data type).
-
#sum(values) ⇒ Numeric
Sum numeric values.
-
#table(headers:, rows:) ⇒ Object
Add a table.
-
#text(content) ⇒ Object
Add a text paragraph.
-
#warning(message) ⇒ Object
Log a warning message.
Constructor Details
#initialize(database) ⇒ Sandbox
Returns a new instance of Sandbox.
14 15 16 17 18 |
# File 'lib/archsight/analysis/sandbox.rb', line 14 def initialize(database) @database = database @sections = [] @resolver_cache = {} end |
Instance Attribute Details
#sections ⇒ Object (readonly)
Output sections collected during script execution
12 13 14 |
# File 'lib/archsight/analysis/sandbox.rb', line 12 def sections @sections end |
Instance Method Details
#_set_analysis(analysis) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Set the current analysis being executed (called by Executor)
272 273 274 |
# File 'lib/archsight/analysis/sandbox.rb', line 272 def _set_analysis(analysis) @current_analysis = analysis end |
#annotation(inst, key) ⇒ Object?
Get an annotation value from an instance
86 87 88 |
# File 'lib/archsight/analysis/sandbox.rb', line 86 def annotation(inst, key) inst.annotations[key] end |
#annotations(inst) ⇒ Hash
Get all annotations from an instance (frozen copy)
93 94 95 |
# File 'lib/archsight/analysis/sandbox.rb', line 93 def annotations(inst) inst.annotations.dup.freeze end |
#avg(values) ⇒ Float?
Calculate average
139 140 141 142 143 144 |
# File 'lib/archsight/analysis/sandbox.rb', line 139 def avg(values) compact = values.compact return nil if compact.empty? compact.sum.to_f / compact.size end |
#code(content, lang: "") ⇒ Object
Add a code block
220 221 222 |
# File 'lib/archsight/analysis/sandbox.rb', line 220 def code(content, lang: "") @sections << { type: :code, content: content, lang: lang } end |
#collect(items, key = nil) {|item| ... } ⇒ Array
Collect values into array
165 166 167 168 169 170 171 172 173 |
# File 'lib/archsight/analysis/sandbox.rb', line 165 def collect(items, key = nil, &block) if block items.map(&block).compact elsif key items.map { |item| item.respond_to?(key) ? item.send(key) : item.annotations[key.to_s] }.compact else items.compact end end |
#config(key) ⇒ Object?
Get a configuration value from the analysis
265 266 267 |
# File 'lib/archsight/analysis/sandbox.rb', line 265 def config(key) @current_analysis&.annotations&.[]("analysis/config/#{key}") end |
#count(items) ⇒ Integer
Count items
132 133 134 |
# File 'lib/archsight/analysis/sandbox.rb', line 132 def count(items) items.compact.count end |
#each_instance(kind) {|instance| ... } ⇒ Object
Iterate over all instances of a kind
25 26 27 |
# File 'lib/archsight/analysis/sandbox.rb', line 25 def each_instance(kind, &) instances(kind).each(&) end |
#error(message) ⇒ Object
Log an error message
250 251 252 |
# File 'lib/archsight/analysis/sandbox.rb', line 250 def error() @sections << { type: :message, level: :error, message: } end |
#group_by(items) {|item| ... } ⇒ Hash
Group items by a key
179 180 181 |
# File 'lib/archsight/analysis/sandbox.rb', line 179 def group_by(items, &) items.group_by(&) end |
#heading(text, level: 0) ⇒ Object
Add a heading
190 191 192 |
# File 'lib/archsight/analysis/sandbox.rb', line 190 def heading(text, level: 0) @sections << { type: :heading, text: text, level: level.clamp(0, 6) } end |
#incoming(inst, kind = nil) ⇒ Array
Get direct incoming relations (instances that reference this one)
67 68 69 |
# File 'lib/archsight/analysis/sandbox.rb', line 67 def incoming(inst, kind = nil) resolver_for(inst).incoming(kind) end |
#incoming_transitive(inst, kind = nil, max_depth: 10) ⇒ Array
Get transitive incoming relations
76 77 78 |
# File 'lib/archsight/analysis/sandbox.rb', line 76 def incoming_transitive(inst, kind = nil, max_depth: 10) resolver_for(inst).incoming_transitive(kind, max_depth: max_depth) end |
#info(message) ⇒ Object
Log an info message
256 257 258 |
# File 'lib/archsight/analysis/sandbox.rb', line 256 def info() @sections << { type: :message, level: :info, message: } end |
#instance(kind, name) ⇒ Object?
Get a specific instance by kind and name
40 41 42 |
# File 'lib/archsight/analysis/sandbox.rb', line 40 def instance(kind, name) @database.instance_by_kind(kind.to_s, name) end |
#instances(kind) ⇒ Array
Get all instances of a kind
32 33 34 |
# File 'lib/archsight/analysis/sandbox.rb', line 32 def instances(kind) @database.instances_by_kind(kind.to_s).values end |
#kind(inst) ⇒ String
Get the kind of an instance
107 108 109 |
# File 'lib/archsight/analysis/sandbox.rb', line 107 def kind(inst) inst.klass end |
#list(items) ⇒ Object
Add a bullet list
211 212 213 214 215 |
# File 'lib/archsight/analysis/sandbox.rb', line 211 def list(items) return if items.empty? @sections << { type: :list, items: items } end |
#max(values) ⇒ Numeric?
Find maximum value
156 157 158 |
# File 'lib/archsight/analysis/sandbox.rb', line 156 def max(values) values.compact.max end |
#min(values) ⇒ Numeric?
Find minimum value
149 150 151 |
# File 'lib/archsight/analysis/sandbox.rb', line 149 def min(values) values.compact.min end |
#name(inst) ⇒ String
Get the name of an instance
100 101 102 |
# File 'lib/archsight/analysis/sandbox.rb', line 100 def name(inst) inst.name end |
#outgoing(inst, kind = nil) ⇒ Array
Get direct outgoing relations
50 51 52 |
# File 'lib/archsight/analysis/sandbox.rb', line 50 def outgoing(inst, kind = nil) resolver_for(inst).outgoing(kind) end |
#outgoing_transitive(inst, kind = nil, max_depth: 10) ⇒ Array
Get transitive outgoing relations
59 60 61 |
# File 'lib/archsight/analysis/sandbox.rb', line 59 def outgoing_transitive(inst, kind = nil, max_depth: 10) resolver_for(inst).outgoing_transitive(kind, max_depth: max_depth) end |
#query(query_string) ⇒ Array
Execute a query string
116 117 118 |
# File 'lib/archsight/analysis/sandbox.rb', line 116 def query(query_string) @database.query(query_string) end |
#report(data, title: nil) ⇒ Object
Report findings (legacy method - creates appropriate section based on data type)
229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/archsight/analysis/sandbox.rb', line 229 def report(data, title: nil) heading(title, level: 1) if title case data when Array report_array(data) when Hash report_hash(data) else text(data.to_s) end end |
#sum(values) ⇒ Numeric
Sum numeric values
125 126 127 |
# File 'lib/archsight/analysis/sandbox.rb', line 125 def sum(values) values.compact.sum end |
#table(headers:, rows:) ⇒ Object
Add a table
203 204 205 206 207 |
# File 'lib/archsight/analysis/sandbox.rb', line 203 def table(headers:, rows:) return if rows.empty? @sections << { type: :table, headers: headers, rows: rows } end |
#text(content) ⇒ Object
Add a text paragraph
196 197 198 |
# File 'lib/archsight/analysis/sandbox.rb', line 196 def text(content) @sections << { type: :text, content: content } end |
#warning(message) ⇒ Object
Log a warning message
244 245 246 |
# File 'lib/archsight/analysis/sandbox.rb', line 244 def warning() @sections << { type: :message, level: :warning, message: } end |