Class: Cisco::RouterBgpAF

Inherits:
NodeUtil show all
Defined in:
lib/cisco_node_utils/bgp_af.rb

Overview

RouterBgpAF - node utility class for BGP address-family config management

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from NodeUtil

#client, client, #config_get, config_get, #config_get_default, config_get_default, config_set, #config_set, #get, #ios_xr?, #nexus?, node, #node, platform, #platform, supports?, #supports?

Constructor Details

#initialize(asn, vrf, af, instantiate = true) ⇒ RouterBgpAF


27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/cisco_node_utils/bgp_af.rb', line 27

def initialize(asn, vrf, af, instantiate=true)
  fail ArgumentError if vrf.to_s.empty? || af.to_s.empty?
  err_msg = '"af" argument must be an array of two string values ' \
    'containing an afi + safi tuple'
  fail ArgumentError, err_msg unless af.is_a?(Array) || af.length == 2
  err_msg = '"vrf" argument must be "default" for l2vpn address-family'
  fail ArgumentError, err_msg if vrf != 'default' && af[1][/evpn/]
  @asn = RouterBgp.validate_asnum(asn)
  @vrf = vrf
  @afi, @safi = af
  set_args_keys_default
  create if instantiate
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args) ⇒ Object

Universal Getter, Default Getter, and Setter


508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
# File 'lib/cisco_node_utils/bgp_af.rb', line 508

def method_missing(*args)
  name = args[0].to_s
  if args.length == 1 # Getter
    if name =~ /^default_(.*)$/
      config_get_default('bgp_af', Regexp.last_match(1))
    else
      config_get('bgp_af', name, @get_args)
    end
  elsif args.length == 2 && name =~ /^(.*)=$/ # Setter
    set_args_keys(state: args[1] ? '' : 'no')
    config_set('bgp_af', Regexp.last_match(1), @set_args)
  else
    super
  end
end

Class Method Details

.afsObject


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/cisco_node_utils/bgp_af.rb', line 41

def self.afs
  af_hash = {}
  RouterBgp.routers.each do |asn, vrfs|
    af_hash[asn] = {}
    vrfs.keys.each do |vrf_name|
      get_args = { asnum: asn }
      get_args[:vrf] = vrf_name unless vrf_name == 'default'
      # Call yaml and search for address-family statements
      af_list = config_get('bgp_af', 'all_afs', get_args)

      next if af_list.nil?

      af_hash[asn][vrf_name] = {}
      af_list.each do |af|
        af_hash[asn][vrf_name][af] =
          RouterBgpAF.new(asn, vrf_name, af, false)
      end
    end
  end
  af_hash
end

Instance Method Details

#additional_paths_selection=(route_map) ⇒ Object

additional paths (Getter/Setter/Default)


141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/cisco_node_utils/bgp_af.rb', line 141

def additional_paths_selection=(route_map)
  route_map.strip!
  if route_map.empty?
    state = 'no'
    # Dummy routemap required if not configured.
    if additional_paths_selection.empty?
      route_map = 'dummy_routemap'
    else
      route_map = additional_paths_selection
    end
  end
  set_args_keys(state: state, route_map: route_map, route_policy: route_map)
  config_set('bgp_af', 'additional_paths_selection', @set_args)
end

advertise_l2vpn_evpn


157
158
159
# File 'lib/cisco_node_utils/bgp_af.rb', line 157

def advertise_l2vpn_evpn
  config_get('bgp_af', 'advertise_l2vpn_evpn', @get_args)
end

161
162
163
164
165
# File 'lib/cisco_node_utils/bgp_af.rb', line 161

def advertise_l2vpn_evpn=(state)
  Feature.nv_overlay_evpn_enable if platform == :nexus
  set_args_keys(state: (state ? '' : 'no'))
  config_set('bgp_af', 'advertise_l2vpn_evpn', @set_args)
end

#client_to_client=(state) ⇒ Object

Client to client (Getter/Setter/Default)


103
104
105
106
107
108
109
110
# File 'lib/cisco_node_utils/bgp_af.rb', line 103

