netconf 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/examples/confd/get-running.rb +27 -27
- data/examples/jnpr/edit-config-jnpr-set.rb +55 -55
- data/examples/jnpr/edit-config-jnpr-text.rb +64 -64
- data/examples/jnpr/edit-config-jnpr.rb +73 -73
- data/examples/jnpr/edit-config-std.rb +64 -64
- data/examples/jnpr/edit-config-text-std.rb +68 -68
- data/examples/jnpr/get-config-jnpr.rb +62 -62
- data/examples/jnpr/get-config-matching.rb +20 -20
- data/examples/jnpr/get-config-std.rb +49 -49
- data/examples/jnpr/get-inventory-serial-explicit.rb +27 -27
- data/examples/jnpr/get-inventory-serial.rb +25 -25
- data/examples/jnpr/get-inventory-telnet.rb +14 -14
- data/examples/jnpr/get-inventory.rb +16 -16
- data/examples/jnpr/scp.rb +22 -22
- data/lib/net/netconf.rb +11 -1
- data/lib/net/netconf/exception.rb +38 -38
- data/lib/net/netconf/ioproc.rb +88 -88
- data/lib/net/netconf/jnpr.rb +9 -9
- data/lib/net/netconf/jnpr/ioproc.rb +14 -14
- data/lib/net/netconf/jnpr/rpc.rb +162 -140
- data/lib/net/netconf/jnpr/serial.rb +15 -15
- data/lib/net/netconf/jnpr/telnet.rb +23 -23
- data/lib/net/netconf/rpc.rb +71 -71
- data/lib/net/netconf/rpc_std.rb +133 -134
- data/lib/net/netconf/serial.rb +135 -135
- data/lib/net/netconf/ssh.rb +78 -77
- data/lib/net/netconf/telnet.rb +52 -52
- data/lib/net/netconf/transport.rb +28 -5
- data/lib/net/netconf/version.rb +3 -0
- metadata +21 -12
    
        data/lib/net/netconf/rpc_std.rb
    CHANGED
    
    | @@ -1,134 +1,133 @@ | |
| 1 | 
            -
            module Netconf  
         | 
| 2 | 
            -
              module RPC
         | 
| 3 | 
            -
                
         | 
| 4 | 
            -
                MSG_END = "]]>]]>"
         | 
| 5 | 
            -
                MSG_END_RE = /\]\]>\]\]>[\r\n]*$/
         | 
| 6 | 
            -
                MSG_CLOSE_SESSION = '<rpc><close-session/></rpc>'       
         | 
| 7 | 
            -
                MSG_HELLO = <<-EOM
         | 
| 8 | 
            -
            <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
         | 
| 9 | 
            -
              <capabilities>
         | 
| 10 | 
            -
                <capability>urn:ietf:params:netconf:base:1.0</capability>
         | 
| 11 | 
            -
              </capabilities>
         | 
| 12 | 
            -
            </hello>
         | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
                
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                   | 
| 20 | 
            -
                   | 
| 21 | 
            -
             | 
| 22 | 
            -
                 | 
| 23 | 
            -
                
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                   | 
| 26 | 
            -
             | 
| 27 | 
            -
                 | 
| 28 | 
            -
                
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                   | 
| 31 | 
            -
                   | 
| 32 | 
            -
             | 
| 33 | 
            -
                 | 
| 34 | 
            -
                
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                   | 
| 37 | 
            -
                   | 
| 38 | 
            -
             | 
| 39 | 
            -
                 | 
| 40 | 
            -
                
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                   | 
| 43 | 
            -
             | 
| 44 | 
            -
                 | 
| 45 | 
            -
                
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                  
         | 
| 48 | 
            -
                   | 
| 49 | 
            -
                   | 
| 50 | 
            -
                  
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                     | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
                        when Nokogiri::XML:: | 
| 56 | 
            -
                         | 
| 57 | 
            -
                         | 
| 58 | 
            -
             | 
| 59 | 
            -
                    when ' | 
| 60 | 
            -
                     | 
| 61 | 
            -
             | 
| 62 | 
            -
                   | 
| 63 | 
            -
                  
         | 
| 64 | 
            -
                   | 
