module ASAConsole::Util

Miscellaneous utility functions.

Constants

CISCO_TIME_REGEX
VERSION_EXPR_REGEX

Public Class Methods

apply_control_chars(raw) click to toggle source

Convert a string with terminal control characters to plain text as it would appear in a terminal window.

An ASA will use backspaces and carriage returns to hide text that has already been output to the console. For example, the ASA outputs extra characters to hide the `<— More —>` prompt when the user presses a key.

@param raw [String] @return [String]

# File lib/asa_console/util.rb, line 41
def self.apply_control_chars(raw)
  output = ''
  raw.split("\n").each do |line|
    io = StringIO.new
    line.scan(/([^\r\x08]+|[\r\x08])/) do |m|
      case m[0]
      when "\r"
        io.rewind
      when "\x08"
        io.pos = io.pos - 1
      else
        io.write(m[0])
      end
    end
    output << io.string << "\n"
  end
  output.chop! unless raw.end_with?("\n")
  output.delete("\x00")
end
parse_cisco_time(str) { |time, tz| ... } click to toggle source

Parse the time format commonly used in various command output. This can be useful for things like extracting the configuration modification time from “show version” output or for parsing the last failover time.

@note

It is not possible to reliably evaluate the timezone string without
running additional commands, so this function (optimistically) returns
a UTC timestamp. See {file:script/test_clock.rb} for one method of
adjusting a remote timestamp to local time using "show clock" commands.

@param str [String] @yieldparam time [Time] @yieldparam tz [String]

timezone string set by "clock timezone" or "clock summer-time"

@return [Time]

time represented in UTC
# File lib/asa_console/util.rb, line 77
def self.parse_cisco_time(str)
  m = CISCO_TIME_REGEX.match(str)
  return nil unless m
  tz      = m[:tz]
  year    = m[:year].to_i
  month   = m[:month]
  day     = m[:day].to_i
  hour    = m[:hour].to_i
  min     = m[:min].to_i
  sec     = m[:sec].to_i
  subsec  = "0.#{m[:subsec]}".to_f
  time = Time.utc(year, month, day, hour, min, sec) + subsec
  time = yield(time, tz) if block_given?
  time
end
version_match?(version, exprs) click to toggle source

Match an ASA software version string in `x.x(x)` format against one or more conditional expressions.

@see version? The ASAConsole wrapper for this function @param version [String] @param exprs [Array<String>] @return [Boolean] `true` if all expressions match, or `false` otherwise

# File lib/asa_console/util.rb, line 100
def self.version_match?(version, exprs)
  ver = []
  version_match_parse(version) { |_opr, pattern| ver = pattern }
  exprs.each do |e|
    version_match_parse(e) do |opr, pattern|
      return false unless version_match_compare(opr, ver, pattern)
    end
  end
  true
end
version_match_compare(opr, ver, pattern) click to toggle source

@api private

# File lib/asa_console/util.rb, line 128
def self.version_match_compare(opr, ver, pattern)
  a = ver[0..(pattern.length - 1)]
  b = pattern.clone
  eq = true
  gt = lt = false
  a.each do |x|
    y = b.shift
    next if x == y
    eq = false
    gt = x > y
    lt = x < y
    break
  end
  case opr
  when '>'  then gt
  when '<'  then lt
  when '==' then eq
  when '>=' then gt || eq
  when '<=' then lt || eq
  when '!=' then !eq
  end
end
version_match_parse(expr) { |opr, pattern| ... } click to toggle source

@api private

# File lib/asa_console/util.rb, line 112
def self.version_match_parse(expr)
  expr = expr.to_s # Forgive users who provide a number instead of a string
  m = VERSION_EXPR_REGEX.match(expr)
  fail Error::InvalidExpressionError, "Expression '#{expr}' is not valid" unless m
  opr = m[:opr]
  opr = '==' if opr == '=' || opr.nil? # Equality is the default operator
  opr = '!=' if opr == '!'
  pattern = [ m[:major].to_i ]
  if m[:minor] && m[:minor] != 'x'
    pattern << m[:minor].to_i
    pattern << m[:maint].to_i if m[:maint] && m[:maint] != 'x'
  end
  yield(opr, pattern)
end