def client_to_client=(state)
  # IOS XR uses "client-to-client reflection disable",
  #     so turning it "on" means disabling it.
  # Thus we invert the desired state before telling the CLI what to do:
  state = !state if ios_xr?
  set_args_keys(state: (state ? '' : 'no'))
  config_set('bgp_af', 'client_to_client', @set_args)
end

#createObject


63
64
65
66
67
68
69
70
# File 'lib/cisco_node_utils/bgp_af.rb', line 63

def create
  if platform == :nexus
    Feature.bgp_enable
    Feature.nv_overlay_evpn_enable if @safi[/evpn/]
  end
  set_args_keys(state: '')
  config_set('bgp', 'address_family', @set_args)
end

#dampen_igp_metricObject

dampen_igp_metric


172
173
174
175
176
177
178
179
# File 'lib/cisco_node_utils/bgp_af.rb', line 172

def dampen_igp_metric
  match = config_get('bgp_af', 'dampen_igp_metric', @get_args)
  if match.is_a?(Array)
    return nil if match[0] == 'no '
    return match[1].to_i if match[1]
  end
  default_dampen_igp_metric
end

#dampen_igp_metric=(val) ⇒ Object


181
182
183
184
185
# File 'lib/cisco_node_utils/bgp_af.rb', line 181

def dampen_igp_metric=(val)
  set_args_keys(state: (val.nil?) ? 'no' : '',
                num:   (val.nil?) ? '' : val)
  config_set('bgp_af', 'dampen_igp_metric', @set_args)
end

#dampeningObject

The data presented to or retrieved from the config_set and config_get for dampening is one of 4 possibilities:

Value Meaning —– ——- nil Dampening is not configured

Dampening is configured with no options

1,3,4,5,nil

Dampening + decay, reuse, suppress, suppress_max

nil,nil,nil,nil,'route-map'

Dampening + routemap


200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/cisco_node_utils/bgp_af.rb', line 200

def dampening
  data = config_get('bgp_af', 'dampening', @get_args)
  return nil if data.nil? # no dampening

  data = data.flatten

  # dampening nil nil nil nil nil
  val = []

  if !data[4].nil?
    # dampening nil nil nil nil route-map
    val = data[4]
  elsif !data[3].nil? && data[4].nil?
    # dampening 1 2 3 4 nil
    val = data[0..3]
  end

  val
end

#dampening=(damp_array) ⇒ Object


280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/cisco_node_utils/bgp_af.rb', line 280

def dampening=(damp_array)
  fail ArgumentError if damp_array.kind_of?(Array) &&
                        !(damp_array.length == 4 ||
                          damp_array.length == 0)

  # Set defaults args
  state = ''
  route_map = ''
  decay = ''
  reuse = ''
  suppress = ''
  suppress_max = ''

  if damp_array.nil?
    # 'no dampening ...' command - no dampening handles all cases
    state = 'no'
    Cisco::Logger.debug("Dampening 'no dampening'")
  elsif damp_array.empty?
    # 'dampening' command - nothing to do here
    Cisco::Logger.debug("Dampening 'dampening'")
  elsif damp_array.size == 4
    # 'dampening dampening_decay dampening_reuse      #   dampening_suppress dampening_suppress_max' command
    decay =        damp_array[0]
    reuse =        damp_array[1]
    suppress =     damp_array[2]
    suppress_max = damp_array[3]
    Cisco::Logger.debug("Dampening 'dampening #{damp_array.join(' ')}''")
  else
    # 'dampening route-map WORD' command
    route_map = "route-map #{damp_array}"    if platform == :nexus
    route_map = "route-policy #{damp_array}" if platform == :ios_xr
    route_map.strip!
    Cisco::Logger.debug("Dampening 'dampening route-map #{route_map}'")
  end

  # Set final args
  set_args_keys(
    state:        state,
    route_map:    route_map,
    decay:        decay,
    reuse:        reuse,
    suppress:     suppress,
    suppress_max: suppress_max,
  )

  Cisco::Logger.debug("Dampening args=#{@set_args}")
  config_set('bgp_af', 'dampening', @set_args)
end

#dampening_half_timeObject

For all of the following dampening getters, half_time, reuse_time, suppress_time, and max_suppress_time, return nil if dampening is not configured, but also return nil if a dampening routemap is configured because they are mutually exclusive.


