Class: Rbeapi::Netdev::Snmp

Inherits:
Api::Entity show all
Defined in:
lib/rbeapi/netdev/snmp.rb

Overview

The Netdev class is a straight port of the original PuppetX netdev code that existed prior to rbeapi. This should be considered a legacy implementation that will go away as the functions get merged into rbeapi.

This class should NOT be used for any further development. YE BE WARNED!

Constant Summary collapse

SNMP_USER_PARAM =

Map SNMP headings from `show snmp user` to snmp_user parameter names

{
  user: :name,
  engine: :engine_id,
  security: :version,
  authentication: :auth,
  privacy: :privacy,
  group: :roles
}

Instance Attribute Summary

Attributes inherited from Api::Entity

#config, #error, #node

Instance Method Summary collapse

Methods inherited from Api::Entity

#configure, #get_block, #initialize, instance

Constructor Details

This class inherits a constructor from Rbeapi::Api::Entity

Instance Method Details

#parse_snmp_hosts(text) ⇒ Array<Hash<Symbol,Object>>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

parse_snmp_hosts parses the raw text from the `show snmp host` command and returns an Array of resource hashes.

rubocop:disable Metrics/MethodLength

Parameters:

  • text (String)

    The text of the `show snmp host` output, e.g. for three hosts:

    “` Notification host: 127.0.0.1 udp-port: 162 type: trap user: public security model: v3 noauth

    Notification host: 127.0.0.1 udp-port: 162 type: trap user: smtpuser security model: v3 auth

    Notification host: 127.0.0.2 udp-port: 162 type: trap user: private security model: v2c

    Notification host: 127.0.0.3 udp-port: 162 type: trap user: public security model: v1

    Notification host: 127.0.0.4 udp-port: 10162 type: inform user: private security model: v2c

    Notification host: 127.0.0.4 udp-port: 162 type: trap user: [email protected] security model: v1

    Notification host: 127.0.0.4 udp-port: 162 type: trap user: public security model: v1

    Notification host: 127.0.0.4 udp-port: 20162 type: trap user: private security model: v1

    “`

Returns:

  • (Array<Hash<Symbol,Object>>)

    Array of resource hashes.


103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/rbeapi/netdev/snmp.rb', line 103

def parse_snmp_hosts(text)
  re = /host: ([^\s]+)\s+.*?port: (\d+)\s+type: (\w+)\s*user: (.*?)\s+security model: (.*?)\n/m # rubocop:disable Metrics/LineLength
  text.scan(re).map do |(host, port, type, username, auth)|
    resource_hash = { name: host, ensure: :present, port: port.to_i }
    sec_match = /^v3 (\w+)/.match(auth)
    resource_hash[:security] = sec_match[1] if sec_match
    ver_match = /^(v\d)/.match(auth) # first 2 characters
    resource_hash[:version] = ver_match[1] if ver_match
    resource_hash[:type] = /trap/.match(type) ? :traps : :informs
    resource_hash[:username] = username
    resource_hash
  end
end

#parse_snmp_users(text) ⇒ Array<Hash<Symbol,Object>>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

parse_snmp_users takes the text output from the `show snmp user` EAPI command and parses the text into structured data suitable for use as a resource has to the provider initializer method.

“`

User name : jeff Security model : v3 Engine ID : f5717f00420008177800 Authentication : SHA Privacy : AES-128 Group : developers

User name : nigel Security model : v2c Group : sysops (not configured)

User name : nigel Security model : v3 Engine ID : f5717f00420008177800 Authentication : SHA Privacy : AES-128 Group : sysops “`

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/MethodLength

Parameters:

  • text (String)

    The text to parse

Returns:

  • (Array<Hash<Symbol,Object>>)

    Array of resource hashes.


248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/rbeapi/netdev/snmp.rb', line 248

def parse_snmp_users(text)
  text.split("\n\n").map do |user_s|
    user_s.scan(/^(\w+).*?: (.*)/).each_with_object({}) do |(h, v), m|
      key = SNMP_USER_PARAM[h.downcase.intern] || h.downcase.intern
      m[key] = case key
                when :privacy  then /AES/.match(v) ? :aes128 : :des
                when :version  then v.sub('v2c', 'v2').intern
                when :auth     then v.downcase.intern
                when :roles    then v.sub(/ \(.*?\)/, '')
                else v.downcase
                end
    end
  end
end

#snmp_notification_receiver_remove(opts = {}) ⇒ Boolean

snmp_notification_receiver_remove removes an snmp-server host from the target device.

Parameters:

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

    a customizable set of options

Options Hash (opts):

  • :name (String) — default: '127.0.0.1'

    The hostname or ip address of the snmp notification receiver host.

  • :username (String) — default: 'public'

    The SNMP username, or community, to use for authentication.

  • :port (Fixnum) — default: 162

    The UDP port of the receiver.

  • :version (Symbol) — default: :v3

    The version, :v1, :v2, or :v3

  • :type (Symbol) — default: :traps

    The notification type, :traps or :informs.

  • :security (Symbol) — default: :auth

    The security mode, :auth, :noauth, or :priv

Returns:

  • (Boolean)

189
190
191
192
# File 'lib/rbeapi/netdev/snmp.rb', line 189

def snmp_notification_receiver_remove(opts = {})
  cmd = 'no ' << snmp_notification_receiver_cmd(opts)
  configure cmd
end

#snmp_notification_receiver_set(opts = {}) ⇒ Boolean

snmp_notification_receiver_set takes a resource hash and configures a SNMP notification host on the target device. In practice this method usually creates a resource because nearly all of the properties can vary and are components of a resource identifier.

Parameters:

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

    a customizable set of options

