Class: Cisco::Vlan

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

Overview

Vlan - node utility class for VLAN configuration management

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(vlan_id, instantiate = true) ⇒ Vlan

Returns a new instance of Vlan.



31
32
33
34
35
36
37
# File 'lib/cisco_node_utils/vlan.rb', line 31

def initialize(vlan_id, instantiate=true)
  @vlan_id = vlan_id.to_s
  fail ArgumentError,
       'Invalid value(non-numeric Vlan id)' unless @vlan_id[/^\d+$/]

  create if instantiate
end

Instance Attribute Details

#vlan_idObject (readonly)

Returns the value of attribute vlan_id.



29
30
31
# File 'lib/cisco_node_utils/vlan.rb', line 29

def vlan_id
  @vlan_id
end

Class Method Details

.vlansObject



43
44
45
46
47
48
49
50
51
52
# File 'lib/cisco_node_utils/vlan.rb', line 43

def self.vlans
  hash = {}
  vlan_list = config_get('vlan', 'all_vlans')
  return hash if vlan_list.nil?

  vlan_list.each do |id|
    hash[id] = Vlan.new(id, false)
  end
  hash
end

Instance Method Details

#add_interface(interface) ⇒ Object



201
202
203
# File 'lib/cisco_node_utils/vlan.rb', line 201

def add_interface(interface)
  interface.access_vlan = @vlan_id
end

#cli_error_check(result, ignore_message = nil) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cisco_node_utils/vlan.rb', line 62

def cli_error_check(result, ignore_message=nil)
  # The NXOS vlan cli does not raise an exception in some conditions and
  # instead just displays a STDOUT error message; thus NXAPI does not detect
  # the failure and we must catch it by inspecting the "body" hash entry
  # returned by NXAPI. This vlan cli behavior is unlikely to change.
  # Check for messages that can be safely ignored.

  errors = /(ERROR:|VLAN:|Warning:)/

  return unless
    result[2].is_a?(Hash) && errors.match(result[2]['body'].to_s)
  # Split errors into a list, but keep the delimiter as part of the message.
  error_list =
    (result[2]['body'].split(errors) - ['']).each_slice(2).map(&:join)
  error_list.each do |msg|
    next if ignore_message && msg.to_s.include?(ignore_message)
    fail result[2]['body']
  end
end

#createObject



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

def create
  config_set('vlan', 'create', @vlan_id)
end

#default_fabric_controlObject



103
104
105
# File 'lib/cisco_node_utils/vlan.rb', line 103

def default_fabric_control
  config_get_default('vlan', 'fabric_control')
end

#default_mapped_vniObject



235
236
237
# File 'lib/cisco_node_utils/vlan.rb', line 235

def default_mapped_vni
  config_get_default('vlan', 'mapped_vni')
end

#default_modeObject



138
139
140
# File 'lib/cisco_node_utils/vlan.rb', line 138

def default_mode
  config_get_default('vlan', 'mode')
end

#default_private_vlan_associationObject



274
275
276
# File 'lib/cisco_node_utils/vlan.rb', line 274

def default_private_vlan_association
  config_get_default('vlan', 'private_vlan_association')
end

#default_private_vlan_typeObject



260
261
262
# File 'lib/cisco_node_utils/vlan.rb', line 260

def default_private_vlan_type
  config_get_default('vlan', 'private_vlan_type')
end

#default_shutdownObject



197
198
199
# File 'lib/cisco_node_utils/vlan.rb', line 197

def default_shutdown
  config_get_default('vlan', 'shutdown')
end

#default_stateObject



181
182
183
# File 'lib/cisco_node_utils/vlan.rb', line 181

def default_state
  config_get_default('vlan', 'state')
end

#default_vlan_nameObject



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

def default_vlan_name
  sprintf('VLAN%04d', @vlan_id)
end

#destroyObject



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

def destroy
  config_set('vlan', 'destroy', @vlan_id)
end

#fabric_controlObject



92
93
94
# File 'lib/cisco_node_utils/vlan.rb', line 92

def fabric_control
  config_get('vlan', 'fabric_control', vlan: @vlan_id)
end

#fabric_control=(val) ⇒ Object



96
97
98
99
100
101
# File 'lib/cisco_node_utils/vlan.rb', line 96

