Module: PuppetX::NetDev::EosApi::SnmpMethods

Included in:
PuppetX::NetDev::EosApi
Defined in:
lib/puppet_x/net_dev/eos_api/snmp_methods.rb

Overview

SnmpMethods encapsulate the SNMP specific EOS API methods. This separation makes it easier to provide documentation and introspect where methods come from given an api instance.

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 Method Summary collapse

Instance Method Details

#parse_snmp_communities(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_communities takes the text output from the ‘show snmp community` EAPI command and parses the text into structured data suitable for use as a resource hash to the provider initializer method. An example of the output looks like:

“‘ Community name: jeff Community access: read-write Access list: stest1

Community name: jeff2 Community access: read-write Access list: stest2 (non-existent)

Community name: private Community access: read-write

Community name: public Community access: read-only “‘

Parameters:

  • text (String)

    The text to parse

Returns:

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

    Array of resource hashes.



184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 184

def parse_snmp_communities(text)
  blocks = text.split("\n\n")
  # (?:\s*\(.*?\)|\n|$) deals with trailing data after the value.  e.g.
  # an ACL might come back as `Access list: stest2 (non-existent)`
  regexp = / (\w+): (\w.*?)(?:\s*\(.*?\)|\n|$)/
  communities = blocks.map { |l| l.scan(regexp) }
  communities.map do |pairs|
    pairs.each_with_object({}) do |(key, val), resource_hash|
      resource_hash.merge!(map_snmp_keys(key, val))
    end
  end
end

#parse_snmp_enable(text) ⇒ Symbol

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_enable parses the text output of the ‘show snmp` command an returns :true or :false for the enabled state.

Parameters:

  • text (String)

    The text of the snmp output, e.g. for a disabled SNMP service:

    SNMP agent enabled in VRFs: default
    SNMP agent disabled: no communities or users configured
    

Returns:

  • (Symbol)

    :true or :false



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 66

def parse_snmp_enable(text)
  disabled_regexp = /SNMP agent disabled:/m
  enabled_regexp = /SNMP packets input/m

  disabled_mdata = disabled_regexp.match(text)
  return :false if disabled_mdata

  enabled_mdata = enabled_regexp.match(text)
  return :true if enabled_mdata

  fail ArgumentError, 'could not parse text for SNMP enabled state'
end

#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: priv@te 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.



371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 371

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_traps(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_traps takes the raw text output of the ‘show snmp trap` command and parses the data into hases suitable for new provider instances.

Parameters:

  • text (String)

    The raw text to process.

Returns:

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

    Array of resource hashes.



280
281
282
283
284
285
286
287
288
289
290
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 280

def parse_snmp_traps(text)
  regexp = /(\w+)\s+([-_\w]+)\s+(\w+).*$/
  triples = text.scan(regexp)
  triples.shift # Header
  triples.map do |triple|
    {
      name: format('%s %s', *triple),
      enable: /yes/xi.match(triple[2]) ? :true : :false
    }
  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.



522
523
524
525
526
527
528
529
530
531
532
533
534
535
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 522

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_attributesHash<Symbol,String>

snmp_attributes retrieves the current state of the SNMP service on the device and returns data suitable for a provider instance.

Returns:

  • (Hash<Symbol,String>)


17
18
19
20
21
22
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 17

def snmp_attributes
  rval = { name: 'settings', ensure: :present }
  rval.merge!(snmp_location)
  rval.merge!(snmp_enable)
  rval.merge!(snmp_contact)
end

#snmp_communitiesArray<Hash<Symbol,Object>>

snmp_communities retrieves all of the SNMP community strings 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.

Parameters:

  • buf (String)

    Describe the string parameter here

Returns:

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

    Array of resource hashes.



150
151
152
153
154
155
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 150

def snmp_communities
  cmd = 'show snmp community'
  result = eapi_action(cmd, 'get snmp communities', format: 'text')
  text = result.first['output']
  parse_snmp_communities(text)
end

#snmp_community_destroy(opts) ⇒ Boolean

snmp_community_destroy deletes an SNMP community from the target device. given a hash of attributes from the resource model.

Parameters:

  • opts (Hash)

    a customizable set of options

Options Hash (opts):

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

    The community name

Returns:

  • (Boolean)

    true if the resource was successfully created



249
250
251
252
253
254
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 249

def snmp_community_destroy(opts)
  prefix = %w(enable configure)
  cmd = "no snmp-server community #{opts[:name]}"
  result = eapi_action([*prefix, cmd], 'destroy snmp community')
  result && true || false
end

#snmp_community_set(opts) ⇒ Boolean

snmp_community_set creates or updates an snmp community on the target device given a hash of attributes from the resource model.

Parameters:

  • opts (Hash)

    a customizable set of options

