Can't fetch config from Telnet enabled device

Very new to Librenms/Oxidized as of last week. It has been almost a complete success with the exception of one device which uses telnet. A cisco. No amount of googleing seems to give me the answer I need. As far as I can tell it is just skipping attempting to log into the device. It used to timeout until I altered the prompt statement in the ios.rb file to look like /^([\w.@()-]+[#:>]\s?)$/ because it couldn’t detect “login:”. When I cat the debug file I see the below.
User Access Verification

login: terminal length 0
Password:

% Authentication failed.

login: terminal length 0
Password:

% Authentication failed.

login: show version
Password:

% Authentication failed.

Which tells me is is skipping the username and password part. In an attempt to see if it was even trying the telnet section I added the the below post login commands to the ios.rb file. And with those in there it is working like a charm. But, I know this can’t be the correct way.
cfg :telnet do
username /^[uU]sername:/i
password /^[pP]assword:/i
post_login ‘username’
post_login ‘password’
end

This also brings up a second issue. I saw that if I created an .config/oxidized/config/model folder and put the ios.rb file in there it was supposed to take over. But, I cannot get it to work from that location. Only works if I edit the 29.1 gems files.

My current config

username: oxidized
password: password
#model: junos
resolve_dns: true
interval: 3600
use_syslog: false
debug: true
threads: 30
use_max_threads: true
timeout: 20
retries: 2
prompt: !ruby/regexp /^([\w.@-]+[#:>]\s?)$/
rest: 192.168.10.112:8888
next_adds_job: false
vars: {}
groups: {}
group_map: {}
models: {}
pid: "/home/oxidized/.config/oxidized/pid"
crash:
  directory: "/home/oxidized/.config/oxidized/crashes"
  hostnames: false
stats:
  history_size: 10
input:
  default: ssh, telnet
  debug: true
  ssh:
    secure: false
  ftp:
    passive: true
  telnet:
   debug: true
  utf8_encoded: true
source:
  default: http
  debug: true
  http:
    url: http://localhost/api/v0/oxidized
    map:
      name: hostname
      model: os
      group: group
    headers:
      X-Auth-Token: *********************
groups:
  defaultgrp:
    username: username
    password: password
  ios:
    username: username
    password: password
  Adtran:
    username: username
    password: password
  Copiers:
    username: username
    password: password
  TestGroup:
    username: username
    password: password
  TelnetTest:
    username: username
    password: password
  sharp:
   username: admin
   password: admin
output:
 default: git
 git:
  user: oxidized
  email: [email protected]
  repo: "/home/oxidized/.config/oxidized/devices.git"
#  file:
#    directory: "/home/oxidized/.config/oxidized/configs"

Current ios.rb

class IOS < Oxidized::Model
  using Refinements

  prompt /^([\w.@()-]+[#:>]\s?)$/
  comment  '! '

  # example how to handle pager
  # expect /^\s--More--\s+.*$/ do |data, re|
  #  send ' '
  #  data.sub re, ''
  # end

  # non-preferred way to handle additional PW prompt
  # expect /^[\w.]+>$/ do |data|
  #  send "enable\n"
  #  send vars(:enable) + "\n"
  #  data
  # end

  cmd :all do |cfg|
    # cfg.gsub! /\cH+\s{8}/, ''         # example how to handle pager
    # cfg.gsub! /\cH+/, ''              # example how to handle pager
    # get rid of errors for commands that don't work on some devices
    cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, ''
    cfg.cut_both
  end

  cmd :secret do |cfg|
    cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
    cfg.gsub! /^(snmp-server host \S+( vrf \S+)?( informs?)?( version (1|2c|3 (noauth|auth|priv)))?)\s+\S+((\s+\S*)*)\s*/, '\\1 <secret hidden> \\7'
    cfg.gsub! /^(username .+ (password|secret) \d) .+/, '\\1 <secret hidden>'
    cfg.gsub! /^(enable (password|secret)( level \d+)? \d) .+/, '\\1 <secret hidden>'
    cfg.gsub! /^(\s+(?:password|secret)) (?:\d )?\S+/, '\\1 <secret hidden>'
    cfg.gsub! /^(.*wpa-psk ascii \d) (\S+)/, '\\1 <secret hidden>'
    cfg.gsub! /^(.*key 7) (\d.+)/, '\\1 <secret hidden>'
    cfg.gsub! /^(tacacs-server (.+ )?key) .+/, '\\1 <secret hidden>'
    cfg.gsub! /^(crypto isakmp key) (\S+) (.*)/, '\\1 <secret hidden> \\3'
    cfg.gsub! /^(\s+ip ospf message-digest-key \d+ md5) .+/, '\\1 <secret hidden>'
    cfg.gsub! /^(\s+ip ospf authentication-key) .+/, '\\1 <secret hidden>'
    cfg.gsub! /^(\s+neighbor \S+ password) .+/, '\\1 <secret hidden>'
    cfg.gsub! /^(\s+vrrp \d+ authentication text) .+/, '\\1 <secret hidden>'
    cfg.gsub! /^(\s+standby \d+ authentication) .{1,8}$/, '\\1 <secret hidden>'
    cfg.gsub! /^(\s+standby \d+ authentication md5 key-string) .+?( timeout \d+)?$/, '\\1 <secret hidden> \\2'
    cfg.gsub! /^(\s+key-string) .+/, '\\1 <secret hidden>'
    cfg.gsub! /^((tacacs|radius) server [^\n]+\n(\s+[^\n]+\n)*\s+key) [^\n]+$/m, '\1 <secret hidden>'
    cfg.gsub! /^(\s+ppp (chap|pap) password \d) .+/, '\\1 <secret hidden>'
    cfg
  end

  cmd 'show version' do |cfg|
    comments = []
    comments << cfg.lines.first
    lines = cfg.lines
    lines.each_with_index do |line, i|
      slave = ''
      slaveslot = ''

      if line =~ /^Slave in slot (\d+) is running/
        slave = " Slave:"
        slaveslot = ", slot #{Regexp.last_match(1)}"
      end

      comments << "Image:#{slave} Compiled: #{Regexp.last_match(1)}" if line =~ /^Compiled (.*)$/

      comments << "Image:#{slave} Software: #{Regexp.last_match(1)}, #{Regexp.last_match(2)}" if line =~ /^(?:Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/

      comments << "ROM Bootstrap: #{Regexp.last_match(3)}" if line =~ /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/

      comments << "BOOTFLASH: #{Regexp.last_match(1)}" if line =~ /^BOOTFLASH: .*(Version.*)$/

      comments << "Memory: nvram #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (non-volatile|NVRAM)/

      comments << "Memory: flash #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (flash memory|flash internal|processor board System flash|ATA CompactFlash)/i

      comments << "Memory: pcmcia #{Regexp.last_match(2)} #{Regexp.last_match(3)}#{Regexp.last_match(4)} #{Regexp.last_match(1)}" if line =~ /^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i

      if line =~ /(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i
        sproc = Regexp.last_match(1)
        cpu = Regexp.last_match(2)
        mem = Regexp.last_match(3)
        cpuxtra = ''
        comments << "Chassis type:#{slave} #{sproc}"
        comments << "Memory:#{slave} main #{mem}"
        # check the next two lines for more CPU info
        comments << "Processor ID: #{Regexp.last_match(1)}" if cfg.lines[i + 1] =~ /processor board id (\S+)/i
        if cfg.lines[i + 2] =~ /(cpu at |processor: |#{cpu} processor,)/i
          # change implementation to impl and prepend comma
          cpuxtra = cfg.lines[i + 2].gsub(/implementation/, 'impl').gsub(/^/, ', ').chomp
        end
        comments << "CPU:#{slave} #{cpu}#{cpuxtra}#{slaveslot}"
      end

      comments << "Image: #{Regexp.last_match(1)}" if line =~ /^System image file is "([^"]*)"$/
    end
    comments << "\n"
    comment comments.join "\n"
  end

  cmd 'show vtp status' do |cfg|
    cfg.gsub! /^$\n/, ''
    cfg.gsub! /Configuration last modified by.*\n/, ''
    cfg.gsub! /^/, 'VTP: ' unless cfg.empty?
    comment "#{cfg}\n"
  end

  cmd 'show inventory' do |cfg|
    comment cfg
  end

  post do
    cmd_line = 'show running-config'
    cmd_line += ' view full' if vars(:ios_rbac)
    cmd cmd_line do |cfg|
      cfg = cfg.each_line.to_a[3..-1]
      cfg = cfg.reject { |line| line.match /^ntp clock-period / }.join
      cfg = cfg.each_line.reject { |line| line.match /^! (Last|No) configuration change (at|since).*/ unless line =~ /\d+\sby\s\S+$/ }.join
      cfg.gsub! /^Current configuration : [^\n]*\n/, ''
      cfg.gsub! /^ tunnel mpls traffic-eng bandwidth[^\n]*\n*(
                    (?: [^\n]*\n*)*
                    tunnel mpls traffic-eng auto-bw)/mx, '\1'
      cfg
    end
  end

  cfg :telnet do
    username /^[uU]sername:/i
    password /^[pP]assword:/i
    #username /^[lL]ogin:/i
    #post_login 'username'
    #post_login 'password'
  end

  cfg :telnet, :ssh do
    # preferred way to handle additional passwords
    post_login do
      if vars(:enable) == true
        cmd "enable"
      elsif vars(:enable)
        cmd "enable", /^[pP]assword:/
        cmd vars(:enable)
      end
    end
    post_login 'terminal length 0'
    post_login 'terminal width 0'
    pre_logout 'exit'
  end
end
`

Have you looked into a separate group for the device? Before a software update, we had some devices that would only accept eight-character passwords, so they all had to be placed in a separate group in NMS. That group was configured to use different settings in Oxidized.

Edit: I say separate group - they were grouped via config.php using the syntax below. It might be different now that lnms is around. My deployment predates lnms, and I haven’t removed old settings from config.php in favor of that method.

#Template: $config['oxidized']['group']['hostname'][] = array('regex' => '/^REGEX_HERE$/', 'group' => 'XXX_ssh');
$config['oxidized']['group']['hostname'][] = array('regex' => '/^10\.4\.0\.([0-9]|1[0-4])$/', 'group' => 'AUS_ssh');

Edit 2: This is an example of using a separate group for a range of IPs, but it can be applied to a single IP with identical group names. The Oxidized config would look like this:

groups:
  special_ssh:
    password: 12345678
  DAL_ssh:
    password: DALPass
    vars:
      enable: DALEnable
  NWA_ssh:
    password: NWAPass
    vars:
      enable: NWAEnable