class Oxidized::Script::CLI

Attributes

cmd_class[RW]

Public Class Methods

new() click to toggle source
# File lib/oxidized/script/cli.rb, line 48
def initialize
  @args, @opts = opts_parse load_dynamic

  Config.load(@opts)
  Oxidized.setup_logger

  if @opts[:commands]
    Oxidized.config.vars.ssh_no_exec = true
  end

  if @cmd_class
    @cmd_class.run :args=>@args, :opts=>@opts, :host=>@host, :cmd=>@cmd
    exit 0
  else
    if @group or @regex or @ostype
      @cmd = @args.shift
    else
      @host = @args.shift
      @cmd  = @args.shift if @args
    end
    @oxs  = nil
    raise NothingToDo, 'no host given' if not @host and not @group and not @ostype and not @regex
    if @dryrun
      puts get_hosts
      exit
    end
    raise NothingToDo, 'nothing to do, give command or -x' if not @cmd and not @opts[:commands]
  end
end

Public Instance Methods

run() click to toggle source
# File lib/oxidized/script/cli.rb, line 11
def run
  if @group or @regex or @ostype
    $stdout.sync = true
    nodes = get_hosts
    counter = @threads.to_i
    Signal.trap("CLD") { counter += 1 }
    nodes.each do |node|
      Process.wait if counter <= 0
      puts "Forking " + node if @verbose
      counter -= 1
      fork {
        begin
          @host = node
          connect
          if @opts[:commands]
            puts "Running commands on #{node}:\n#{run_file @opts[:commands]}"
          elsif @cmd
            puts "Running commands on #{node}:\n#{@oxs.cmd @cmd}"
          end
        rescue => error
          puts "We had the following error on node #{node}:\n#{error}"
        end
      }
    end
    Process.waitall
  else
    connect
    if @opts[:commands]
      puts run_file @opts[:commands]
    elsif @cmd
      puts @oxs.cmd @cmd
    end
  end
end

Private Instance Methods

connect() click to toggle source
# File lib/oxidized/script/cli.rb, line 116
def connect
  opts = {}
  opts[:host]     = @host
  [:model, :username, :password, :timeout, :enable, :verbose, :community, :protocols].each do |key|
    opts[key] = @opts[key] if @opts[key]
  end
  @oxs = Script.new opts
end
get_hosts() click to toggle source
# File lib/oxidized/script/cli.rb, line 152
def get_hosts
  puts "running list for hosts" if @verbose
  if @group
    puts " - in group: #{@group}" if @verbose
  end
  if @ostype
    puts " - (and) matching ostype: #{@ostype}" if @verbose
  end
  if @regex
    puts " - (and) matching: #{@regex}" if @verbose
  end
  Oxidized.mgr = Manager.new
  out = []
  loop_verbose = false # turn on/off verbose output for the following loop
  Nodes.new.each do |node|
    if @group
      puts " ... checking if #{node.name} in group: #{@group}, node group is: #{node.group}" if loop_verbose
      next unless @group == node.group
    end
    if @ostype
      puts " ... checking if #{node.name} matching ostype: #{@ostype}, node ostype is: #{node.model.to_s}" if loop_verbose
      next unless node.model.to_s.match(/#{@ostype}/i)
    end
    if @regex
      puts " ... checking if if #{node.name} matching: #{@regex}" if loop_verbose
      next unless node.name.match(/#{@regex}/)
    end
    out << node.name
  end
  out
end
load_dynamic() click to toggle source
# File lib/oxidized/script/cli.rb, line 136
def load_dynamic
  cmds = []
  files = File.dirname __FILE__
  files = File.join files, 'commands', '*.rb'
  files = Dir.glob files
  files.each { |file| require_relative file }
  Script::Command.constants.each do |cmd|
    next if cmd == :Base
    cmd = Script::Command.const_get cmd
    name = cmd.const_get :Name
    desc = cmd.const_get :Description
    cmds << { class: cmd, name: name, description: desc }
  end
  cmds
end
opts_parse(cmds) click to toggle source
# File lib/oxidized/script/cli.rb, line 78
def opts_parse cmds
  slop = Slop.new(help: true)
  slop.banner 'Usage: oxs [options] hostname [command]'
  slop.on 'm=', '--model',     'host model (ios, junos, etc), otherwise discovered from Oxidized source'
  slop.on 'o=', '--ostype',    'OS Type (ios, junos, etc)'
  slop.on 'x=', '--commands',  'commands file to be sent'
  slop.on 'u=', '--username',  'username to use'
  slop.on 'p=', '--password',  'password to use'
  slop.on 't=', '--timeout',   'timeout value to use'
  slop.on 'e=', '--enable',    'enable password to use'
  slop.on 'c=', '--community', 'snmp community to use for discovery'
  slop.on 'g=', '--group',     'group to run commands on (ios, junos, etc), specified in oxidized db'
  slop.on 'r=', '--threads',   'specify ammount of threads to use for running group', default: '1'
  slop.on       '--regex=',    'run on all hosts that match the regexp'
  slop.on       '--dryrun',    'do a dry run on either groups or regexp to find matching hosts'
  slop.on       '--protocols=','protocols to use, default "ssh, telnet"'
  slop.on 'v',  '--verbose',   'verbose output, e.g. show commands sent'
  slop.on 'd',  '--debug',     'turn on debugging'
  slop.on :terse, 'display clean output'
  cmds.each do |cmd|
    if cmd[:class].respond_to? :cmdline
      cmd[:class].cmdline slop, self
    else
      slop.on cmd[:name], cmd[:description] do
        @cmd_class = cmd[:class]
      end
    end
  end
  slop.parse
  @group = slop[:group]
  @ostype = slop[:ostype]
  @threads = slop[:threads]
  @verbose = slop[:verbose]
  @dryrun = slop[:dryrun]
  @regex = slop[:regex]
  [slop.parse!, slop]
end
run_file(file) click to toggle source
# File lib/oxidized/script/cli.rb, line 125
def run_file file
  out = ''
  file = file == '-' ? $stdin : File.read(file)
  file.each_line do |line|
    line.chomp!
    # line.sub!(/\\n/, "\n") # treat escaped newline as newline
    out += @oxs.cmd line
  end
  out
end