Class: Cisco::Ace

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

Overview

Ace - node utility class for Ace Configuration

Instance Attribute Summary collapse

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(afi, acl_name, seqno) ⇒ Ace


23
24
25
26
27
28
# File 'lib/cisco_node_utils/ace.rb', line 23

def initialize(afi, acl_name, seqno)
  @afi = Acl.afi_cli(afi)
  @acl_name = acl_name.to_s
  @seqno = seqno.to_s
  set_args_keys_default
end

Instance Attribute Details

#acl_nameObject (readonly)

Returns the value of attribute acl_name


21
22
23
# File 'lib/cisco_node_utils/ace.rb', line 21

def acl_name
  @acl_name
end

#afiObject (readonly)

Returns the value of attribute afi


21
22
23
# File 'lib/cisco_node_utils/ace.rb', line 21

def afi
  @afi
end

Class Method Details

.acesObject

Create a hash of all aces under a given acl_name.


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/cisco_node_utils/ace.rb', line 31

def self.aces
  afis = %w(ipv4 ipv6)
  hash = {}
  afis.each do |afi|
    hash[afi] = {}
    acls = config_get('acl', 'all_acls', afi: Acl.afi_cli(afi))
    next if acls.nil?

    acls.each do |acl_name|
      hash[afi][acl_name] = {}
      aces = config_get('acl', 'all_aces',
                        afi: Acl.afi_cli(afi), acl_name: acl_name)
      next if aces.nil?

      aces.each do |seqno|
        hash[afi][acl_name][seqno] = Ace.new(afi, acl_name, seqno)
      end
    end
  end
  hash
end

Instance Method Details

#ace_getObject

common ace getter


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/cisco_node_utils/ace.rb', line 70

def ace_get
  str = config_get('acl', 'ace', @get_args)
  return nil if str.nil?

  remark = Regexp.new('(?<seqno>\d+) remark (?<remark>.*)').match(str)
  return remark unless remark.nil?

  # specialized icmp protocol handling
  return icmp_ace_get(str) if str.include?('icmp')

  # rubocop:disable Metrics/LineLength
  regexp = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
             ' *(?<proto>\d+|\S+)'\
             ' *(?<src_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
             ' *(?<src_port>range \S+ \S+|(lt|eq|gt|neq|portgroup) \S+)?'\
             ' *(?<dst_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
             ' *(?<dst_port>range \S+ \S+|(lt|eq|gt|neq|portgroup) \S+)?'\
             ' *(?<tcp_flags>(ack *|fin *|urg *|syn *|psh *|rst *)*)?'\
             ' *(?<established>established)?'\
             ' *(?<precedence>precedence \S+)?'\
             ' *(?<dscp>dscp \S+)?'\
             ' *(?<time_range>time-range \S+)?'\
             ' *(?<packet_length>packet-length (range \d+ \d+|(lt|eq|gt|neq) \d+))?'\
             ' *(?<ttl>ttl \d+)?'\
             ' *(?<http_method>http-method (\d+|connect|delete|get|head|post|put|trace))?'\
             ' *(?<tcp_option_length>tcp-option-length \d+)?'\
             ' *(?<redirect>redirect \S+)?'\
             ' *(?<log>log)?')
  # rubocop:enable Metrics/LineLength
  regexp.match(str)
end

#ace_set(attrs) ⇒ Object

common ace setter. Put the values you need in a hash and pass it in. attrs = :proto=>'tcp', :src =>'host 1.1.1.1'


158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/cisco_node_utils/ace.rb', line 158

def ace_set(attrs)
  if attrs.empty?
    attrs[:state] = 'no'
  else
    # remove existing ace first
    destroy if seqno
    attrs[:state] = ''
  end

  if attrs[:remark]
    cmd = 'ace_remark'
    set_args_keys(attrs)
  else
    cmd = 'ace'
    set_args_keys_default
    set_args_keys(attrs)
    [:action,
     :proto,
     :src_addr,
     :src_port,
     :dst_addr,
     :dst_port,
     :tcp_flags,
     :established,
     :precedence,
     :dscp,
     :time_range,
     :packet_length,
     :ttl,
     :http_method,
     :tcp_option_length,
     :redirect,
     :log,
     :proto_option,
     :set_erspan_dscp,
     :set_erspan_gre_proto,
     :vlan,
    ].each do |p|
      attrs[p] = '' if attrs[p].nil?
      send(p.to_s + '=', attrs[p])
    end
    @get_args = @set_args
  end
  config_set('acl', cmd, @set_args)
