class PuppetX::Eos::Eapi
Eapi
class
Constants
- SOCKET_PATH
The default path to the EOS command api unix domain socket.
Attributes
Public Class Methods
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
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
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
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 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
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
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
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
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