229
230
231
232
233
234
235
236
# File 'lib/cisco_node_utils/bgp_af.rb', line 229

def dampening_half_time
  return nil if dampening.nil? || dampening_routemap_configured?
  if dampening.is_a?(Array) && !dampening.empty?
    dampening[0].to_i
  else
    default_dampening_half_time
  end
end

#dampening_max_suppress_timeObject


256
257
258
259
260
261
262
263
# File 'lib/cisco_node_utils/bgp_af.rb', line 256

def dampening_max_suppress_time
  return nil if dampening.nil? || dampening_routemap_configured?
  if dampening.is_a?(Array) && !dampening.empty?
    dampening[3].to_i
  else
    default_dampening_max_suppress_time
  end
end

#dampening_reuse_timeObject


238
239
240
241
242
243
244
245
# File 'lib/cisco_node_utils/bgp_af.rb', line 238

def dampening_reuse_time
  return nil if dampening.nil? || dampening_routemap_configured?
  if dampening.is_a?(Array) && !dampening.empty?
    dampening[1].to_i
  else
    default_dampening_reuse_time
  end
end

#dampening_routemapObject


265
266
267
268
269
270
# File 'lib/cisco_node_utils/bgp_af.rb', line 265

def dampening_routemap
  if dampening.nil? || (dampening.is_a?(String) && dampening.size > 0)
    return dampening
  end
  default_dampening_routemap
end

#dampening_routemap_configured?Boolean


272
273
274
275
276
277
278
# File 'lib/cisco_node_utils/bgp_af.rb', line 272

def dampening_routemap_configured?
  if dampening_routemap.is_a?(String) && dampening_routemap.size > 0
    true
  else
    false
  end
end

#dampening_stateObject

Return true if dampening is enabled, else false.


221
222
223
# File 'lib/cisco_node_utils/bgp_af.rb', line 221

def dampening_state
  !dampening.nil?
end

#dampening_suppress_timeObject


247
248
249
250
251
252
253
254
# File 'lib/cisco_node_utils/bgp_af.rb', line 247

def dampening_suppress_time
  return nil if dampening.nil? || dampening_routemap_configured?
  if dampening.is_a?(Array) && !dampening.empty?
    dampening[2].to_i
  else
    default_dampening_suppress_time
  end
end

#default_information_originateObject

Default Information (Getter/Setter/Default)


116
117
118
# File 'lib/cisco_node_utils/bgp_af.rb', line 116

def default_information_originate
  config_get('bgp_af', 'default_information_originate', @get_args)
end

#default_metricObject

default_metric (Getter/Setter/Default)


360
361
362
# File 'lib/cisco_node_utils/bgp_af.rb', line 360

def default_metric
  config_get('bgp_af', 'default_metric', @get_args)
end

#default_metric=(val) ⇒ Object


364
365
366
367
368
369
370
371
# File 'lib/cisco_node_utils/bgp_af.rb', line 364

def default_metric=(val)
  # To remove the default_metric you can not use 'no default_metric'
  # dummy metric to work around this
  dummy_metric = 1
  set_args_keys(state: (val == default_default_metric) ? 'no' : '',
                num:   (val == default_default_metric) ? dummy_metric : val)
  config_set('bgp_af', 'default_metric', @set_args)
end

#default_redistributeObject


477
478
479
# File 'lib/cisco_node_utils/bgp_af.rb', line 477

def default_redistribute
  config_get_default('bgp_af', 'redistribute')
end

#destroyObject


72
73
74
75
# File 'lib/cisco_node_utils/bgp_af.rb', line 72

def destroy
  set_args_keys(state: 'no')
  config_set('bgp', 'address_family', @set_args)
end

#distance_ebgpObject


338
339
340
341
342
# File 'lib/cisco_node_utils/bgp_af.rb', line 338

def distance_ebgp
  ebgp, _ibgp, _local = distance
  return default_distance_ebgp if ebgp.nil?
  ebgp.to_i
end

#distance_ibgpObject


344
345
346
347
348
# File 'lib/cisco_node_utils/bgp_af.rb', line 344