| 65 | 
            -
                  
         | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
                   | 
| 73 | 
            -
                  
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                    f_node =  | 
| 76 | 
            -
                    f_node | 
| 77 | 
            -
                     | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
                  
         | 
| 86 | 
            -
                   | 
| 87 | 
            -
                   | 
| 88 | 
            -
                   | 
| 89 | 
            -
                   | 
| 90 | 
            -
                  
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                     | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
                        when Nokogiri::XML:: | 
| 96 | 
            -
                         | 
| 97 | 
            -
                         | 
| 98 | 
            -
             | 
| 99 | 
            -
                    when ' | 
| 100 | 
            -
                     | 
| 101 | 
            -
             | 
| 102 | 
            -
                   | 
| 103 | 
            -
                  
         | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
            < | 
| 108 | 
            -
            < | 
| 109 | 
            -
                | 
| 110 | 
            -
             | 
| 111 | 
            -
            </ | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
                   | 
| 116 | 
            -
                  
         | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
                   | 
| 126 | 
            -
                  
         | 
| 127 | 
            -
                   | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
             | 
| 134 | 
            -
            end # module: Netconf
         | 
| 1 | 
            +
            module Netconf  
         | 
| 2 | 
            +
              module RPC
         | 
| 3 | 
            +
                
         | 
| 4 | 
            +
                MSG_END = "]]>]]>"
         | 
| 5 | 
            +
                MSG_END_RE = /\]\]>\]\]>[\r\n]*$/
         | 
| 6 | 
            +
                MSG_CLOSE_SESSION = '<rpc><close-session/></rpc>'       
         | 
| 7 | 
            +
                MSG_HELLO = <<-EOM
         | 
| 8 | 
            +
            <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
         | 
| 9 | 
            +
              <capabilities>
         | 
| 10 | 
            +
                <capability>urn:ietf:params:netconf:base:1.0</capability>
         | 
| 11 | 
            +
              </capabilities>
         | 
| 12 | 
            +
            </hello>
         | 
| 13 | 
            +
            EOM
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              module Standard
         | 
| 16 | 
            +
                
         | 
| 17 | 
            +
                def lock( target )      
         | 
| 18 | 
            +
                  rpc = Nokogiri::XML( "<rpc><lock><target><#{target}/></target></lock></rpc>" ).root
         | 
| 19 | 
            +
                  Netconf::RPC.set_exception( rpc, Netconf::LockError )
         | 
| 20 | 
            +
                  @trans.rpc_exec( rpc )      
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                def unlock( target )
         | 
| 24 | 
            +
                  rpc = Nokogiri::XML( "<rpc><unlock><target><#{target}/></target></unlock></rpc>" ).root
         | 
| 25 | 
            +
                  @trans.rpc_exec( rpc )          
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                def validate( source )
         | 
| 29 | 
            +
                  rpc = Nokogiri::XML( "<rpc><validate><source><#{source}/></source></validate></rpc>" ).root
         | 
| 30 | 
            +
                  Netconf::RPC.set_exception( rpc, Netconf::ValidateError )      
         | 
| 31 | 
            +
                  @trans.rpc_exec( rpc )          
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
                
         | 
| 34 | 
            +
                def commit
         | 
| 35 | 
            +
                  rpc = Nokogiri::XML( "<rpc><commit/></rpc>" ).root
         | 
| 36 | 
            +
                  Netconf::RPC.set_exception( rpc, Netconf::CommitError )      
         | 
| 37 | 
            +
                  @trans.rpc_exec( rpc )                
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
                
         | 
| 40 | 
            +
                def delete_config( target )
         | 
| 41 | 
            +
                  rpc = Nokogiri::XML( "<rpc><delete-config><target><#{target}/></target></delete-config></rpc>" ).root
         | 
| 42 | 
            +
                  @trans.rpc_exec( rpc )          
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
                
         | 
| 45 | 
            +
                def get_config( *args ) # :yeield: filter_builder
         | 
| 46 | 
            +
                  
         | 
| 47 | 
            +
                  source = 'running'    # default source is 'running'
         | 
| 48 | 
            +
                  filter = nil          # no filter by default
         | 
| 49 | 
            +
                  
         | 
