Class: Oxidized::Model

Inherits:
Object
  • Object
show all
Includes:
Config::Vars, SemanticLogger::Loggable
Defined in:
lib/oxidized/model/model.rb,
lib/oxidized/model/outputs.rb

Direct Known Subclasses

ACMEPACKET, ACOS, ACSW, ADVA, AEN, ALTEONOS, AOS, AOS7, AOSW, ARBOS, ASA, AWPlus, AddPack, Adtran, Aireos, Airfiber, Airos, Alvarion, Aoscx, Apc_aos, AricentISS, ArubaInstant, AsterNOS, AsyncOS, AudioCodes, AudioCodesMP, AxOS, BDCOM, BR6910, Boss, C4CMTS, CNOS, Cambium, CambiumePMP, Casa, Catos, CiscoCE, CiscoNGA, CiscoSMA, CiscoSMB, CiscoVPN3k, ComnetMS, Comtrol, Comware, Coriant8600, CoriantGroove, CoriantTmos, Cumulus, DCNOS, DNOS, DataCom, DellX, Dlink, DlinkNextGen, ECIapollo, EFOS, EOS, EatonNetwork, EdgeCOS, EdgeSwitch, Edgeos, Eltex, Enterasys, Enterasys800, Enterprise_SONiC, F5OS, FSOS, FTOS, FabricOS, FastIron, FiberDriver, FireLinuxOS, Firebrick, FirewareOS, FortiOS, FortiWLC, FujitsuPY, GaiaOS, Garderos, GcomBNPS, GrandStream, H3C, HPEBladeSystem, HPMSM, Hatteras, Hios, Hirschmann, HpeMsa, IBOS, IOS, IOSXR, IPOS, ISAM, Icotera, Ingate, IronWare, JunOS, KornfeldOS, LANCOM, LenovoNOS, LinksysSRW, LinuxGeneric, ML66, MLNXOS, MasterOS, Mimosab11, Mtrlrfs, NDMS, NOS, NSXConfig, NSXDfw, NSXFirewall, NXOS, NecIX, NetScaler, Netgear, Netonix, Nodegrid, OS10, OS6, OcNOS, OneFinity, OneOS, OpenGear, OpenWrt, Openbsd, OpnSense, PanOS, PanOS_API, Perle, PfSense, Planet, PowerConnect, Procurve, PurityOS, QTECH, QuantaOS, RAISECOM, RGOS, Riverbed, RouterOS, SAOS, SAOS10, SGOS, SLXOS, SROS, SROSMD, ScreenOS, Siklu, SikluMHTG, SixWind, SmartAX, SmartCS, SonicOS, SpeedTouch, StoneOS, SwOS, TDRE, TELCO, TMOS, TNSR, TPLink, Trango, TrueNAS, UCS, UPLINKOLT, Unifiap, VOLTAIRE, VRP, Viptela, Voss, Vyatta, Vyos, WEOS, XOS, Yamaha, ZTEOLT, ZhoneOLT, Zy1308, ZyNOS, ZyNOSADSL, ZyNOSCLI, ZyNOSGS, ZyNOSMGS

Defined Under Namespace

Classes: Outputs

Constant Summary collapse

METADATA_DEFAULT =

rubocop:disable Style/FormatStringToken

"%{comment}Fetched by Oxidized with model %{model} " \
"from host %{name} [%{ip}]\n".freeze

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Config::Vars

#vars

Class Attribute Details

.procsHash (readonly)

Returns hash proc procs :pre+:post to be prepended/postfixed to output.

Returns:

  • (Hash)

    hash proc procs :pre+:post to be prepended/postfixed to output

Author:

Since:

  • 0.0.39



139
140
141
# File 'lib/oxidized/model/model.rb', line 139

def procs
  @procs
end

Instance Attribute Details

#inputObject

Returns the value of attribute input.



161
162
163
# File 'lib/oxidized/model/model.rb', line 161

def input
  @input
end

#nodeObject

Returns the value of attribute node.



161
162
163
# File 'lib/oxidized/model/model.rb', line 161

def node
  @node
end

Class Method Details

.cfg(*methods, **args, &block) ⇒ Object



51
52
53
54
55
# File 'lib/oxidized/model/model.rb', line 51