end

#actionObject


227
228
229
230
231
# File 'lib/cisco_node_utils/ace.rb', line 227

def action
  match = ace_get
  return nil if match.nil?
  match.names.include?('action') ? match[:action] : nil
end

#action=(action) ⇒ Object


233
234
235
# File 'lib/cisco_node_utils/ace.rb', line 233

def action=(action)
  @set_args[:action] = action
end

#check_redirect_repeat(str) ⇒ Object


213
214
215
216
217
# File 'lib/cisco_node_utils/ace.rb', line 213

def check_redirect_repeat(str)
  return false unless str.include?('redirect')
  nstr = str.sub('redirect', '').strip
  nstr.include?('redirect') ? true : false
end

#destroyObject


53
54
55
56
# File 'lib/cisco_node_utils/ace.rb', line 53

def destroy
  set_args_keys(state: 'no')
  config_set('acl', 'ace_destroy', @set_args)
end

#dscpObject


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

def dscp
  Utils.extract_value(ace_get, 'dscp')
end

#dscp=(dscp) ⇒ Object


337
338
339
# File 'lib/cisco_node_utils/ace.rb', line 337

def dscp=(dscp)
  @set_args[:dscp] = Utils.attach_prefix(dscp, :dscp)
end

#dst_addrObject


280
281
282
283
284
285
286
287
# File 'lib/cisco_node_utils/ace.rb', line 280

def dst_addr
  match = ace_get
  return nil if match.nil? || !match.names.include?('dst_addr')
  addr = match[:dst_addr]
  # Normalize addr. Some platforms zero_pad ipv6 addrs.
  addr.gsub!(/^0*/, '').gsub!(/:0*/, ':') if valid_ipv6?(addr)
  addr
end

#dst_addr=(dst_addr) ⇒ Object


289
290
291
# File 'lib/cisco_node_utils/ace.rb', line 289

def dst_addr=(dst_addr)
  @set_args[:dst_addr] = dst_addr
end

#dst_portObject


293
294
295
296
297
# File 'lib/cisco_node_utils/ace.rb', line 293

def dst_port
  match = ace_get
  return nil if match.nil?
  match.names.include?('dst_port') ? match[:dst_port] : nil
end

#dst_port=(src_port) ⇒ Object


299
300
301
# File 'lib/cisco_node_utils/ace.rb', line 299

def dst_port=(src_port)
  @set_args[:dst_port] = src_port
end

#establishedObject


313
314
315
316
317
318
319
# File 'lib/cisco_node_utils/ace.rb', line 313

def established
  match = ace_get
  return nil unless remark.nil?
  return false if match.nil?
  return false unless match.names.include?('established')
  match[:established] == 'established' ? true : false
end

#established=(established) ⇒ Object


321
322
323
# File 'lib/cisco_node_utils/ace.rb', line 321

def established=(established)
  @set_args[:established] = established.to_s == 'true' ? 'established' : ''
end

#http_methodObject


412
413
414
# File 'lib/cisco_node_utils/ace.rb', line 412

def http_method
  Utils.extract_value(ace_get, 'http_method', 'http-method')
end

#http_method=(http_method) ⇒ Object


416
417
418
419
420
# File 'lib/cisco_node_utils/ace.rb', line 416

def http_method=(http_method)
  @set_args[:http_method] = Utils.attach_prefix(http_method,
                                                :http_method,
                                                'http-method')
end

#icmp_ace_get(str) ⇒ Object

icmp ace getter


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/cisco_node_utils/ace.rb', line 103