| 50 | 
            +
                  while arg = args.shift
         | 
| 51 | 
            +
                    case arg.class.to_s
         | 
| 52 | 
            +
                    when /^Nokogiri/ 
         | 
| 53 | 
            +
                      filter = case arg
         | 
| 54 | 
            +
                        when Nokogiri::XML::Builder  then arg.doc.root
         | 
| 55 | 
            +
                        when Nokogiri::XML::Document then arg.root
         | 
| 56 | 
            +
                        else arg
         | 
| 57 | 
            +
                        end    
         | 
| 58 | 
            +
                    when 'Hash' then attrs = arg
         | 
| 59 | 
            +
                    when 'String' then source = arg
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                  
         | 
| 63 | 
            +
                  rpc = Nokogiri::XML("<rpc><get-config><source><#{source}/></source></get-config></rpc>").root
         | 
| 64 | 
            +
                  
         | 
| 65 | 
            +
                  if block_given?
         | 
| 66 | 
            +
                    Nokogiri::XML::Builder.with( rpc.at( 'get-config' )){ |xml|
         | 
| 67 | 
            +
                      xml.filter( :type => 'subtree' ) {
         | 
| 68 | 
            +
                        yield( xml )
         | 
| 69 | 
            +
                      }
         | 
| 70 | 
            +
                    }
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                  
         | 
| 73 | 
            +
                  if filter
         | 
| 74 | 
            +
                    f_node = Nokogiri::XML::Node.new( 'filter', rpc )
         | 
| 75 | 
            +
                    f_node['type'] = 'subtree'
         | 
| 76 | 
            +
                    f_node << filter.dup   # copy filter, don't mess with the original since it may be re-used
         | 
| 77 | 
            +
                    rpc.at('get-config') <<  f_node
         | 
| 78 | 
            +
                  end             
         | 
| 79 | 
            +
                        
         | 
| 80 | 
            +
                  @trans.rpc_exec( rpc )      
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def edit_config( *args ) # :yeield: config_builder
         | 
| 84 | 
            +
                  
         | 
| 85 | 
            +
                  toplevel = 'config'   # default toplevel config element
         | 
| 86 | 
            +
                  target = 'candidate'  # default source is 'candidate'  @@@/JLS hack; need to fix this
         | 
| 87 | 
            +
                  config = nil
         | 
| 88 | 
            +
                  options = {}
         | 
| 89 | 
            +
                  
         | 
| 90 | 
            +
                  while arg = args.shift
         | 
| 91 | 
            +
                    case arg.class.to_s
         | 
| 92 | 
            +
                    when /^Nokogiri/ 
         | 
| 93 | 
            +
                      config = case arg
         | 
| 94 | 
            +
                        when Nokogiri::XML::Builder  then arg.doc.root
         | 
| 95 | 
            +
                        when Nokogiri::XML::Document then arg.root
         | 
| 96 | 
            +
                        else arg
         | 
| 97 | 
            +
                        end    
         | 
| 98 | 
            +
                    when 'Hash' then options = arg
         | 
| 99 | 
            +
                    when 'String' then target = arg
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
                  
         | 
| 103 | 
            +
                  toplevel = options[:toplevel] if options[:toplevel]
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  rpc_str = <<-EO_RPC
         | 
| 106 | 
            +
            <rpc>
         | 
| 107 | 
            +
            <edit-config>
         | 
| 108 | 
            +
               <target><#{target}/></target>
         | 
| 109 | 
            +
               <#{toplevel}/>
         | 
| 110 | 
            +
            </edit-config>
         | 
| 111 | 
            +
            </rpc>
         | 
| 112 | 
            +
            EO_RPC
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                  rpc = Nokogiri::XML( rpc_str ).root
         | 
| 115 | 
            +
                  
         | 
| 116 | 
            +
                  if block_given?
         | 
| 117 | 
            +
                    Nokogiri::XML::Builder.with(rpc.at( toplevel )){ |xml|
         | 
| 118 | 
            +
                      yield( xml )
         | 
| 119 | 
            +
                    }
         | 
| 120 | 
            +
                  elsif config
         | 
| 121 | 
            +
                    rpc.at( toplevel ) << config.dup
         | 
