class PuppetX::Eos::Eapi

Eapi class

Constants

SOCKET_PATH

The default path to the EOS command api unix domain socket.

Attributes

enable_pwd[R]
hostname[R]
password[R]
port[R]
socket[R]
uri[R]
use_ssl[R]
username[R]

Public Class Methods

new(opts = {}) click to toggle source

Initialize an instance of Eapi. This class provides direct API connectivity to command API running on Arista EOS switches. This class will send and receive eAPI calls using JSON-RPC over HTTP/S. Each option has a corresponding environment variable which will override the options hash if defined.

@param [Hash] opts The eAPI configuration options

@option opts [String] :hostname (EOS_HOSTNAME) Hostname or IP address

of eAPI endpoint.

@option opts [String] :username (EOS_USERNAME) eAPI username @option opts [String] :password (EOS_PASSWORD) eAPI password @option opts [String] :enable_pwd (EOS_ENABLE_PASSWORD) Enable mode

password

@option opts [Boolean] :use_ssl (EOS_USE_SSL) eAPI protocol @option opts [Integer] :port (EOS_PORT) eAPI port @option opts [String] :socket (‘/var/run/command-api.sock’) Initialize

an HTTP client using a unix domain socket.  This option will negate
the :hostname, :port, :username, :password, :port, and :use_ssl
options

@return [Eos::Eapi] instance of Eos::Eapi

# File lib/puppet_x/eos/eapi.rb, line 87
def initialize(opts = {})
  @hostname = ENV['EOS_HOSTNAME'] || opts[:hostname] || 'localhost'
  @username = ENV['EOS_USERNAME'] || opts[:username] || 'admin'
  @password = ENV['EOS_PASSWORD'] || opts[:password] || ''
  @enable_pwd = ENV['EOS_ENABLE_PASSWORD'] || opts[:enable_pwd] || ''
  use_ssl = (ENV['EOS_USE_SSL'] || opts[:use_ssl]) ? true : false
  @protocol = use_ssl ? 'https' : 'http'
  port = (ENV['EOS_PORT'] || opts[:port]) || (use_ssl ? '443' : '80')
  @port = port.to_i
  unless ENV['EOS_DISABLE_SOCKET']
    @socket = ENV['EOS_SOCKET_PATH'] || opts[:socket]
    unless @socket
      sock_path = Pathname.new(SOCKET_PATH)
      if sock_path.socket? && sock_path.readable? && sock_path.writable?
        @socket = SOCKET_PATH
      end
    end
  end
end

Public Instance Methods

config(commands) click to toggle source

The config method is a convenience method that will handling putting the switch into config mode prior to executing commands. The method will insert ‘config’ at the top of the command stack and then pop the empty hash from the response output before return the array to the caller

@param [Array<String>] commands An ordered list of commands to execute

@return [Array<Hash>] ordered list of output from commands

# File lib/puppet_x/eos/eapi.rb, line 224
def config(commands)
  commands = [*commands] unless commands.respond_to?('each')
  commands.insert(0, 'configure')
  begin
    result = enable(commands)
    result.shift
    result
  rescue
    return nil
  end
end
enable(commands, options = {}) click to toggle source

The enable method is a convenience method that will handling putting the switch into priviledge mode prior to executing commands.

@param [Array<String>] commands An ordered list of commands to execute

@return [Array<Hash>] ordered list of output from commands

# File lib/puppet_x/eos/eapi.rb, line 210
def enable(commands, options = {})
  execute([*commands], options)
end
execute(commands, options = {}) click to toggle source

The execute method takes the array of commands and inserts the ‘enable’ command to make certain the commands are executed in priviledged mode. If an enable password is needed, it is inserted into the command stack as well. Since the enable command will generate an empty hash on the response, it is popped off before returning the array of hashes

@param [Array<String>] ordered list of commands to insert into the

POST request

@return [Array<Hash>] ordered list of output from the command

@raise [Eos::Eapi::CommandError] if the response from invoke contains

the key error
# File lib/puppet_x/eos/eapi.rb, line 191
def execute(commands, options = {})
  modified_commands = [{cmd: 'enable', input: @enable_pwd}, *commands]
  resp = invoke(request(modified_commands, options))
  if resp['error']
    data = resp['error']['data']
    fail ApiError, "command #{commands.inspect} failed: #{format_error(data)}"
  end
  result = resp['result']
  result.shift
  result
end
http() click to toggle source

http returns a memoized HTTP object instance

@return [Net::Http] http client

# File lib/puppet_x/eos/eapi.rb, line 120
def http
  return @http if @http
  if @socket
    @http = NetX::HTTPUnix.new("unix://#{@socket}")
  else
    @http = Net::HTTP.new(uri.host, uri.port)
  end
end
invoke(body) click to toggle source

The invoke method takes the JSON formatted message and sends it to the eAPI end point. The response return value from command API is parsed from JSON and returned as an array of hashes with the output for each command

@param [Array<String>] ordered list of commands to send to the host

return [Array<Hash>] ordered list of ouput from the command execution

# File lib/puppet_x/eos/eapi.rb, line 168
def invoke(body)
  request = Net::HTTP::Post.new('/command-api')
  request.body = JSON.dump(body)
  request.basic_auth @username, @password
  response = http.request(request)
  JSON(response.body)
end
method_missing(name) click to toggle source

Autloads an eAPI provider module for working with EOS objects

@return [Object]

# File lib/puppet_x/eos/eapi.rb, line 133
def method_missing(name)
  name = "PuppetX::Eos::#{name}"
  klass = name.split('::').inject(Object) { |a, e| a.const_get e }
  klass.new self
end
request(command, params = {}) click to toggle source

The request method converts an array of commands to a valid eAPI request hash. The request message can be then sent to the eAPI end point using JSON-RPC over HTTP/S. eAPI exposes a single method, runCmds.

@param [Array<String>] command An array of commands to be inserted

@return [Hash] returns a hash that can be serialized to JSON and sent

to the command API end point
# File lib/puppet_x/eos/eapi.rb, line 149
def request(command, params = {})
  # id = params[:id] || SecureRandom.uuid
  id = 1
  format = params[:format] || 'json'
  cmds = [*command]
  params = { 'version' => 1, 'cmds' => cmds, 'format' => format }
  { 'jsonrpc' => '2.0', 'method' => 'runCmds',
    'params' => params, 'id' => id }
end

Private Instance Methods

format_error(data) click to toggle source

format_error takes the value of the ‘error’ key from the EOS API response and formats the error strings into a string suitable for error messages.

@param [Array<Hash>] data Array of data from the API response, this

will be lcoated in the sub-key api_response['error']['data']

@api private

@return [String] the human readable error message

# File lib/puppet_x/eos/eapi.rb, line 247
def format_error(data)
  if data
    data.each_with_object([]) do |i, ary|
      ary.push(*i['errors']) if i['errors']
    end.join(', ')
  else
    'unknown error'
  end
end