def icmp_ace_get(str)
  # rubocop:disable Metrics/LineLength
  # fragments is nvgen at a different location than all other
  # proto_option so get rid of it so as not to mess up other fields
  str.sub!('fragments ', '')
  regexp = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
             ' *(?<proto>\d+|\S+)'\
             ' *(?<src_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
             ' *(?<dst_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
             ' *(?<proto_option>\S+)?'\
             ' *(?<precedence>precedence \S+)?'\
             ' *(?<dscp>dscp \S+)?'\
             ' *(?<time_range>time-range \S+)?'\
             ' *(?<packet_length>packet-length (range \d+ \d+|(lt|eq|gt|neq) \d+))?'\
             ' *(?<ttl>ttl \d+)?'\
             ' *(?<vlan>vlan \d+)?'\
             ' *(?<set_erspan_gre_proto>set-erspan-gre-proto \d+)?'\
             ' *(?<set_erspan_dscp>set-erspan-dscp \d+)?'\
             ' *(?<redirect>redirect \S+)?')
  regexp_no_proto_option = Regexp.new('(?<seqno>\d+) (?<action>\S+)'\
             ' *(?<proto>\d+|\S+)'\
             ' *(?<src_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
             ' *(?<dst_addr>any|host \S+|[:\.0-9a-fA-F]+ [:\.0-9a-fA-F]+|[:\.0-9a-fA-F]+\/\d+|addrgroup \S+)'\
             ' *(?<precedence>precedence \S+)?'\
             ' *(?<dscp>dscp \S+)?'\
             ' *(?<time_range>time-range \S+)?'\
             ' *(?<packet_length>packet-length (range \d+ \d+|(lt|eq|gt|neq) \d+))?'\
             ' *(?<ttl>ttl \d+)?'\
             ' *(?<vlan>vlan \d+)?'\
             ' *(?<set_erspan_gre_proto>set-erspan-gre-proto \d+)?'\
             ' *(?<set_erspan_dscp>set-erspan-dscp \d+)?'\
             ' *(?<redirect>redirect \S+)?')
  temp = regexp.match(str)
  po = temp[:proto_option]
  if po.nil?
    return temp
  # redirect can be proto_option or an actual redirect to interface
  elsif po.strip.match(/redirect$/)
    if str.match(/Ethernet|port-channel/)
      # if proto_option is given as redirect and also redirect to intf
      # we need to do extra processing
      return temp if check_redirect_repeat(str)
      return regexp_no_proto_option.match(str)
    end
  # the reserved keywords check
  elsif po.strip.match(/precedence$|dscp$|time-range$|packet-length$|ttl$|vlan$|set-erspan-gre-proto$|set-erspan-dscp$|log$/)
    return regexp_no_proto_option.match(str)
  else
    return temp
  end
  # rubocop:enable Metrics/LineLength
end

#logObject


458
459
460
461
# File 'lib/cisco_node_utils/ace.rb', line 458

def log
  return nil unless remark.nil?
  config_get('acl', 'ace', @get_args).include?('log') ? true : false
end

#log=(log) ⇒ Object


463
464
465
# File 'lib/cisco_node_utils/ace.rb', line 463

def log=(log)
  @set_args[:log] = log.to_s == 'true' ? 'log' : ''
end

#packet_lengthObject


394
395
396
# File 'lib/cisco_node_utils/ace.rb', line 394

def packet_length
  Utils.extract_value(ace_get, 'packet_length', 'packet-length')
end

#packet_length=(packet_length) ⇒ Object


398
399
400
401
402
# File 'lib/cisco_node_utils/ace.rb', line 398

def packet_length=(packet_length)
  @set_args[:packet_length] = Utils.attach_prefix(packet_length,
                                                  :packet_length,
                                                  'packet-length')
end

#precedenceObject


325
326
327
# File 'lib/cisco_node_utils/ace.rb', line 325

def precedence
  Utils.extract_value(ace_get, 'precedence')
end

#precedence=(precedence) ⇒ Object


329
330
331
# File 'lib/cisco_node_utils/ace.rb', line 329

def precedence=(precedence)
  @set_args[:precedence] = Utils.attach_prefix(precedence, :precedence)
end

#protoObject


247
248
249
250
251
# File 'lib/cisco_node_utils/ace.rb', line 247

def proto
  match = ace_get
  return nil if match.nil?
  match.names.include?('proto') ? match[:proto] : nil
