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

Returns a new instance of Transport.



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

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.



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

def capabilities
  @capabilities
end

#rpcObject (readonly)

Returns the value of attribute rpc.



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

def rpc
  @rpc
end

#session_idObject (readonly)

Returns the value of attribute session_id.



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

def session_id
  @session_id
end

#stateObject (readonly)

Returns the value of attribute state.



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

def state
  @state
end

#timeout=(value) ⇒ Object (writeonly)

Sets the attribute timeout

Parameters:

  • value

    the value to set the attribute timeout to.



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

def timeout=(value)
  @timeout = value
end

#waitio=(value) ⇒ Object (writeonly)

Sets the attribute waitio

Parameters:

  • value

    the value to set the attribute waitio to.



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

def waitio=(value)
  @waitio = value
end

Instance Method Details

#closeObject



77
78
79
80
81
82
# File 'lib/net/netconf/transport.rb', line 77

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

#closed?Boolean

Returns:

  • (Boolean)


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

def closed?
  @state == :NECONF_CLOSED
end

#has_capability?(capability) ⇒ Boolean

Returns:

  • (Boolean)


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

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



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

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

Returns:

  • (Boolean)


32
33
34
# File 'lib/net/netconf/transport.rb', line 32

def open?
  @state == :NETCONF_OPEN
end

#rpc_exec(cmd_nx) ⇒ Object



91
92
93
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
# File 'lib/net/netconf/transport.rb', line 91

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



85
86
87
88
89
# File 'lib/net/netconf/transport.rb', line 85

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

#trans_receive_helloObject



63
64
65
# File 'lib/net/netconf/transport.rb', line 63

def trans_receive_hello
  trans_receive()
end

#trans_send_helloObject



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

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