1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
require 'strscan'
require_relative 'outputs'
module Oxidized
class Model
include Oxidized::Config::Vars
class << self
def inherited klass
klass.instance_variable_set '@cmd', Hash.new { |h, k| h[k] = [] }
klass.instance_variable_set '@cfg', Hash.new { |h, k| h[k] = [] }
klass.instance_variable_set '@procs', Hash.new { |h, k| h[k] = [] }
klass.instance_variable_set '@expect', []
klass.instance_variable_set '@comment', nil
klass.instance_variable_set '@prompt', nil
end
def comment _comment = '# '
return @comment if @comment
@comment = block_given? ? yield : _comment
end
def prompt _prompt = nil
@prompt or @prompt = _prompt
end
def cfg *methods, **args, &block
[methods].flatten.each do |method|
process_args_block(@cfg[method.to_s], args, block)
end
end
def cfgs
@cfg
end
def cmd _cmd = nil, **args, &block
if _cmd.class == Symbol
process_args_block(@cmd[_cmd], args, block)
else
process_args_block(@cmd[:cmd], args, [_cmd, block])
end
Oxidized.logger.debug "lib/oxidized/model/model.rb Added #{_cmd} to the commands list"
end
def cmds
@cmd
end
def expect re, **args, &block
process_args_block(@expect, args, [re, block])
end
def expects
@expect
end
# calls the block at the end of the model, prepending the output of the
# block to the output string
#
# @author Saku Ytti <saku@ytti.fi>
# @since 0.0.39
# @yield expects block which should return [String]
# @return [void]
def pre **args, &block
process_args_block(@procs[:pre], args, block)
end
# calls the block at the end of the model, adding the output of the block
# to the output string
#
# @author Saku Ytti <saku@ytti.fi>
# @since 0.0.39
# @yield expects block which should return [String]
# @return [void]
def post **args, &block
process_args_block(@procs[:post], args, block)
end
# @author Saku Ytti <saku@ytti.fi>
# @since 0.0.39
# @return [Hash] hash proc procs :pre+:post to be prepended/postfixed to output
def procs
@procs
end
private
def process_args_block(target, args, block)
if args[:clear]
target.replace([block])
else
method = args[:prepend] ? :unshift : :push
target.send(method, block)
end
end
end
attr_accessor :input, :node
def cmd string, &block
Oxidized.logger.debug "lib/oxidized/model/model.rb Executing #{string}"
out = @input.cmd(string)
return false unless out
out = out.b unless Oxidized.config.input.utf8_encoded?
self.class.cmds[:all].each do |all_block|
out = instance_exec Oxidized::String.new(out), string, &all_block
end
if vars :remove_secret
self.class.cmds[:secret].each do |all_block|
out = instance_exec Oxidized::String.new(out), string, &all_block
end
end
out = instance_exec Oxidized::String.new(out), &block if block
process_cmd_output out, string
end
def output
@input.output
end
def send data
@input.send data
end
def expect re, &block
self.class.expect re, &block
end
def cfg
self.class.cfgs
end
def prompt
self.class.prompt
end
def expects data
self.class.expects.each do |re, cb|
if data.match re
if cb.arity == 2
data = instance_exec [data, re], &cb
else
data = instance_exec data, &cb
end
end
end
data
end
def get
Oxidized.logger.debug 'lib/oxidized/model/model.rb Collecting commands\' outputs'
outputs = Outputs.new
procs = self.class.procs
self.class.cmds[:cmd].each do |command, block|
out = cmd command, &block
return false unless out
outputs << out
end
procs[:pre].each do |pre_proc|
outputs.unshift process_cmd_output(instance_eval(&pre_proc), '')
end
procs[:post].each do |post_proc|
outputs << process_cmd_output(instance_eval(&post_proc), '')
end
outputs
end
def comment _comment
data = ''
_comment.each_line do |line|
data << self.class.comment << line
end
data
end
def screenscrape
@input.class.to_s.match(/Telnet/) || vars(:ssh_no_exec)
end
private
def process_cmd_output output, name
output = Oxidized::String.new output if ::String === output
output = Oxidized::String.new '' unless Oxidized::String === output
output.set_cmd(name)
output
end
end
end
|