def fabric_control=(val)
  no_cmd = (val) ? '' : 'no'
  result = config_set('vlan', 'fabric_control', vlan:  @vlan_id,
                                                state: no_cmd)
  cli_error_check(result)
end

#fabricpath_featureObject



107
108
109
# File 'lib/cisco_node_utils/vlan.rb', line 107

def fabricpath_feature
  FabricpathGlobal.fabricpath_feature
end

#fabricpath_feature_set(fabricpath_set) ⇒ Object



111
112
113
# File 'lib/cisco_node_utils/vlan.rb', line 111

def fabricpath_feature_set(fabricpath_set)
  FabricpathGlobal.fabricpath_feature_set(fabricpath_set)
end

#interfacesObject



209
210
211
212
213
214
215
216
217
218
# File 'lib/cisco_node_utils/vlan.rb', line 209

def interfaces
  all_interfaces = Interface.interfaces
  interfaces = {}
  all_interfaces.each do |name, i|
    next unless i.switchport_mode == :access
    next unless i.access_vlan.to_i == @vlan_id.to_i
    interfaces[name] = i
  end
  interfaces
end

#mapped_vniObject



220
221
222
# File 'lib/cisco_node_utils/vlan.rb', line 220

def mapped_vni
  config_get('vlan', 'mapped_vni', vlan: @vlan_id)
end

#mapped_vni=(vni) ⇒ Object



224
225
226
227
228
229
230
231
232
233
# File 'lib/cisco_node_utils/vlan.rb', line 224

def mapped_vni=(vni)
  Feature.vn_segment_vlan_based_enable
  # Remove the existing mapping first as cli doesn't support overwriting.
  config_set('vlan', 'mapped_vni', vlan: @vlan_id,
                     state: 'no', vni: vni)
  # Configure the new mapping
  state = vni == default_mapped_vni ? 'no' : ''
  config_set('vlan', 'mapped_vni', vlan: @vlan_id,
                      state: state, vni: vni)
end

#modeObject



115
116
117
118
119
120
121
122
123
124
# File 'lib/cisco_node_utils/vlan.rb', line 115

def mode
  result = config_get('vlan', 'mode', @vlan_id)
  return default_mode if result.nil?
  # Note: The yaml definition for this property
  # uses 'multiple' as a workaround for a bug
  # in the N7k nxapi code which displays
  # the 'show vlan' output twice.
  result[0].downcase! if result[0][/FABRICPATH/]
  result[0]
end

#mode=(str) ⇒ Object



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

def mode=(str)
  if str == default_mode
    config_set('vlan', 'mode', @vlan_id, 'no', '')
  else
    if 'fabricpath' == str
      fabricpath_feature_set(:enabled) unless
        :enabled == fabricpath_feature
    end
    config_set('vlan', 'mode', @vlan_id, '', str)
  end
end

#private_vlan_associationObject



264
265
266
267
# File 'lib/cisco_node_utils/vlan.rb', line 264

def private_vlan_association
  return nil unless Feature.private_vlan_enabled?
  config_get('vlan', 'private_vlan_association', id: @vlan_id)
end

#private_vlan_association=(vlan_list) ⇒ Object



269
270
271
272
# File 'lib/cisco_node_utils/vlan.rb', line 269

def private_vlan_association=(vlan_list)
  Feature.private_vlan_enable
  vlan_list_delta(private_vlan_association, vlan_list)
end

#private_vlan_typeObject



239
240
241
242
# File 'lib/cisco_node_utils/vlan.rb', line 239

def private_vlan_type
  return nil unless Feature.private_vlan_enabled?
  config_get('vlan', 'private_vlan_type', id: @vlan_id)
end

#private_vlan_type=(type) ⇒ Object



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/cisco_node_utils/vlan.rb', line 244

def private_vlan_type=(type)
  Feature.private_vlan_enable
  fail TypeError unless type && type.is_a?(String)

  if type == default_private_vlan_type
    return if private_vlan_type.empty?
    set_args_keys(state: 'no', type: private_vlan_type)
    ignore_msg = 'Warning: Private-VLAN CLI removed'
  else
    set_args_keys(state: '', type: type)
    ignore_msg = 'Warning: Private-VLAN CLI entered'
  end
  result = config_set('vlan', 'private_vlan_type', @set_args)
  cli_error_check(result, ignore_msg)
end

#remove_interface(interface) ⇒ Object