| 122 | 
            +
                  else
         | 
| 123 | 
            +
                    raise ArgumentError, "You must specify edit-config data!"    
         | 
| 124 | 
            +
                  end                    
         | 
| 125 | 
            +
                  
         | 
| 126 | 
            +
                  Netconf::RPC.set_exception( rpc, Netconf::EditError )    
         | 
| 127 | 
            +
                  @trans.rpc_exec( rpc )      
         | 
| 128 | 
            +
                end    
         | 
| 129 | 
            +
                    
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              end # module: RPC  
         | 
| 133 | 
            +
            end # module: Netconf
         | 
    
        data/lib/net/netconf/serial.rb
    CHANGED
    
    | @@ -1,135 +1,135 @@ | |
| 1 | 
            -
            require 'serialport'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Netconf
         | 
| 4 | 
            -
              
         | 
| 5 | 
            -
              class Serial < Netconf::Transport
         | 
| 6 | 
            -
                
         | 
| 7 | 
            -
                DEFAULT_BAUD = 9600
         | 
| 8 | 
            -
                DEFAULT_DATABITS = 8
         | 
| 9 | 
            -
                DEFAULT_STOPBITS = 1
         | 
| 10 | 
            -
                DEFAULT_PARITY = SerialPort::NONE
         | 
| 11 | 
            -
                DEFAULT_RDBLKSZ = (1024*1024)
         | 
| 12 | 
            -
                
         | 
| 13 | 
            -
                attr_reader :args
         | 
| 14 | 
            -
                    
         | 
| 15 | 
            -
                def initialize( args_h, &block )
         | 
| 16 | 
            -
                  os_type = args_h[:os_type] || Netconf::DEFAULT_OS_TYPE
         | 
| 17 | 
            -
                  
         | 
| 18 | 
            -
                  raise Netconf::InitError, "Missing 'port' param" unless args_h[:port]
         | 
| 19 | 
            -
                  raise Netconf::InitError, "Missing 'username' param" unless args_h[:username]
         | 
| 20 | 
            -
                  
         | 
| 21 | 
            -
                  @args = args_h.clone
         | 
| 22 | 
            -
                  @args[:prompt] ||= /([%>])\s+$/
         | 
| 23 | 
            -
                    
         | 
| 24 | 
            -
                  # extend this instance with the capabilities of the specific console
         | 
| 25 | 
            -
                  # type; it needs to define #trans_start_netconf session
         | 
| 26 | 
            -
                  # this must be provided! if the caller does not, this will 
         | 
| 27 | 
            -
                  # throw a NameError exception.
         | 
| 28 | 
            -
                  
         | 
| 29 | 
            -
                  extend Netconf::const_get( os_type )::TransSerial        
         | 
| 30 | 
            -
                  
         | 
| 31 | 
            -
                  @trans_timeout = @args[:timeout] || Netconf::DEFAULT_TIMEOUT
         | 
| 32 | 
            -
                  @trans_waitio = @args[:waitio] || Netconf::DEFAULT_WAITIO
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                  super( &block )      
         | 
| 35 | 
            -
                end      
         | 
| 36 | 
            -
                
         | 
| 37 | 
            -
                def login
         | 
| 38 | 
            -
                  
         | 
| 39 | 
            -
                  begin
         | 
| 40 | 
            -
                    puts
         | 
| 41 | 
            -
                    waitfor(/ogin:/)
         | 
| 42 | 
            -
                  rescue Timeout::Error
         | 
| 43 | 
            -
                    puts
         | 
| 44 | 
            -
                    waitfor(/ogin:/)
         | 
| 45 | 
            -
                  end
         | 
| 46 | 
            -
                  
         | 
| 47 | 
            -
                  puts @args[:username]
         | 
| 48 | 
            -
                  
         | 
| 49 | 
            -
                  waitfor(/assword:/)
         | 
| 50 | 
            -
                  puts @args[:password]
         | 
| 51 | 
            -
                  
         | 
| 52 | 
            -
                  waitfor( @args[:prompt] )
         | 
| 53 | 
            -
                end
         | 
| 54 | 
            -
                
         | 
| 55 | 
            -
                def trans_open # :yield: self
         | 