def distance_ibgp
  _ebgp, ibgp, _local = distance
  return default_distance_ibgp if ibgp.nil?
  ibgp.to_i
end

#distance_localObject


350
351
352
353
354
# File 'lib/cisco_node_utils/bgp_af.rb', line 350

def distance_local
  _ebgp, _ibgp, local = distance
  return default_distance_local if local.nil?
  local.to_i
end

#distance_set(ebgp, ibgp, local) ⇒ Object

Distance (Getter/Setter/Default)


333
334
335
336
# File 'lib/cisco_node_utils/bgp_af.rb', line 333

def distance_set(ebgp, ibgp, local)
  set_args_keys(state: '', ebgp: ebgp, ibgp: ibgp, local: local)
  config_set('bgp_af', 'distance', @set_args)
end

#fail_unsupported(callee) ⇒ Object

PROPERTIES #


95
96
97
# File 'lib/cisco_node_utils/bgp_af.rb', line 95

def fail_unsupported(callee)
  fail Cisco::UnsupportedError.new('bgp_af', callee.to_s)
end

#inject_mapObject

inject_map (Getter/Setter/Default)


377
378
379
380
# File 'lib/cisco_node_utils/bgp_af.rb', line 377

def inject_map
  cmds = config_get('bgp_af', 'inject_map', @get_args)
  cmds.nil? ? nil : cmds.each(&:compact!).sort
end

#inject_map=(should_list) ⇒ Object


382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/cisco_node_utils/bgp_af.rb', line 382

def inject_map=(should_list)
  c = inject_map
  fail_unsupported(__callee__) if c.nil?
  delta_hash = Utils.delta_add_remove(should_list, c)
  return if delta_hash.values.flatten.empty?
  [:add, :remove].each do |action|
    Cisco::Logger.debug("inject_map delta #{@get_args}\n #{action}: " \
                        "#{delta_hash[action]}")
    delta_hash[action].each do |inject, exist, copy|
      # inject & exist are mandatory, copy is optional
      state = (action == :add) ? '' : 'no'
      copy = 'copy-attributes' unless copy.nil?
      set_args_keys(state: state, inject: inject, exist: exist, copy: copy)
      config_set('bgp_af', 'inject_map', @set_args)
    end
  end
end

#maximum_paths=(val) ⇒ Object

maximum_paths (Getter/Setter/Default)


404
405
406
407
408
# File 'lib/cisco_node_utils/bgp_af.rb', line 404

def maximum_paths=(val)
  set_args_keys(state: (val == default_maximum_paths) ? 'no' : '',
                num:   (val == default_maximum_paths) ? '' : val)
  config_set('bgp_af', 'maximum_paths', @set_args)
end

#maximum_paths_ibgp=(val) ⇒ Object


410
411
412
413
414
# File 'lib/cisco_node_utils/bgp_af.rb', line 410

def maximum_paths_ibgp=(val)
  set_args_keys(state: (val == default_maximum_paths_ibgp) ? 'no' : '',
                num:   (val == default_maximum_paths_ibgp) ? '' : val)
  config_set('bgp_af', 'maximum_paths_ibgp', @set_args)
end

#networksObject

Build an array of all network commands currently on the device


421
422
423
424
# File 'lib/cisco_node_utils/bgp_af.rb', line 421

def networks
  c = config_get('bgp_af', 'networks', @get_args)
  c.nil? ? nil : c.each(&:compact!)
end

#networks=(should_list) ⇒ Object

networks setter. Processes a hash of network commands from delta_add_remove().


428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/cisco_node_utils/bgp_af.rb', line 428

def networks=(should_list)
  delta_hash = Utils.delta_add_remove(should_list, networks)
  return if delta_hash.values.flatten.empty?
  [:add, :remove].each do |action|
    Cisco::Logger.debug("networks delta #{@get_args}\n #{action}: " \
                        "#{delta_hash[action]}")
    delta_hash[action].each do |network, route_map_policy|
      state = (action == :add) ? '' : 'no'
      network = Utils.process_network_mask(network)
      unless route_map_policy.nil?
        route_map = "route-map #{route_map_policy}"
        route_policy = "route-policy #{route_map_policy}"
      end
      set_args_keys(state: state, network: network, route_map: route_map,
                    route_policy: route_policy)
      config_set('bgp_af', 'networks', @set_args)
    end
  end
