diff options
Diffstat (limited to 'lib/oxidized/input')
| -rw-r--r-- | lib/oxidized/input/cli.rb | 18 | ||||
| -rw-r--r-- | lib/oxidized/input/ssh.rb | 12 | ||||
| -rw-r--r-- | lib/oxidized/input/telnet.rb | 95 | 
3 files changed, 114 insertions, 11 deletions
| diff --git a/lib/oxidized/input/cli.rb b/lib/oxidized/input/cli.rb index 1d58e85..8daddac 100644 --- a/lib/oxidized/input/cli.rb +++ b/lib/oxidized/input/cli.rb @@ -8,18 +8,26 @@ module Oxidized        end        def get -        @post_login.each { |command| cmd command } +        @post_login.each { |command, block| block ? block.call : (cmd command) }          d = @node.model.get          disconnect          d        end + +      def disconnect_cli +        @pre_logout.each { |command, block| block ? block.call : (cmd command) } +      end -      def post_login _post_login -        @post_login << _post_login unless @exec +      def post_login _post_login=nil, &block +        unless @exec +          @post_login << [_post_login, block] +        end        end -      def pre_logout _pre_logout -        @pre_logout << _pre_logout unless @exec +      def pre_logout _pre_logout=nil, &block +        unless @exec +          @pre_logout <<  [_pre_logout, block] +        end        end      end    end diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb index 3471eea..3d14a57 100644 --- a/lib/oxidized/input/ssh.rb +++ b/lib/oxidized/input/ssh.rb @@ -15,7 +15,7 @@ module Oxidized        rescue Timeout::Error, Net::SSH::Disconnect, Errno::ECONNREFUSED          return false        end -      @ses = open_shell @ssh unless @exec +      open_shell @ssh unless @exec        not @ssh.closed?      end @@ -28,11 +28,15 @@ module Oxidized        end      end +    def send data +      @ses.send_data data +    end +      private      def disconnect        begin -        @pre_logout.each { |command| cmd command } +        disconnect_cli          @ssh.loop          @ssh.close if not @ssh.closed?        rescue Net::SSH::Disconnect @@ -40,9 +44,10 @@ module Oxidized      end      def open_shell ssh -      ses = ssh.open_channel do |ch| +      @ses = ssh.open_channel do |ch|          ch.on_data do |ch, data|            @output << data +          @output = @node.model.expects @output          end          ch.request_pty do |ch, success|            raise NoShell, "Can't get PTY" unless success @@ -52,7 +57,6 @@ module Oxidized          end        end        expect @node.prompt -      ses      end      def exec state=nil diff --git a/lib/oxidized/input/telnet.rb b/lib/oxidized/input/telnet.rb index 0ec08f9..c1afde2 100644 --- a/lib/oxidized/input/telnet.rb +++ b/lib/oxidized/input/telnet.rb @@ -10,7 +10,8 @@ module Oxidized        @timeout = CFG.timeout        @node.model.cfg['telnet'].each { |cb| instance_exec &cb }        begin -        @telnet  = Net::Telnet.new 'Host' => @node.ip, 'Waittime' => @timeout +        @telnet  = Net::Telnet.new 'Host' => @node.ip, 'Waittime' => @timeout, +                                   'Model' => @node.model          expect username          @telnet.puts @node.auth[:username]          expect password @@ -32,6 +33,10 @@ module Oxidized        end      end +    def send data +      @telnet.write data +    end +      private      def expect re @@ -40,7 +45,7 @@ module Oxidized      def disconnect        begin -        @pre_logout.each { |command| cmd(command, nil) } +        disconnect_cli          @telnet.close        rescue Errno::ECONNRESET        end @@ -56,3 +61,89 @@ module Oxidized    end  end + + +class Net::Telnet +  ## FIXME: we just need 'line = model.expects line' to handle pager +  ## how to do this, without redefining the whole damn thing +  def waitfor(options) # :yield: recvdata +    time_out = @options["Timeout"] +    waittime = @options["Waittime"] +    fail_eof = @options["FailEOF"] +    model    = @options["Model"] + +    if options.kind_of?(Hash) +      prompt   = if options.has_key?("Match") +                   options["Match"] +                 elsif options.has_key?("Prompt") +                   options["Prompt"] +                 elsif options.has_key?("String") +                   Regexp.new( Regexp.quote(options["String"]) ) +                 end +      time_out = options["Timeout"]  if options.has_key?("Timeout") +      waittime = options["Waittime"] if options.has_key?("Waittime") +      fail_eof = options["FailEOF"]  if options.has_key?("FailEOF") +    else +      prompt = options +    end + +    if time_out == false +      time_out = nil +    end + +    line = '' +    buf = '' +    rest = '' +    until(prompt === line and not IO::select([@sock], nil, nil, waittime)) +      unless IO::select([@sock], nil, nil, time_out) +        raise Net::ReadTimeout, "timed out while waiting for more data" +      end +      begin +        c = @sock.readpartial(1024 * 1024) +        @dumplog.log_dump('<', c) if @options.has_key?("Dump_log") +        if @options["Telnetmode"] +          c = rest + c +          if Integer(c.rindex(/#{IAC}#{SE}/no) || 0) < +             Integer(c.rindex(/#{IAC}#{SB}/no) || 0) +            buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/no)]) +            rest = c[c.rindex(/#{IAC}#{SB}/no) .. -1] +          elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) || +                     c.rindex(/\r\z/no) +            buf = preprocess(c[0 ... pt]) +            rest = c[pt .. -1] +          else +            buf = preprocess(c) +            rest = '' +          end +       else +         # Not Telnetmode. +         # +         # We cannot use preprocess() on this data, because that +         # method makes some Telnetmode-specific assumptions. +         buf = rest + c +         rest = '' +         unless @options["Binmode"] +           if pt = buf.rindex(/\r\z/no) +             buf = buf[0 ... pt] +             rest = buf[pt .. -1] +           end +           buf.gsub!(/#{EOL}/no, "\n") +         end +        end +        @log.print(buf) if @options.has_key?("Output_log") +        line += buf +        line = model.expects line +        line = yield line if block_given? +        yield buf if block_given? +      rescue EOFError # End of file reached +        raise if fail_eof +        if line == '' +          line = nil +          yield nil if block_given? +        end +        break +      end +    end +    line +  end +end | 
