Class: Netconf::Transport

Inherits:
Object
  • Object
show all
Defined in:
lib/net/netconf/transport.rb

Direct Known Subclasses

IOProc, SSH, Serial, Telnet

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ Transport


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/net/netconf/transport.rb', line 19

def initialize( &block ) 
  
  @state = :NETCONF_CLOSED
  @os_type = @args[:os_type] || Netconf::DEFAULT_OS_TYPE
        
  @rpc = Netconf::RPC::Executor.new( self, @os_type )
  @rpc_message_id = 1
  
  if block_given?
    open( &block = nil )      # do not pass this block to open()
    yield self
    close()
  end
  
end

Instance Attribute Details

#capabilitiesObject (readonly)

Returns the value of attribute capabilities


16
17
18
# File 'lib/net/netconf/transport.rb', line 16

def capabilities
  @capabilities
end

#rpcObject (readonly)

Returns the value of attribute rpc


16
17
18
# File 'lib/net/netconf/transport.rb', line 16

def rpc
  @rpc
end

#session_idObject (readonly)

Returns the value of attribute session_id


16
17
18
# File 'lib/net/netconf/transport.rb', line 16

def session_id
  @session_id
end

#stateObject (readonly)

Returns the value of attribute state


16
17
18
# File 'lib/net/netconf/transport.rb', line 16

def state
  @state
end

#timeout=(value) ⇒ Object (writeonly)

Sets the attribute timeout


17
18
19
# File 'lib/net/netconf/transport.rb', line 17

def timeout=(value)
  @timeout = value
end

#waitio=(value) ⇒ Object (writeonly)

Sets the attribute waitio


17
18
19
# File 'lib/net/netconf/transport.rb', line 17

def waitio=(value)
  @waitio = value
end

Instance Method Details

#closeObject


80
81
82
83
84
85
# File 'lib/net/netconf/transport.rb', line 80

def close
  raise Netconf::StateError unless @state == :NETCONF_OPEN         
  trans_close()
  @state = :NETCONF_CLOSED            
  self
end

#closed?Boolean


39
40
41
# File 'lib/net/netconf/transport.rb', line 39

def closed?
  @state == :NECONF_CLOSED
end

#has_capability?(capability) ⇒ Boolean


75
76
77
78
# File 'lib/net/netconf/transport.rb', line 75

def has_capability?( capability )
  @capabilities.select{|c| c.include? capability }.pop
  # note: the caller could also simply use #grep on @capabilities
end

#open(&block) ⇒ Object

:yield: specialized transport open, generally not used


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/net/netconf/transport.rb', line 43

def open( &block ) # :yield: specialized transport open, generally not used
  
  raise Netconf::StateError if @state == :NETCONF_OPEN
  
  # block is used to deal with special open processing ...
  # this is *NOT* the block passed to initialize()
  raise Netconf::OpenError unless trans_open( &block )      
        
  # read the <hello> from the server and parse out
  # the capabilities and session-id
  
  hello_rsp = Nokogiri::XML( trans_receive_hello() )
  hello_rsp.remove_namespaces!
        
  @capabilities = hello_rsp.xpath('//capability').map{ |c| c.text }
  @session_id = hello_rsp.xpath('//session-id').text
        
  # send the <hello> 
  trans_send_hello()
  
  @state = :NETCONF_OPEN            
  self      
end

#open?Boolean

initialize


35
36
37
# File 'lib/net/netconf/transport.rb', line 35

def open?
  @state == :NETCONF_OPEN
end

#rpc_exec(cmd_nx) ⇒ Object


94
95
96
97
98
99
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/net/netconf/transport.rb', line 94

def rpc_exec( cmd_nx )
  raise Netconf::StateError unless @state == :NETCONF_OPEN         
  
  # add the mandatory message-id and namespace to the RPC
  
  rpc_nx = cmd_nx.parent.root
  rpc_nx.default_namespace = Netconf::NAMESPACE
  rpc_nx['message-id'] = @rpc_message_id.to_s
  @rpc_message_id += 1
  
  # send the XML command through the transport and 
  # receive the response; then covert it to a Nokogiri XML
  # object so we can process it.
  
  rsp_nx = Nokogiri::XML( send_and_receive( cmd_nx.to_xml ))
  
  # the following removes only the default namespace (xmlns)
  # definitions from the document.  This is an alternative
  # to using #remove_namespaces! which would remove everything
  # including vendor specific namespaces.  So this approach is a 
  # nice "compromise" ... just don't know what it does 
  # performance-wise on large datasets.

  rsp_nx.traverse{ |n| n.namespace = nil }
  
  # set the response context to the root node; <rpc-reply>
  
  rsp_nx = rsp_nx.root
        
  # check for rpc-error elements.  these could be
  # located anywhere in the structured response
  
  rpc_errs = rsp_nx.xpath('//self::rpc-error')
  if rpc_errs.count > 0
    
    # look for rpc-errors that have a severity == 'error'
    # in some cases the rpc-error is generated with
    # severity == 'warning'
    
    sev_err = rpc_errs.xpath('error-severity[. = "error"]')
    
    # if there are rpc-error with severity == 'error'
    # or if the caller wants to raise if severity == 'warning'
    # then generate the exception
    
    if(( sev_err.count > 0 ) || Netconf::raise_on_warning )
      exception = Netconf::RPC.get_exception( cmd_nx )       
      raise exception.new( self, cmd_nx, rsp_nx )
    end        
  end        
  
  # return the XML with context at toplevel element; i.e.
  # after the <rpc-reply> element
  # @@@/JLS: might this be <ok> ? isn't for Junos, but need to check
  # @@@/JLS: the generic case.
  
  rsp_nx.first_element_child
  
end

#send_and_receive(cmd_str) ⇒ Object

string in; string out


88
89
90
91
92
# File 'lib/net/netconf/transport.rb', line 88

def send_and_receive( cmd_str )
  trans_send( cmd_str )
  trans_send( RPC::MSG_END )
  trans_receive()
end

#trans_receive_helloObject


67
68
69
# File 'lib/net/netconf/transport.rb', line 67

def trans_receive_hello
  trans_receive()
end

#trans_send_helloObject


71
72
73
# File 'lib/net/netconf/transport.rb', line 71

def trans_send_hello
  trans_send( Netconf::RPC::MSG_HELLO )
end