end

#proto=(proto) ⇒ Object


253
254
255
# File 'lib/cisco_node_utils/ace.rb', line 253

def proto=(proto)
  @set_args[:proto] = proto # TBD ip vs ipv4
end

#proto_optionObject


440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/cisco_node_utils/ace.rb', line 440

def proto_option
  match = ace_get
  return nil if match.nil? || proto != 'icmp' || !remark.nil?
  # fragments is nvgen at a different location than all other
  # proto_option
  if config_get('acl', 'ace', @get_args).include?('fragments')
    return 'fragments'
  end
  # log is special case
  return nil if !match.names.include?('proto_option') ||
                match[:proto_option] == 'log'
  match[:proto_option]
end

#proto_option=(proto_option) ⇒ Object


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

def proto_option=(proto_option)
  @set_args[:proto_option] = proto_option
end

#redirectObject


432
433
434
# File 'lib/cisco_node_utils/ace.rb', line 432

def redirect
  Utils.extract_value(ace_get, 'redirect')
end

#redirect=(redirect) ⇒ Object


436
437
438
# File 'lib/cisco_node_utils/ace.rb', line 436

def redirect=(redirect)
  @set_args[:redirect] = Utils.attach_prefix(redirect, :redirect)
end

#remarkObject


237
238
239
240
241
# File 'lib/cisco_node_utils/ace.rb', line 237

def remark
  match = ace_get
  return nil if match.nil?
  match.names.include?('remark') ? match[:remark] : nil
end

#remark=(remark) ⇒ Object


243
244
245
# File 'lib/cisco_node_utils/ace.rb', line 243

def remark=(remark)
  @set_args[:remark] = remark
end

#seqnoObject

PROPERTIES



221
222
223
224
225
# File 'lib/cisco_node_utils/ace.rb', line 221

def seqno
  match = ace_get
  return nil if match.nil?
  match.names.include?('seqno') ? match[:seqno] : nil
end

#set_args_keys(hash = {}) ⇒ Object

rubocop:disable Style/AccessorMethodName


64
65
66
67
# File 'lib/cisco_node_utils/ace.rb', line 64

def set_args_keys(hash={})
  set_args_keys_default
  @set_args = @get_args.merge!(hash) unless hash.empty?
end

#set_args_keys_defaultObject


58
59
60
61
# File 'lib/cisco_node_utils/ace.rb', line 58

def set_args_keys_default
  keys = { afi: @afi, acl_name: @acl_name, seqno: @seqno }
  @get_args = @set_args = keys
end

#set_erspan_dscpObject


349
350
351
352
353
354
355
356
357
# File 'lib/cisco_node_utils/ace.rb', line 349

def set_erspan_dscp
  ret = Utils.extract_value(ace_get, 'set_erspan_dscp', 'set-erspan-dscp')
  return ret if ret
  # position of set_erspan_dscp is different in older release so check again
  str = config_get('acl', 'ace', @get_args)
  sstr = str.split
  return sstr[sstr.index('set-erspan-dscp') + 1] if
    sstr.include?('set-erspan-dscp')
end

#set_erspan_dscp=(set_erspan_dscp) ⇒ Object


359
360
361
362
363
# File 'lib/cisco_node_utils/ace.rb', line 359

def set_erspan_dscp=(set_erspan_dscp)
  @set_args[:set_erspan_dscp] = Utils.attach_prefix(set_erspan_dscp,
                                                    :set_erspan_dscp,
                                                    'set-erspan-dscp')
end

#set_erspan_gre_protoObject


365
366
367
368
369
370
371
372
373
374
375
# File 'lib/cisco_node_utils/ace.rb', line 365

def set_erspan_gre_proto
  ret = Utils.extract_value(ace_get, 'set_erspan_gre_proto',
                            'set-erspan-gre-proto')
  return ret if ret
  # position of set_erspan_gre_proto is different in older release
  # so check again
  str = config_get('acl', 'ace', @get_args)
  sstr = str.split
  return sstr[sstr.index('set-erspan-gre-proto') + 1] if
    sstr.include?('set-erspan-gre-proto')
end