205
206
207
# File 'lib/cisco_node_utils/vlan.rb', line 205

def remove_interface(interface)
  interface.access_vlan = interface.default_access_vlan
end

#set_args_keys(hash = {}) ⇒ Object

rubocop:disable Style/AccessorMethodName



87
88
89
90
# File 'lib/cisco_node_utils/vlan.rb', line 87

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

#set_args_keys_defaultObject



82
83
84
85
# File 'lib/cisco_node_utils/vlan.rb', line 82

def set_args_keys_default
  keys = { vlan: @vlan_id }
  @set_args = keys
end

#shutdownObject



185
186
187
188
189
# File 'lib/cisco_node_utils/vlan.rb', line 185

def shutdown
  result = config_get('vlan', 'shutdown', @vlan_id)
  # Valid result is either: "active"(aka no shutdown) or "shutdown"
  result[/shut/] ? true : false
end

#shutdown=(val) ⇒ Object



191
192
193
194
195
# File 'lib/cisco_node_utils/vlan.rb', line 191

def shutdown=(val)
  no_cmd = (val) ? '' : 'no'
  result = config_set('vlan', 'shutdown', @vlan_id, no_cmd)
  cli_error_check(result)
end

#stateObject



161
162
163
164
165
166
167
168
169
# File 'lib/cisco_node_utils/vlan.rb', line 161

def state
  result = config_get('vlan', 'state', @vlan_id)
  case result
  when /act/
    return 'active'
  when /sus/
    return 'suspend'
  end
end

#state=(str) ⇒ Object



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

def state=(str)
  str = str.to_s
  if str.empty?
    result = config_set('vlan', 'state', @vlan_id, 'no', '')
  else
    result = config_set('vlan', 'state', @vlan_id, '', str)
  end
  cli_error_check(result)
end

#to_sObject



39
40
41
# File 'lib/cisco_node_utils/vlan.rb', line 39

def to_s
  "VLAN #{vlan_id}"
end

#vlan_list_delta(is_list, should_list) ⇒ Object


vlan_list_delta is a helper function for the private_vlan_association property. It walks the delta hash and adds/removes each target private vlan. This api is used by private vlan to prepare the input to the setter method. The input can be in the following formats for vlans: 10-12,14. Prepare_array api is transforming this input into a flat array. In the example above the returned array will be 10, 11, 12, 14. Prepare array is first splitting the input on ‘,’ and the than expanding the vlan range element like 10-12 into a flat array. The final result will be a flat array. This way we can later used the lib utility to check the delta from the input vlan value and the vlan configured to apply the right config.



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
329
# File 'lib/cisco_node_utils/vlan.rb', line 292

def vlan_list_delta(is_list, should_list)
  new_list = []
  should_list.each do |item|
    if item.include?(',')
      new_list.push(item.split(','))
    else
      new_list.push(item)
    end
  end
  new_list.flatten!
  new_list.sort!

  new_list.each { |item| item.gsub!('-', '..') }

  should_list_new = []
  new_list.each do |elem|
    if elem.include?('..')
      elema = elem.split('..').map { |d| Integer(d) }
      elema.sort!
      tr = elema[0]..elema[1]
      tr.to_a.each do |item|
        should_list_new.push(item.to_s)
      end
    else
      should_list_new.push(elem)
    end
  end

  delta_hash = Utils.delta_add_remove(should_list_new, is_list)
  [:add, :remove].each do |action|
    delta_hash[action].each do |vlans|
      state = (action == :add) ? '' : 'no'
      set_args_keys(state: state, vlans: vlans)
      result = config_set('vlan', 'private_vlan_association', @set_args)
      cli_error_check(result)
    end
  end
end

#vlan_nameObject



142
143
144
145
# File 'lib/cisco_node_utils/vlan.rb', line 142

def vlan_name
  result = config_get('vlan', 'name', @vlan_id)
  result.nil? ? default_vlan_name : result
end

#vlan_name=(str) ⇒ Object



147
148
149
150
151
152
153
154
155
# File 'lib/cisco_node_utils/vlan.rb', line 147

def vlan_name=(str)
  fail TypeError unless str.is_a?(String)
  if str.empty?
    result = config_set('vlan', 'name', @vlan_id, 'no', '')
  else
    result = config_set('vlan', 'name', @vlan_id, '', str)
  end
  cli_error_check(result)
end