| 56 | 
            -
                  
         | 
| 57 | 
            -
                  baud = @args[:speed] || DEFAULT_BAUD
         | 
| 58 | 
            -
                  data_bits = @args[:bits] || DEFAULT_DATABITS
         | 
| 59 | 
            -
                  stop_bits = @args[:stop] || DEFAULT_STOPBITS
         | 
| 60 | 
            -
                  parity = @args[:parity] || DEFAULT_PARITY
         | 
| 61 | 
            -
                  
         | 
| 62 | 
            -
                  @trans = SerialPort.new( @args[:port], baud, data_bits, stop_bits, parity )            
         | 
| 63 | 
            -
                        
         | 
| 64 | 
            -
                  got = login()      
         | 
| 65 | 
            -
                  yield self if block_given?      
         | 
| 66 | 
            -
                  trans_start_netconf( got )      
         | 
| 67 | 
            -
                  
         | 
| 68 | 
            -
                  self
         | 
| 69 | 
            -
                end
         | 
| 70 | 
            -
                
         | 
| 71 | 
            -
                def trans_receive_hello
         | 
| 72 | 
            -
                  hello_str = trans_receive()
         | 
| 73 | 
            -
                  so_xml = hello_str.index("\n") + 1
         | 
| 74 | 
            -
                  hello_str.slice!(0, so_xml)
         | 
| 75 | 
            -
                  hello_str
         | 
| 76 | 
            -
                end
         | 
| 77 | 
            -
                
         | 
| 78 | 
            -
                def trans_send_hello
         | 
| 79 | 
            -
                  nil
         | 
| 80 | 
            -
                end
         | 
| 81 | 
            -
                
         | 
| 82 | 
            -
                def trans_close
         | 
| 83 | 
            -
                  @trans.write Netconf::RPC::MSG_CLOSE_SESSION
         | 
| 84 | 
            -
                  @trans.close
         | 
| 85 | 
            -
                end
         | 
| 86 | 
            -
                
         | 
| 87 | 
            -
                def trans_send( cmd_str )
         | 
| 88 | 
            -
                  @trans.write( cmd_str )
         | 
| 89 | 
            -
                end
         | 
| 90 | 
            -
                
         | 
| 91 | 
            -
                def trans_receive
         | 
| 92 | 
            -
                  got = waitfor( Netconf::RPC::MSG_END_RE )
         | 
| 93 | 
            -
                  msg_end = got.rindex( Netconf::RPC::MSG_END )
         | 
| 94 | 
            -
                  got[msg_end .. -1] = ''
         | 
| 95 | 
            -
                  got
         | 
| 96 | 
            -
                end
         | 
| 97 | 
            -
                    
         | 
| 98 | 
            -
                def puts( str = nil )
         | 
| 99 | 
            -
                  @trans.puts str 
         | 
| 100 | 
            -
                end
         | 
| 101 | 
            -
                    
         | 
| 102 | 
            -
                def waitfor( this_re = nil )      
         | 
| 103 | 
            -
                  on_re = this_re || @args[:prompt]
         | 
| 104 | 
            -
                  
         | 
| 105 | 
            -
                  time_out = @trans_timeout
         | 
| 106 | 
            -
                  wait_io = @trans_waitio
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                  time_out = nil if time_out == false
         | 
| 109 | 
            -
                  done = false
         | 
| 110 | 
            -
                  rx_buf = ''      
         | 
| 111 | 
            -
                              
         | 
| 112 | 
            -
                  until( rx_buf.match( on_re ) and not IO::select( [@trans], nil, nil, wait_io ) )
         | 
| 113 | 
            -
                          
         | 
| 114 | 
            -
                    unless IO::select( [@trans], nil, nil, time_out )
         | 
| 115 | 
            -
                      raise TimeoutError, "Netconf IO timed out while waiting for more data"
         | 
| 116 | 
            -
                    end
         | 
| 117 | 
            -
                  
         | 
| 118 | 
            -
                    begin                   
         | 
| 119 | 
            -
                      
         | 
| 120 | 
            -
                      rx_some = @trans.readpartial( DEFAULT_RDBLKSZ )                       
         | 