def cfg(*methods, **args, &block)
  [methods].flatten.each do |method|
    process_args_block(@cfg[method.to_s], args, block)
  end
end

.cfgsObject



57
58
59
# File 'lib/oxidized/model/model.rb', line 57

def cfgs
  @cfg
end

.clean(what) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/oxidized/model/model.rb', line 94

def clean(what)
  case what
  when :escape_codes
    ansi_escape_regex = /
      \r?        # Optional carriage return at start
      \e         # ESC character - starts escape sequence
      (?:        # Non-capturing group for different sequence types:
        # Type 1: CSI (Control Sequence Introducer)
        \[       # Literal '[' - starts CSI sequence
        [0-?]*   # Parameter bytes: digits (0-9), semicolon, colon, etc.
        [ -\/]*  # Intermediate bytes: space through slash characters
        [@-~]    # Final byte: determines the actual command
      |          # OR
        # Type 2: Simple escape
        [=>]     # Single character commands after ESC
      )
      \r?        # Optional carriage return at end
    /x
    expect ansi_escape_regex do |data, re|
      data.gsub re, ''
    end
  end
end

.cmd(cmd_arg = nil, **args, &block) ⇒ Object



61
62
63
64
65
66
67
68
69
70
# File 'lib/oxidized/model/model.rb', line 61

def cmd(cmd_arg = nil, **args, &block)
  if cmd_arg.instance_of?(Symbol)
    process_args_block(@cmd[cmd_arg], args, block)
  else
    # Normal command
    process_args_block(@cmd[:cmd], args,
                       { cmd: cmd_arg, args: args, block: block })
  end
  logger.debug "Added #{cmd_arg} to the commands list"
end

.cmdsObject



82
83
84
# File 'lib/oxidized/model/model.rb', line 82

def cmds
  @cmd
end

.comment(str = "# ") ⇒ Object



37
38
39
40
41
42
43
44
45
# File 'lib/oxidized/model/model.rb', line 37

def comment(str = "# ")
  @comment = if block_given?
               yield
             elsif not @comment
               str
             else
               @comment
             end
end

.expect(regex, **args, &block) ⇒ Object



86
87
88
# File 'lib/oxidized/model/model.rb', line 86

def expect(regex, **args, &block)
  process_args_block(@expect, args, [regex, block])
end

.expectsObject



90
91
92
# File 'lib/oxidized/model/model.rb', line 90

def expects
  @expect
end

.inherited(klass) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/oxidized/model/model.rb', line 18

def inherited(klass)
  super
  if klass.superclass == Oxidized::Model
    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
    klass.instance_variable_set '@metadata', {}
  else # we're subclassing some existing model, take its variables
    instance_variables.each do |var|
      iv = instance_variable_get(var)
      klass.instance_variable_set var, iv.dup
      @cmd[:cmd] = iv[:cmd].dup if var.to_s == "@cmd"
    end
  end
end

.metadata(position, value = nil, &block) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'lib/oxidized/model/model.rb', line 72

def (position, value = nil, &block)
  return unless i[top bottom].include? position

  if block_given?
    [position] = block
  else
    [position] = value
  end
end

.post(**args) { ... } ⇒ void

This method returns an undefined value.

calls the block at the end of the model, adding the output of the block to the output string

Yields:

  • expects block which should return [String]



132
133
134
# File 'lib/oxidized/model/model.rb', line 132

def post(**args, &block)
  process_args_block(@procs[:post], args, block)
end

.pre(**args) { ... } ⇒ void

This method returns an undefined value.

calls the block at the end of the model, prepending the output of the block to the output string

Yields:

  • expects block which should return [String]



123
124
125
# File 'lib/oxidized/model/model.rb', line 123

def pre(**args, &block)
  process_args_block(@procs[:pre], args, block)
end

.prompt(regex = nil) ⇒ Object



47
48
49
# File 'lib/oxidized/model/model.rb', line 47

def prompt(regex = nil)
  @prompt = regex || @prompt
end

Instance Method Details

#cfgObject



231
232
233
# File 'lib/oxidized/model/model.rb', line 231

def cfg
  self.class.cfgs
end

#cmd(string, &block) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/oxidized/model/model.rb', line 163

def cmd(string, &block)
  logger.debug "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 out, string, &all_block
  end
  if vars :remove_secret
    self.class.cmds[:secret].each do |all_block|
      out = instance_exec out, string, &all_block
    end
  end
  out = instance_exec out, &block if block
  process_cmd_output out, string
end

#comment(str) ⇒ Object



279
280
281
282
283
284
285
# File 'lib/oxidized/model/model.rb', line 279

def comment(str)
  data = String.new('')
  str.each_line do |line|
    data << self.class.comment << line
  end
  data
end

#expectObject



227
228
229
# File 'lib/oxidized/model/model.rb', line 227

def expect(...)
  self.class.expect(...)
end

#expects(data) ⇒ Object



239
240
241
242
243
244
245
246
# File 'lib/oxidized/model/model.rb', line 239

def expects(data)
  self.class.expects.each do |re, cb|
    if data.match re
      data = cb.arity == 2 ? instance_exec([data, re], &cb) : instance_exec(data, &cb)
    end
  end
  data
end

#getObject



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/oxidized/model/model.rb', line 248

def get
  logger.debug 'Collecting commands\' outputs'
  outputs = Outputs.new
  self.class.cmds[:cmd].each do |data|
    command = data[:cmd]
    args = data[:args]
    block = data[:block]

    next if args.include?(:if) && !instance_exec(&args[:if])

    out = cmd command, &block
    return false unless out

    outputs << out
  end
  procs = self.class.procs
  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
  if vars("metadata") == true
     = (:top)
     = (:bottom)
    outputs.unshift  if 
    outputs <<  if 
  end
  outputs
end

#interpolate_string(template) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/oxidized/model/model.rb', line 199

def interpolate_string(template)
  return nil unless template

  time = Time.now
  template_variables = {
    model:   self.class.name,
    name:    node.name,
    ip:      node.ip,
    group:   node.group,
    comment: self.class.comment,
    year:    time.year,
    month:   "%02d" % time.month,
    day:     "%02d" % time.day,
    hour:    "%02d" % time.hour,
    minute:  "%02d" % time.min,
    second:  "%02d" % time.sec
  }
  template % template_variables
end

#metadata(position) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/oxidized/model/model.rb', line 181

def (position)
  return unless i[top bottom].include? position

   = self.class.instance_variable_get(:@metadata)
  var_position = { top: "metadata_top", bottom: "metadata_bottom" }
  if [:top] || [:bottom]
    # the model defines metadata at :top ot :bottom, use the model
    value = [position]
    value.is_a?(Proc) ? instance_eval(&value) : interpolate_string(value)
  elsif vars("metadata_top") || vars("metadata_bottom")
    # vars defines metadata_top or metadata bottom, use the vars
    interpolate_string(vars(var_position[position]))
  elsif position == :top
    # default: use METADATA_DEFAULT for top
    interpolate_string()
  end
end

#outputObject



219
220
221
# File 'lib/oxidized/model/model.rb', line 219

def output
  @input.output
end

#promptObject



235
236
237
# File 'lib/oxidized/model/model.rb', line 235

def prompt
  self.class.prompt
end

#screenscrapeObject



305
306
307
# File 'lib/oxidized/model/model.rb', line 305

def screenscrape
  @input.class.to_s.match(/Telnet/) || vars(:ssh_no_exec)
end

#send(data) ⇒ Object



223
224
225
# File 'lib/oxidized/model/model.rb', line 223

def send(data)
  @input.send data
end

#xmlcomment(str) ⇒ Object



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/oxidized/model/model.rb', line 287

def xmlcomment(str)
  # XML Comments start with <!-- and end with -->
  #
  # Because it's illegal for the first or last characters of a comment
  # to be a -, i.e. <!--- or ---> are illegal, and also to improve
  # readability, we add extra spaces after and before the beginning
  # and end of comment markers.
  #
  # Also, XML Comments must not contain --. So we put a space between
  # any double hyphens, by replacing any - that is followed by another -
  # with '- '
  data = String.new('')
  str.each_line do |_line|
    data << '<!-- ' << str.gsub(/-(?=-)/, '- ').chomp << " -->\n"
  end
  data
end