#set_erspan_gre_proto=(set_erspan_gre_proto) ⇒ Object


377
378
379
380
381
382
# File 'lib/cisco_node_utils/ace.rb', line 377

def set_erspan_gre_proto=(set_erspan_gre_proto)
  @set_args[:set_erspan_gre_proto] =
      Utils.attach_prefix(set_erspan_gre_proto,
                          :set_erspan_gre_proto,
                          'set-erspan-gre-proto')
end

#src_addrObject


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

def src_addr
  match = ace_get
  return nil if match.nil? || !match.names.include?('src_addr')
  addr = match[:src_addr]
  # Normalize addr. Some platforms zero_pad ipv6 addrs.
  addr.gsub!(/^0*/, '').gsub!(/:0*/, ':') if valid_ipv6?(addr)
  addr
end

#src_addr=(src_addr) ⇒ Object


266
267
268
# File 'lib/cisco_node_utils/ace.rb', line 266

def src_addr=(src_addr)
  @set_args[:src_addr] = src_addr
end

#src_portObject


270
271
272
273
274
# File 'lib/cisco_node_utils/ace.rb', line 270

def src_port
  match = ace_get
  return nil if match.nil?
  match.names.include?('src_port') ? match[:src_port] : nil
end

#src_port=(src_port) ⇒ Object


276
277
278
# File 'lib/cisco_node_utils/ace.rb', line 276

def src_port=(src_port)
  @set_args[:src_port] = src_port
end

#tcp_flagsObject


303
304
305
306
307
# File 'lib/cisco_node_utils/ace.rb', line 303

def tcp_flags
  match = ace_get
  return nil if match.nil?
  match.names.include?('tcp_flags') ? match[:tcp_flags].strip : nil
end

#tcp_flags=(tcp_flags) ⇒ Object


309
310
311
# File 'lib/cisco_node_utils/ace.rb', line 309

def tcp_flags=(tcp_flags)
  @set_args[:tcp_flags] = tcp_flags.strip
end

#tcp_option_lengthObject


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

def tcp_option_length
  Utils.extract_value(ace_get, 'tcp_option_length', 'tcp-option-length')
end

#tcp_option_length=(tcp_option_length) ⇒ Object


426
427
428
429
430
# File 'lib/cisco_node_utils/ace.rb', line 426

def tcp_option_length=(tcp_option_length)
  @set_args[:tcp_option_length] = Utils.attach_prefix(tcp_option_length,
                                                      :tcp_option_length,
                                                      'tcp-option-length')
end

#time_rangeObject


384
385
386
# File 'lib/cisco_node_utils/ace.rb', line 384

def time_range
  Utils.extract_value(ace_get, 'time_range', 'time-range')
end

#time_range=(time_range) ⇒ Object


388
389
390
391
392
# File 'lib/cisco_node_utils/ace.rb', line 388

def time_range=(time_range)
  @set_args[:time_range] = Utils.attach_prefix(time_range,
                                               :time_range,
                                               'time-range')
end

#ttlObject


404
405
406
# File 'lib/cisco_node_utils/ace.rb', line 404

def ttl
  Utils.extract_value(ace_get, 'ttl')
end

#ttl=(ttl) ⇒ Object


408
409
410
# File 'lib/cisco_node_utils/ace.rb', line 408

def ttl=(ttl)
  @set_args[:ttl] = Utils.attach_prefix(ttl, :ttl)
end

#valid_ipv6?(addr) ⇒ Boolean


204
205
206
207
208
209
210
211
# File 'lib/cisco_node_utils/ace.rb', line 204

def valid_ipv6?(addr)
  begin
    ret = IPAddr.new(addr.split[0]).ipv6?
  rescue
    ret = false
  end
  ret
end

#vlanObject


341
342
343
# File 'lib/cisco_node_utils/ace.rb', line 341

def vlan
  Utils.extract_value(ace_get, 'vlan')
end

#vlan=(vlan) ⇒ Object


345
346
347
# File 'lib/cisco_node_utils/ace.rb', line 345

def vlan=(vlan)
  @set_args[:vlan] = Utils.attach_prefix(vlan, :vlan)
end