class ASAConsole::Config

A parser for ASA running/startup config.

Each instance represents a single config entry which may include nested lines of config that can be queried with {#select} or {#select_all}.

@example Print ACEs with line numbers for each access list

# Start by fetching a top-level Config object
config = asa.running_config('access-list')
config.names_of('access-list').each do |acl|
  puts "Access list #{acl}:"
  counter = 0
  config.select('access-list', acl) do |ace|
    counter += 1
    puts " Line #{counter}: #{ace.line}"
  end
  puts
end

@example List all interfaces that participate in EIGRP

# Start by fetching a top-level Config object
config = asa.running_config('all router eigrp')
router = config.select('router eigrp')
router.select('passive-interface') do |passive_interface|
  ifname = passive_interface.config_data
  next if ifname == 'default'
  if passive_interface.negated?
    puts "Interface '#{ifname}' is sending routing updates"
  else
    puts "Interface '#{ifname}' is passive"
  end
end if router

@attr_reader keystr [String, nil]

Key used to select the line of config represented by this object, or `nil`
if the object contains nested top-level config.

@attr_reader config_name [String, nil]

An identifier, such as an access list name, used to distinguish between
config entries of the same type.

@attr_reader config_data [String, nil]

Remainder of the config line following the {#keystr} and {#config_name}.

Attributes

config_data[R]
config_name[R]
keystr[R]

Public Class Methods

new(opts = {}) click to toggle source

@see running_config @option opts [String] :keystr class attribute @option opts [String] :config_name class attribute @option opts [String] :config_data class attribute @option opts [Boolean] :negated

`true` if the config line began with "no", or `false` otherwise

@option opts [String] :nested_config

a multiline string of config (indentation stripped)
# File lib/asa_console/config.rb, line 60
def initialize(opts = {})
  @keystr         = opts[:keystr]
  @config_name    = opts[:config_name]
  @config_data    = opts[:config_data]
  @negated        = opts.fetch(:negated, false)
  @nested_config  = opts.fetch(:nested_config, '')
end

Public Instance Methods

empty?() click to toggle source

@return [Boolean]

`true` if there is no nested config, or `false` otherwise
# File lib/asa_console/config.rb, line 87
def empty?
  @nested_config.empty?
end
line() click to toggle source

@return [String, nil]

the selected line, or `nil` if this is a top-level object
# File lib/asa_console/config.rb, line 70
def line
  parts = []
  parts << 'no' if @negated
  parts << @keystr if @keystr
  parts << @config_name if @config_name
  parts << @config_data if @config_data
  parts.empty? ? nil : parts.join(' ')
end
names_of(keystr) click to toggle source

@see select @param keystr [String] @return [Array<String>]

a unique list of config element names matched by `keystr`
# File lib/asa_console/config.rb, line 159
def names_of(keystr)
  names = []
  regex = /^(?:no )?#{Regexp.escape(keystr)} (?<name>\S+)/
  @nested_config.each_line do |line|
    m = regex.match(line)
    next unless m
    names << m[:name] unless names.include? m[:name]
  end
  names
end
negated?() click to toggle source

@return [Boolean]

`true` if the selected line began with "no", or `false` otherwise
# File lib/asa_console/config.rb, line 81
def negated?
  @negated ? true : false
end
select(keystr = nil, config_name = nil) { |config| ... } click to toggle source

Select the first matching line of the nested config or `yield` all matching lines if a block is given.

@param keystr [String, nil] @param config_name [String, nil] @yieldparam config [Config] @yieldreturn [nil] if a block is given @return [Config] if no block given

# File lib/asa_console/config.rb, line 117
def select(keystr = nil, config_name = nil)
  prefix = [keystr, config_name].join(' ').strip
  regex = /^(?<no>no )?#{Regexp.escape(prefix)} ?(?<data>.+)?/

  io = StringIO.open(@nested_config)
  lines = io.readlines
  io.close

  loop do
    break if lines.empty?

    m = regex.match(lines.shift)
    next unless m

    nested_config = ''
    loop do
      break unless lines[0] && lines[0].start_with?(' ')
      nested_config << lines.shift.sub(/^ /, '')
    end

    config = Config.new(
      keystr:         keystr,
      config_name:    config_name,
      config_data:    m[:data],
      negated:        !m[:no].nil?,
      nested_config:  nested_config
    )

    if block_given?
      yield config
    else
      return config
    end
  end

  nil
end
select_all() { |config| ... } click to toggle source

Select all lines of nested config. Equivalent to {#select} with no arguments.

@yieldparam config [Config] @yieldreturn [nil] if a block is given @return [Array<Config>] if no block given

# File lib/asa_console/config.rb, line 97
def select_all
  result = []
  select do |config|
    if block_given?
      yield config
    else
      result << config
    end
  end
  result unless block_given?
end