Options Hash (opts):

  • :name (String) — default: '127.0.0.1'

    The hostname or ip address of the snmp notification receiver host.

  • :username (String) — default: 'public'

    The SNMP username, or community, to use for authentication.

  • :port (Fixnum) — default: 162

    The UDP port of the receiver.

  • :version (Symbol) — default: :v3

    The version, :v1, :v2, or :v3

  • :type (Symbol) — default: :traps

    The notification type, :traps or :informs.

  • :security (Symbol) — default: :auth

    The security mode, :auth, :noauth, or :priv

Returns:

  • (Boolean)

143
144
145
# File 'lib/rbeapi/netdev/snmp.rb', line 143

def snmp_notification_receiver_set(opts = {})
  configure snmp_notification_receiver_cmd(opts)
end

#snmp_notification_receiversArray<Hash<Symbol,Object>>

snmp_notification_receivers obtains a list of all the snmp notification receivers and returns them as an Array of resource hashes suitable for the provider's new class method. This command maps the `show snmp host` command to an array of resource hashes.

Returns:

  • (Array<Hash<Symbol,Object>>)

    Array of resource hashes.


57
58
59
60
61
62
# File 'lib/rbeapi/netdev/snmp.rb', line 57

def snmp_notification_receivers
  cmd = 'show snmp host'
  result = node.enable(cmd)
  text = result.first[:result]['output']
  parse_snmp_hosts(text)
end

#snmp_user_destroy(opts = {}) ⇒ Hash<Symbol,Object>, String

snmp_user_destroy removes an SNMP user from the target device

Parameters:

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

    a customizable set of options

Options Hash (opts):

  • :name (String) — default: 'johndoe'

    The username

  • :roles (Array) — default: ['developers']

    The group, as an Array, this user is associated with.

  • :version (Symbol) — default: :v2

    The snmp version for this user account.

  • :auth (Symbol) — default: :sha

    The authentication digest method

  • :privacy (Symbol) — default: :aes

    The encryption scheme for privacy.

  • :password (String) — default: 'abc123'

    The password to configure for authentication and privacy.

Returns:

  • (Hash<Symbol,Object>)

    Updated properties, e.g. the password hash which is idempotent.

  • (String)

343
344
345
346
347
348
349
# File 'lib/rbeapi/netdev/snmp.rb', line 343

def snmp_user_destroy(opts = {})
  group = [*opts[:roles]].first
  version = opts[:version].to_s.sub('v2', 'v2c')
  cmd = "no snmp-server user #{opts[:name]} #{group} #{version}"
  configure cmd
  {}
end

#snmp_user_password_hash(running_config, user_cmd) ⇒ Hash<Symbol,String>

snmp_user_password obtains the password hash from the device in order to provide an idempotent configuration value.

Parameters:

  • running_config (String)

    The text of the current running configuration.

  • user_cmd (String)

    The prefix of the command that identifies the user in the running-config. e.g. ('snmp-server user jeff developers v3')

Returns:

  • (Hash<Symbol,String>)

    The hashes for :auth and :privacy


363
364
365
366
367
# File 'lib/rbeapi/netdev/snmp.rb', line 363

def snmp_user_password_hash(running_config, user_cmd)
  regexp = /#{user_cmd} .*?auth \w+\s+(.*?)\s+priv \w+\s+(.*?)\s/
  (auth_hash, priv_hash) = running_config.scan(regexp).first
  { auth: auth_hash, privacy: priv_hash }
end

#snmp_user_set(opts = {}) ⇒ Hash<Symbol,Object>

snmp_user_set creates or updates an SNMP user account on the target device.

rubocop:disable Metrics/MethodLength

Parameters:

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

    a customizable set of options

Options Hash (opts):

  • :name (String) — default: 'johndoe'

    The username

  • :roles (Array) — default: ['developers']

    The group, as an Array, this user is associated with.

  • :version (Symbol) — default: :v2

    The snmp version for this user account.

  • :auth (Symbol) — default: :sha

    The authentication digest method

  • :privacy (Symbol) — default: :aes

    The encryption scheme for privacy.

  • :password (String) — default: 'abc123'

    The password to configure for authentication and privacy.

Returns:

  • (Hash<Symbol,Object>)

    Updated properties, e.g. the password hash which is idempotent.


300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/rbeapi/netdev/snmp.rb', line 300

def snmp_user_set(opts = {})
  group = [*opts[:roles]].first
  fail ArgumentError, 'at least one role is required' unless group
  version = opts[:version].to_s.sub('v2', 'v2c')
  cmd = user_cmd = "snmp-server user #{opts[:name]} #{group} #{version}"
  if opts[:password] && version == 'v3'
    privacy = opts[:privacy].to_s.scan(/aes|des/).first
    fail ArgumentError,
          'privacy is required when managing passwords' unless privacy
    cmd += " auth #{opts[:auth] || 'sha'} #{opts[:password]} "\
      "priv #{privacy} #{opts[:password]}"
  end
  configure cmd
  hash = snmp_user_password_hash(running_config, user_cmd)
  { password: hash[:auth] }
end

#snmp_usersArray<Hash<Symbol,Object>>

snmp_users retrieves all of the SNMP users defined on the target device and returns an Array of Hash objects suitable for use as a resource hash to the provider's initializer method.

Returns:

  • (Array<Hash<Symbol,Object>>)

    Array of resource hashes.


202
203
204
205
206
207
208
209
210
211
212
# File 'lib/rbeapi/netdev/snmp.rb', line 202

def snmp_users
  cmd = 'show snmp user'
  result = node.enable(cmd)
  text = result.first[:result]['output']
  users = parse_snmp_users(text)
  users.each do |h|
    cmd = "snmp-server user #{h[:name]} #{h[:roles]} #{h[:version]}"
    password = snmp_user_password_hash(config, cmd)[:auth]
    h[:password] = password if password
  end
end