Options Hash (opts):

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

    The community name

  • :group (Symbol) — default: :ro

    :ro or :rw for read-only or read-write access control for the community name.

  • :acl (String) — default: 'stest1'

    The standard ACL name defined on the switch. This ACL is defined using the ‘ip access-list standard stest1` command.

Returns:

  • (Boolean)

    true if the resource was successfully created



232
233
234
235
236
237
238
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 232

def snmp_community_set(opts)
  prefix = %w(enable configure)
  cmd = "snmp-server community #{opts[:name]}"
  cmd << " #{opts[:group]}" if opts[:group]
  cmd << " #{opts[:acl]}" if opts[:acl]
  eapi_action([*prefix, cmd], 'define snmp community') && true || false
end

#snmp_contactHash<Symbol,Symbol>

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.

snmp_contact returns the snmp contact string configured on the device.

Returns:

  • (Hash<Symbol,Symbol>)

    e.g. ‘{ contact: ’Jane Doe’ }‘



85
86
87
88
89
90
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 85

def snmp_contact
  cmd = 'show snmp contact'
  result = eapi_action(cmd, 'get snmp contact')
  contact = result.first['contact']
  { contact: contact }
end

#snmp_contact=(contact) ⇒ Boolean

snmp_contact= updates the SNMP contact on the target device.

Parameters:

  • contact (String)

    The contact name, e.g. ‘Jane Doe’

Returns:

  • (Boolean)

    true or false



120
121
122
123
124
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 120

def snmp_contact=(contact)
  cmd = %w(enable configure)
  cmd << "snmp-server contact #{contact}"
  eapi_action(cmd, 'set snmp contact') && true || false
end

#snmp_enableHash<Symbol,Symbol>

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.

snmp_enable returns :true if SNMP is enabled on the device or :false otherwise as a Hash suitable for merge into ‘snmp_attributes`.

Returns:

  • (Hash<Symbol,Symbol>)

    e.g. ‘{ enable: :true }`



45
46
47
48
49
50
51
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 45

def snmp_enable
  cmd = 'show snmp'
  result = eapi_action(cmd, 'get snmp status', format: 'text')
  text = result.first['output']
  enable = parse_snmp_enable(text)
  { enable: enable }
end

#snmp_enable=(state) ⇒ Object

snmp_enable= disables or enables SNMP

Parameters:

  • state (Boolean)

    enable SNMP if true, disable if false.



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 98

def snmp_enable=(state)
  cmd = %w(enable configure)
  case state
  when true
    cmd << 'snmp-server community public ro'
  when false
    cmd << 'no snmp-server'
  else
    fail ArgumentError, "invalid state #{state.inspect}"
  end

  eapi_action(cmd, 'configure snmp') && true || false
end

#snmp_locationHash<Symbol,String>

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.

snmp_location obtains the configured SNMP location string from the device.

Returns:

  • (Hash<Symbol,String>)


31
32
33
34
35
36
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 31

def snmp_location
  cmd = 'show snmp location'
  result = eapi_action(cmd, 'get snmp location')
  location = result.first['location']
  { location: location }
end

#snmp_location=(location) ⇒ Boolean

snmp_location= updates the SNMP location on the target device.

Parameters:

  • location (String)

    The location, e.g. ‘Planet Earth’

Returns:

  • (Boolean)

    true or false



134
135
136
137
138
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 134

def snmp_location=(location)
  cmd = %w(enable configure)
  cmd << "snmp-server location #{location}"
  eapi_action(cmd, 'set snmp location') && true || false
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)


460
461
462
463
464
465
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 460

def snmp_notification_receiver_remove(opts = {})
  prefix = %w(enable configure)
  cmd = 'no ' << snmp_notification_receiver_cmd(opts)
  result = eapi_action([*prefix, cmd], 'remove snmp host')
  result ? true : false
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)


411
412
413
414
415
416
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 411

def snmp_notification_receiver_set(opts = {})
  prefix = %w(enable configure)
  cmd = snmp_notification_receiver_cmd(opts)
  result = eapi_action([*prefix, cmd], 'set snmp host')
  result ? true : false
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.



324
325
326
327
328
329
330
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 324

def snmp_notification_receivers
  cmd = 'show snmp host'
  msg = 'get snmp notification hosts'
  result = eapi_action(cmd, msg, format: 'text')
  text = result.first['output']
  parse_snmp_hosts(text)
end

#snmp_notification_set(opts) ⇒ Boolean

snmp_notification_set configures a SNMP trap notification on the target device.

Parameters:

  • opts (Hash)

    a customizable set of options

Options Hash (opts):

  • :name (String) — default: 'snmp link-down'

    The trap name with the type name as a prefix separated by a space. The special name ‘all’ will enable or disable all notifications.

  • :enable (Symbol) — default: :true

    :true to enable the notification, :false to disable the notification.

Returns:

  • (Boolean)

    true if successful



306
307
308
309
310
311
312
313
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 306

def snmp_notification_set(opts)
  prefix = %w(enable configure)
  pre = opts[:enable] == :true ? '' : 'no '
  suffix = opts[:name] == 'all' ? '' : " #{opts[:name]}"
  cmd = pre << 'snmp-server enable traps' << suffix
  result = eapi_action([*prefix, cmd], 'set snmp trap')
  result && true || false
end

#snmp_notificationsArray<Hash<Symbol,Object>>

snmp_notifications returns an Array of resource hashes suitable for initializing new provider resources.

Returns:

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

    Array of resource hashes.



263
264
265
266
267
268
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 263

def snmp_notifications
  cmd = 'show snmp trap'
  result = eapi_action(cmd, 'get snmp traps', format: 'text')
  text = result.first['output']
  parse_snmp_traps(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)


618
619
620
621
622
623
624
625
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 618

def snmp_user_destroy(opts = {})
  prefix = %w(enable configure)
  group = [*opts[:roles]].first
  version = opts[:version].to_s.sub('v2', 'v2c')
  cmd = "no snmp-server user #{opts[:name]} #{group} #{version}"
  eapi_action([*prefix, cmd], 'remove snmp user')
  {}
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



639
640
641
642
643
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 639

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.



574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 574

def snmp_user_set(opts = {})
  prefix = %w(enable configure)
  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
  eapi_action([*prefix, cmd], 'configure snmp user')
  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.



475
476
477
478
479
480
481
482
483
484
485
486
# File 'lib/puppet_x/net_dev/eos_api/snmp_methods.rb', line 475

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