Class: PuppetX::Eos::Eapi

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet_x/eos/eapi.rb

Overview

Eapi class

Defined Under Namespace

Classes: ApiError

Constant Summary collapse

SOCKET_PATH =

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

'/var/run/command-api.sock'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Eos::Eapi

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.

Parameters:

  • opts (Hash) (defaults to: {})

    The eAPI configuration options

Options Hash (opts):

  • :hostname (String) — default: EOS_HOSTNAME

    Hostname or IP address of eAPI endpoint.

  • :username (String) — default: EOS_USERNAME

    eAPI username

  • :password (String) — default: EOS_PASSWORD

    eAPI password

  • :enable_pwd (String) — default: EOS_ENABLE_PASSWORD

    Enable mode password

  • :use_ssl (Boolean) — default: EOS_USE_SSL

    eAPI protocol

  • :port (Integer) — default: EOS_PORT

    eAPI port

  • :socket (String) — default: '/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



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# 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

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name) ⇒ Object

Autloads an eAPI provider module for working with EOS objects

Returns:

  • (Object)


133
134
135
136
137
# 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

Instance Attribute Details

#enable_pwdObject (readonly)

Returns the value of attribute enable_pwd.



53
54
55
# File 'lib/puppet_x/eos/eapi.rb', line 53

def enable_pwd
  @enable_pwd
end

#hostnameObject (readonly)

Returns the value of attribute hostname.



49
50
51
# File 'lib/puppet_x/eos/eapi.rb', line 49

def hostname
  @hostname
end

#passwordObject (readonly)

Returns the value of attribute password.



52
53
54
# File 'lib/puppet_x/eos/eapi.rb', line 52

def password
  @password
end

#portObject (readonly)

Returns the value of attribute port.



50
51
52
# File 'lib/puppet_x/eos/eapi.rb', line 50

def port
  @port
end

#socketObject (readonly)

Returns the value of attribute socket.



56
57
58
# File 'lib/puppet_x/eos/eapi.rb', line 56

def socket
  @socket
end

#uriUri (readonly)

uri returns a URI object

Returns:

  • (Uri)


111
112
113
# File 'lib/puppet_x/eos/eapi.rb', line 111

def uri
  @uri
end

#use_sslObject (readonly)

Returns the value of attribute use_ssl.



54
55
56
# File 'lib/puppet_x/eos/eapi.rb', line 54

def use_ssl
  @use_ssl
end

#usernameObject (readonly)

Returns the value of attribute username.



51
52
53
# File 'lib/puppet_x/eos/eapi.rb', line 51

def username
  @username
end

Instance Method Details

#config(commands) ⇒ Array<Hash>

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

Parameters:

  • commands (Array<String>)

    An ordered list of commands to execute

Returns:

  • (Array<Hash>)

    ordered list of output from commands



224
225
226
227
228
229
230
231
232
233
234
# 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 = {}) ⇒ Array<Hash>

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

Parameters:

  • commands (Array<String>)

    An ordered list of commands to execute

Returns:

  • (Array<Hash>)

    ordered list of output from commands



210
211
212
# File 'lib/puppet_x/eos/eapi.rb', line 210

def enable(commands, options = {})
  execute([*commands], options)
end

#execute(commands, options = {}) ⇒ Array<Hash>

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

Parameters:

  • ordered (Array<String>)

    list of commands to insert into the POST request

Returns:

  • (Array<Hash>)

    ordered list of output from the command

Raises:

  • (Eos::Eapi::CommandError)

    if the response from invoke contains the key error



191
192
193
194
195
196
197
198
199
200
201
# 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

#httpNet::Http

http returns a memoized HTTP object instance

Returns:

  • (Net::Http)

    http client



120
121
122
123
124
125
126
127
# 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) ⇒ Object

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

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

Parameters:

  • ordered (Array<String>)

    list of commands to send to the host



168
169
170
171
172
173
174
# 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

#request(command, params = {}) ⇒ Hash

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.

Parameters:

  • command (Array<String>)

    An array of commands to be inserted

Returns:

  • (Hash)

    returns a hash that can be serialized to JSON and sent to the command API end point



149
150
151
152
153
154
155
156
157
# 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