| 121 | 
            -
                      
         | 
| 122 | 
            -
                      rx_buf += rx_some
         | 
| 123 | 
            -
                      break if rx_buf.match( on_re )
         | 
| 124 | 
            -
                      
         | 
| 125 | 
            -
                    rescue EOFError # End of file reached
         | 
| 126 | 
            -
                      rx_buf = nil if rx_buf == ''
         | 
| 127 | 
            -
                      break   # out of outer 'until' loop
         | 
| 128 | 
            -
                    end        
         | 
| 129 | 
            -
                    
         | 
| 130 | 
            -
                  end      
         | 
| 131 | 
            -
                  rx_buf
         | 
| 132 | 
            -
                end     
         | 
| 133 | 
            -
                
         | 
| 134 | 
            -
              end # class: Serial
         | 
| 135 | 
            -
            end # module: Netconf
         | 
| 1 | 
            +
            require 'serialport'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Netconf
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              class Serial < Netconf::Transport
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                DEFAULT_BAUD = 9600
         | 
| 8 | 
            +
                DEFAULT_DATABITS = 8
         | 
| 9 | 
            +
                DEFAULT_STOPBITS = 1
         | 
| 10 | 
            +
                DEFAULT_PARITY = SerialPort::NONE
         | 
| 11 | 
            +
                DEFAULT_RDBLKSZ = (1024*1024)
         | 
| 12 | 
            +
                
         | 
| 13 | 
            +
                attr_reader :args
         | 
| 14 | 
            +
                    
         | 
| 15 | 
            +
                def initialize( args_h, &block )
         | 
| 16 | 
            +
                  os_type = args_h[:os_type] || Netconf::DEFAULT_OS_TYPE
         | 
| 17 | 
            +
                  
         | 
| 18 | 
            +
                  raise Netconf::InitError, "Missing 'port' param" unless args_h[:port]
         | 
| 19 | 
            +
                  raise Netconf::InitError, "Missing 'username' param" unless args_h[:username]
         | 
| 20 | 
            +
                  
         | 
| 21 | 
            +
                  @args = args_h.clone
         | 
| 22 | 
            +
                  @args[:prompt] ||= /([%>])\s+$/
         | 
| 23 | 
            +
                    
         | 
| 24 | 
            +
                  # extend this instance with the capabilities of the specific console
         | 
| 25 | 
            +
                  # type; it needs to define #trans_start_netconf session
         | 
| 26 | 
            +
                  # this must be provided! if the caller does not, this will 
         | 
| 27 | 
            +
                  # throw a NameError exception.
         | 
| 28 | 
            +
                  
         | 
| 29 | 
            +
                  extend Netconf::const_get( os_type )::TransSerial        
         | 
| 30 | 
            +
                  
         | 
| 31 | 
            +
                  @trans_timeout = @args[:timeout] || Netconf::DEFAULT_TIMEOUT
         | 
| 32 | 
            +
                  @trans_waitio = @args[:waitio] || Netconf::DEFAULT_WAITIO
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  super( &block )      
         | 
| 35 | 
            +
                end      
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                def login
         | 
| 38 | 
            +
                  
         | 
| 39 | 
            +
                  begin
         | 
| 40 | 
            +
                    puts
         | 
| 41 | 
            +
                    waitfor(/ogin:/)
         | 
| 42 | 
            +
                  rescue Timeout::Error
         | 
| 43 | 
            +
                    puts
         | 
| 44 | 
            +
                    waitfor(/ogin:/)
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                  
         | 
| 47 | 
            +
                  puts @args[:username]
         | 
| 48 | 
            +
                  
         | 
| 49 | 
            +
                  waitfor(/assword:/)
         | 
| 50 | 
            +
                  puts @args[:password]
         | 
| 51 | 
            +
                  
         | 
| 52 | 
            +
                  waitfor( @args[:prompt] )
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
                
         | 
| 55 | 
            +
                def trans_open # :yield: self
         | 
| 56 | 
            +
                  
         | 
| 57 | 
            +
                  baud = @args[:speed] || DEFAULT_BAUD
         | 
| 58 | 
            +
                  data_bits = @args[:bits] || DEFAULT_DATABITS
         | 
