Class: Cisco::Client::NXAPI

Inherits:
Cisco::Client show all
Defined in:
lib/cisco_node_utils/client/nxapi.rb,
lib/cisco_node_utils/client/nxapi/client.rb

Overview

Class representing an HTTP client connecting to a NXAPI server.

Constant Summary collapse

NXAPI_UDS =

Location of unix domain socket for NXAPI localhost

'/tmp/nginx_local/nginx_1_be_nxapi.sock'
NXAPI_REMOTE_URI_PATH =

NXAPI listens for remote connections to “http://<switch IP>/ins” NXAPI listens for local connections to “http://<UDS>/ins_local”

'/ins'
NXAPI_UDS_URI_PATH =
'/ins_local'
NXAPI_VERSION =

Latest supported version is 1.0

'1.0'

Instance Attribute Summary

Attributes inherited from Cisco::Client

#cache_auto, #data_formats, #platform

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Cisco::Client

#cache_auto?, #cache_enable=, #cache_enable?, clients, create, filter_cli, filter_data, find_subconfig, handle_errors, #inspect, #munge_to_array, munge_to_array, register_client, silence_warnings, #supports?, to_regexp, #to_s

Constructor Details

#initialize(**kwargs) ⇒ NXAPI

Constructor for Client. By default this connects to the local unix domain socket. If you need to connect to a remote device, you must provide the host/username/password parameters.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/cisco_node_utils/client/nxapi/client.rb', line 41

def initialize(**kwargs)
  # rubocop:disable Style/HashSyntax
  super(data_formats: [:nxapi_structured, :cli],
        platform:     :nexus,
        **kwargs)
  # rubocop:enable Style/HashSyntax
  # Default: connect to unix domain socket on localhost, if available
  if @host.nil?
    unless File.socket?(NXAPI_UDS)
      fail Cisco::ConnectionRefused, \
           "No host specified but no UDS found at #{NXAPI_UDS} either"
    end
    # net_http_unix provides NetX::HTTPUnix, a small subclass of Net::HTTP
    # which supports connection to local unix domain sockets. We need this
    # in order to run natively under NX-OS but it's not needed for off-box
    # unit testing where the base Net::HTTP will meet our needs.
    require 'net_http_unix'
    @http = NetX::HTTPUnix.new('unix://' + NXAPI_UDS)
    @cookie = kwargs[:cookie]
  else
    # Remote connection. This is primarily expected
    # when running e.g. from a Unix server as part of Minitest.
    @transport = kwargs[:transport] || 'http'
    @verify_mode = kwargs[:verify_mode] || 'none'
    @port.nil? ? @port = '' : @port = ":#{@port}"
    uri = URI.parse("#{@transport}://#{@host}#{@port}")
    @http = Net::HTTP.new(uri.host, uri.port)
  end
  # The default read time out is 60 seconds, which may be too short for
  # scaled configuration to apply. Change it to 300 seconds, which is
  # also used as the default config by firefox.
  @http.read_timeout = 300
  @address = @http.address
end

Class Method Details

.validate_args(**kwargs) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/cisco_node_utils/client/nxapi/client.rb', line 76

def self.validate_args(**kwargs)
  super
  if kwargs[:host].nil?
    # Connection to UDS - no username or password either
    fail ArgumentError unless kwargs[:username].nil? && kwargs[:password].nil?
    validate_cookie(**kwargs)
  else
    # Connection to remote system - username and password are required
    fail TypeError, 'username is required' if kwargs[:username].nil?
    fail TypeError, 'password is required' if kwargs[:password].nil?
  end
end


89
90
91
92
93
94
95
96
97
# File 'lib/cisco_node_utils/client/nxapi/client.rb', line 89

def self.validate_cookie(**kwargs)
  return if kwargs[:cookie].nil?
  format = 'Cookie format must match: <username>:local'
  msg = "Invalid cookie: [#{kwargs[:cookie]}]. : #{format}"

  fail TypeError, msg unless kwargs[:cookie].is_a?(String)
  fail TypeError, msg unless /\S+:local/.match(kwargs[:cookie])
  fail ArgumentError, 'empty cookie' if kwargs[:cookie].empty?
end

Instance Method Details

#cache_flushObject

Clear the cache of CLI output results.

If cache_auto is true (default) then this will be performed automatically whenever a set() is called, but providers may also call this to explicitly force the cache to be cleared.



104
105
106
107
108
109
110
# File 'lib/cisco_node_utils/client/nxapi/client.rb', line 104

def cache_flush
  @cache_hash = {
    'cli_conf'       => {},
    'cli_show'       => {},
    'cli_show_ascii' => {},
  }
end

#get(data_format: :cli, command: nil, context: nil, value: nil, **_kwargs) ⇒ String, Hash

Get the given state from the device.

Unlike set() this will not clear the CLI cache; multiple calls with the same parameters may return cached data rather than querying the device repeatedly.

Parameters:

  • data_format (defaults to: :cli)

    one of Cisco::DATA_FORMATS. Default is :cli

  • command (String) (defaults to: nil)

    the show command to execute

  • context (String, Array<String>) (defaults to: nil)

    Context to refine the results

  • value (String) (defaults to: nil)

    Specific key to look up

  • kwargs

    data-format-specific args

Returns:

  • (String, Hash)

Raises:



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/cisco_node_utils/client/nxapi/client.rb', line 150

def get(data_format: :cli,
        command:     nil,
        context:     nil,
        value:       nil,
        **_kwargs)
  context = munge_to_array(context)
  super
  if data_format == :cli
    output = req('cli_show_ascii', command)
    return self.class.filter_cli(cli_output: output,
                                 context:    context,
                                 value:      value)
  elsif data_format == :nxapi_structured
    output = req('cli_show', command)
    return self.class.filter_data(data: output,
                                  keys: context + munge_to_array(value))
  else
    fail TypeError
  end
end

#read_timeout_check(request) ⇒ Object

Helper method to increase the default @http.read_timeout value from the default value of 300 to accomodate commands that are known to require more time to complete.



174
175
176
177
178
# File 'lib/cisco_node_utils/client/nxapi/client.rb', line 174

def read_timeout_check(request)
  return unless request.body[/install all|install force-all/]
  debug("Increasing http read_timeout to 1000 for 'install all' command")
  @http.read_timeout = 1000
end

#set(data_format: :cli, context: nil, values: nil, **_kwargs) ⇒ Object

Configure the given CLI command(s) on the device.

Parameters:

  • data_format (defaults to: :cli)

    one of Cisco::DATA_FORMATS. Default is :cli

  • context (String, Array<String>) (defaults to: nil)

    Zero or more configuration commands used to enter the desired CLI sub-mode

  • values (String, Array<String>) (defaults to: nil)

    One or more commands to enter within the CLI sub-mode.

  • kwargs

    data-format-specific args

Raises:



122
123
124
125
126
127
128
129
130
131
132
# File 'lib/cisco_node_utils/client/nxapi/client.rb', line 122

def set(data_format: :cli,
        context: nil,
        values: nil,
        **_kwargs)
  # we don't currently support nxapi_structured for configuration
  fail Cisco::RequestNotSupported if data_format == :nxapi_structured
  context = munge_to_array(context)
  values = munge_to_array(values)
  super
  req('cli_conf', context + values)
end