end

#next_hop_route_map=(route_map) ⇒ Object

Next Hop route map (Getter/Setter/Default)


123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/cisco_node_utils/bgp_af.rb', line 123

def next_hop_route_map=(route_map)
  route_map.strip!
  if route_map.empty?
    state = 'no'
    # Dummy routemap required if not configured.
    if next_hop_route_map.empty?
      route_map = 'dummy_routemap'
    else
      route_map = next_hop_route_map
    end
  end
  set_args_keys(state: state, route_map: route_map)
  config_set('bgp_af', 'next_hop_route_map', @set_args)
end

#redistributeObject

Build an array of all redistribute commands currently on the device


453
454
455
456
# File 'lib/cisco_node_utils/bgp_af.rb', line 453

def redistribute
  c = config_get('bgp_af', 'redistribute', @get_args)
  c.nil? ? nil : c.each(&:compact!).sort
end

#redistribute=(should) ⇒ Object

redistribute setter. Process a hash of redistribute commands from delta_add_remove().


460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/cisco_node_utils/bgp_af.rb', line 460

def redistribute=(should)
  delta_hash = Utils.delta_add_remove(should, redistribute)
  return if delta_hash.values.flatten.empty?
  [:add, :remove].each do |action|
    Cisco::Logger.debug("redistribute delta #{@get_args}\n #{action}: " \
                        "#{delta_hash[action]}")
    delta_hash[action].each do |protocol, policy|
      state = (action == :add) ? '' : 'no'
      set_args_keys(state: state, protocol: protocol, policy: policy)

      # route-map/policy may be optional on some platforms
      cmd = policy.nil? ? 'redistribute' : 'redistribute_policy'
      config_set('bgp_af', cmd, @set_args)
    end
  end
end

#respond_to?(method_sym, _include_private = false) ⇒ Boolean

Is the given name available in the YAML?


525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
# File 'lib/cisco_node_utils/bgp_af.rb', line 525

def respond_to?(method_sym, _include_private=false)
  name = method_sym.to_s
  key = :getter?
  if name =~ /^(.*)=$/
    name = Regexp.last_match(1)
    # Use table_map_set() to set these properties
    return false if name == 'table_map' || name == 'table_map_filter'
    key = :setter?
  elsif name =~ /^default_(.*)$/
    name = Regexp.last_match(1)
    key = :default_value?
  end
  begin
    ref = node.cmd_ref.lookup('bgp_af', name)
    ref.send(key)
  rescue IndexError
    super
  end
end

#set_args_keys(hash = {}) ⇒ Object

rubocop:disable Style/AccessorMethodName


86
87
88
89
# File 'lib/cisco_node_utils/bgp_af.rb', line 86

def set_args_keys(hash={}) # rubocop:disable Style/AccessorMethodName
  set_args_keys_default
  @set_args = @get_args.merge!(hash) unless hash.empty?
end

#set_args_keys_defaultObject

Helper methods to delete @set_args hash keys


80
81
82
83
84
# File 'lib/cisco_node_utils/bgp_af.rb', line 80

def set_args_keys_default
  keys = { asnum: @asn, afi: @afi, safi: @safi }
  keys[:vrf] = @vrf unless @vrf == 'default'
  @get_args = @set_args = keys
end

#table_map_set(map, filter = false) ⇒ Object

Table Map (Getter/Setter/Default)


485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
# File 'lib/cisco_node_utils/bgp_af.rb', line 485

def table_map_set(map, filter=false)
  # To remove table map we can not use 'no table-map'
  # Dummy-map specified to work around this
  if filter
    attr = 'table_map_filter'
  else
    attr = 'table_map'
  end
  dummy_map = 'dummy'
  if map == default_table_map
    @set_args[:state] = 'no'
    @set_args[:map] = dummy_map
  else
    @set_args[:state] = ''
    @set_args[:map] = map
  end
  config_set('bgp_af', attr, @set_args)
  set_args_keys_default
end