| 59 | 
            +
                  stop_bits = @args[:stop] || DEFAULT_STOPBITS
         | 
| 60 | 
            +
                  parity = @args[:parity] || DEFAULT_PARITY
         | 
| 61 | 
            +
                  
         | 
| 62 | 
            +
                  @trans = SerialPort.new( @args[:port], baud, data_bits, stop_bits, parity )            
         | 
| 63 | 
            +
                        
         | 
| 64 | 
            +
                  got = login()      
         | 
| 65 | 
            +
                  yield self if block_given?      
         | 
| 66 | 
            +
                  trans_start_netconf( got )      
         | 
| 67 | 
            +
                  
         | 
| 68 | 
            +
                  self
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
                
         | 
| 71 | 
            +
                def trans_receive_hello
         | 
| 72 | 
            +
                  hello_str = trans_receive()
         | 
| 73 | 
            +
                  so_xml = hello_str.index("\n") + 1
         | 
| 74 | 
            +
                  hello_str.slice!(0, so_xml)
         | 
| 75 | 
            +
                  hello_str
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
                
         | 
| 78 | 
            +
                def trans_send_hello
         | 
| 79 | 
            +
                  nil
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
                
         | 
| 82 | 
            +
                def trans_close
         | 
| 83 | 
            +
                  @trans.write Netconf::RPC::MSG_CLOSE_SESSION
         | 
| 84 | 
            +
                  @trans.close
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
                
         | 
| 87 | 
            +
                def trans_send( cmd_str )
         | 
| 88 | 
            +
                  @trans.write( cmd_str )
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
                
         | 
| 91 | 
            +
                def trans_receive
         | 
| 92 | 
            +
                  got = waitfor( Netconf::RPC::MSG_END_RE )
         | 
| 93 | 
            +
                  msg_end = got.rindex( Netconf::RPC::MSG_END )
         | 
| 94 | 
            +
                  got[msg_end .. -1] = ''
         | 
| 95 | 
            +
                  got
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
                    
         | 
| 98 | 
            +
                def puts( str = nil )
         | 
| 99 | 
            +
                  @trans.puts str 
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
                    
         | 
| 102 | 
            +
                def waitfor( this_re = nil )      
         | 
| 103 | 
            +
                  on_re = this_re || @args[:prompt]
         | 
| 104 | 
            +
                  
         | 
| 105 | 
            +
                  time_out = @trans_timeout
         | 
| 106 | 
            +
                  wait_io = @trans_waitio
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  time_out = nil if time_out == false
         | 
| 109 | 
            +
                  done = false
         | 
| 110 | 
            +
                  rx_buf = ''      
         | 
| 111 | 
            +
                              
         | 
| 112 | 
            +
                  until( rx_buf.match( on_re ) and not IO::select( [@trans], nil, nil, wait_io ) )
         | 
| 113 | 
            +
                          
         | 
| 114 | 
            +
                    unless IO::select( [@trans], nil, nil, time_out )
         | 
| 115 | 
            +
                      raise TimeoutError, "Netconf IO timed out while waiting for more data"
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
                  
         | 
| 118 | 
            +
                    begin                   
         | 
| 119 | 
            +
                      
         | 
| 120 | 
            +
                      rx_some = @trans.readpartial( DEFAULT_RDBLKSZ )                       
         | 
| 121 | 
            +
                      
         | 
| 122 | 
            +
                      rx_buf += rx_some
         | 
| 123 | 
            +
                      break if rx_buf.match( on_re )
         | 
| 124 | 
            +
                      
         | 
| 125 | 
            +
                    rescue EOFError # End of file reached
         | 
| 126 | 
            +
                      rx_buf = nil if rx_buf == ''
         | 
| 127 | 
            +
                      break   # out of outer 'until' loop
         | 
| 128 | 
            +
                    end        
         | 
| 129 | 
            +
                    
         | 
| 130 | 
            +
                  end      
         | 
| 131 | 
            +
                  rx_buf
         | 
| 132 | 
            +
                end     
         | 
| 133 | 
            +
                
         | 
| 134 | 
            +
              end # class: Serial
         | 
| 135 | 
            +
            end # module: Netconf
         |