Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oxidized-script issue from oxidized issue #1455 #24

Open
bruccoo3000 opened this issue Jul 18, 2018 · 7 comments
Open

oxidized-script issue from oxidized issue #1455 #24

bruccoo3000 opened this issue Jul 18, 2018 · 7 comments

Comments

@bruccoo3000
Copy link

ytti,

Here's the changes that I made as per your post for lines 37-42:

          rescue => error
            puts "We had the following error on node #{node}:\n#{error}"
          end
        }
      end
      Process.waitall
    else
      @hosts = @host.split(/\s*,\s*/)
      @hosts.each do |host|
        @host = host
        <lines 37 ... 42>
      end
    end
  end

I've tried different orders of nodes to see what would happen and it seems that what ever the first node is then that would be the device that would be output.

Thanks again

@ytti
Copy link
Owner

ytti commented Jul 18, 2018

Did you write <lines 37 ... 42>> verbatim? You were supposed to copy the lines there. I want to see what your file actually looks like.

@bruccoo3000
Copy link
Author

module Oxidized
require_relative 'script'
require 'slop'

class Script
class CLI
attr_accessor :cmd_class
class CLIError < ScriptError; end
class NothingToDo < ScriptError; end

  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
      @hosts = @host.split(/\s*,\s*/)
      @hosts.each do |host|
        @host = host
      end
    end
  end

  private

  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

  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

  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

  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

  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

  def get_hosts
    if @group and @regex
      puts "running list for hosts in group: #{@group} and matching: #{@regex}" if @verbose
      nodes_group = run_group @group
      nodes_regex = run_regex @regex
      return nodes_group & nodes_regex
    elsif @group and @ostype
      puts "running list for hosts in group: #{@group} and matching: #{@ostype}" if @verbose
      nodes_group = run_group @group
      nodes_ostype = run_ostype @ostype
      return nodes_group & nodes_ostype
    elsif @regex
      puts 'running list for hosts matching: ' + @regex if @verbose
      return run_regex @regex
    elsif @ostype
      puts 'running list for hosts matching ostype: ' + @ostype if @verbose
      return run_ostype @ostype
    else
      puts 'running list for hosts in group: ' + @group if @verbose
      return run_group @group
    end
  end

  def run_group group
    Oxidized.mgr = Manager.new
    out = []
    Nodes.new.each do |node|
      next unless group == node.group
      out << node.name
    end
    out
  end

  def run_ostype ostype
    Oxidized.mgr = Manager.new
    out = []
    Nodes.new.each do |node|
      ostype.downcase # need to make sure they are both in lowercase
      nodemodel = node.model.to_s.downcase # need to make sure they are both in lowercase
      next unless nodemodel =~ /#{ostype}/
      out << node.name
    end
    out
  end

  def run_regex regex
    Oxidized.mgr = Manager.new
    out = []
    Nodes.new.each do |node|
      next unless node.name =~ /#{regex}/
      out << node.name
    end
    out
  end

end

end
end

I have copied and replaced lines 37-42 with the changes noted in issue #1455.

@ytti
Copy link
Owner

ytti commented Jul 18, 2018

You were supposed to insert 37..42 to the named spot. Now it shouldn't do anything, if it does something, it's because it's running in group, ostype or regexp mode.

@bruccoo3000
Copy link
Author

Ah, so I misunderstood.

So, I did a few things to see if I am getting it right.

  1. Replaced lines 37-42 with the commands you placed in issue #1455. As seen in the previous post
  2. Added the commands before section 37-42. Didn't work
  3. Added the commands after section 37-42. Didn't work

Now if you're saying I need to insert those commands in that section, at what line should I be inserting them?

Thanks for your patience.

@ytti
Copy link
Owner

ytti commented Jul 18, 2018

Try this http://p.ip.fi/uhTz.txt

@laf
Copy link
Contributor

laf commented Jul 21, 2018

I can confirm the changes proposed here work absolutely fine.

@bruccoo3000
Copy link
Author

Thanks for the file, I've replaced the following files:
/usr/local/share/gems/gems/oxidized-script-0.5.1/lib/oxidized/script/cli.rb
/home/oxidized/.rvm/gems/ruby-2.5.1/gems/oxidized-script-0.5.1/lib/oxidized/script/cli.rb

.....and I see the following:
[oxidized@oxidized ~]$ oxs node1,node2 'sh ver'
I, [2018-07-23T09:56:16.475202 #999] INFO -- : lib/oxidized/nodes.rb: Loading nodes
I, [2018-07-23T09:56:31.707494 #999] INFO -- : lib/oxidized/nodes.rb: Loaded 2 nodes

The output I receive is only for the second device in the list. Here's the list of files I have for cli.rb:
/usr/local/share/gems/gems/puma-3.11.4/lib/puma/cli.rb
/usr/local/share/gems/gems/rubygems-update-2.7.6/bundler/lib/bundler/cli.rb
/usr/local/share/gems/gems/sass-listen-4.0.0/lib/sass-listen/cli.rb
/usr/local/share/gems/gems/bundler-1.16.2/lib/bundler/cli.rb
/usr/local/share/gems/gems/oxidized-script-0.5.1/lib/oxidized/script/cli.rb
/usr/local/share/gems/gems/rubygems-update-2.7.7/bundler/lib/bundler/cli.rb
/usr/local/share/gems/gems/oxidized-0.24.0/lib/oxidized/cli.rb
/usr/local/share/gems/gems/oxidized-0.24.0/lib/oxidized/input/cli.rb
/usr/local/share/ruby/site_ruby/bundler/cli.rb
/home/oxidized/.gem/ruby/gems/rubygems-update-2.7.6/bundler/lib/bundler/cli.rb
/home/oxidized/.rvm/gems/ruby-2.5.1/gems/sass-listen-4.0.0/lib/sass-listen/cli.rb
/home/oxidized/.rvm/gems/ruby-2.5.1/gems/puma-3.11.4/lib/puma/cli.rb
/home/oxidized/.rvm/gems/ruby-2.5.1/gems/oxidized-script-0.5.1/lib/oxidized/script/cli.rb
/home/oxidized/.rvm/gems/ruby-2.5.1/gems/oxidized-0.24.0/lib/oxidized/cli.rb
/home/oxidized/.rvm/gems/ruby-2.5.1/gems/oxidized-0.24.0/lib/oxidized/input/cli.rb
/home/oxidized/.rvm/gems/ruby-2.5.1/gems/rubygems-update-2.7.7/bundler/lib/bundler/cli.rb
/home/oxidized/.rvm/rubies/ruby-2.5.1/lib/ruby/site_ruby/2.5.0/bundler/cli.rb

Pretty sure I updated the right ones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants