junos-ez-stdlib 0.1.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +6 -14
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +8 -0
  5. data/.travis.yml +18 -0
  6. data/CHANGELOG.md +60 -19
  7. data/Gemfile +7 -0
  8. data/README.md +41 -30
  9. data/Rakefile +6 -0
  10. data/SUGGESTION-BOX/README.md +32 -0
  11. data/docs/Providers/Group.md +61 -0
  12. data/docs/Providers/L2ports.md +1 -1
  13. data/docs/Providers/LAGports.md +57 -0
  14. data/docs/Providers/Vlans.md +1 -1
  15. data/examples/config/config_file.rb +0 -0
  16. data/examples/config/config_template_object.rb +0 -0
  17. data/examples/config/config_template_simple.rb +0 -0
  18. data/examples/config/load_sample.conf +129 -0
  19. data/examples/config/load_sample.set +3 -0
  20. data/examples/config/load_template_main.conf +7 -0
  21. data/examples/config/load_template_object.conf +7 -0
  22. data/examples/config/multi_config.rb +0 -0
  23. data/examples/fs_utils.rb +0 -0
  24. data/examples/lag_port.rb +27 -0
  25. data/examples/re_upgrade.rb +0 -0
  26. data/examples/re_utils.rb +0 -0
  27. data/examples/simple.rb +0 -1
  28. data/examples/st_hosts.rb +0 -0
  29. data/examples/user.rb +0 -0
  30. data/examples/vlans.rb +4 -4
  31. data/junos-ez-stdlib.gemspec +25 -14
  32. data/lib/junos-ez/exceptions.rb +0 -0
  33. data/lib/junos-ez/facts.rb +5 -7
  34. data/lib/junos-ez/facts/chassis.rb +6 -0
  35. data/lib/junos-ez/facts/ifd_style.rb +6 -3
  36. data/lib/junos-ez/facts/personality.rb +6 -6
  37. data/lib/junos-ez/facts/switch_style.rb +11 -2
  38. data/lib/junos-ez/facts/version.rb +24 -9
  39. data/lib/junos-ez/group.rb +206 -0
  40. data/lib/junos-ez/ip_ports.rb +0 -0
  41. data/lib/junos-ez/ip_ports/classic.rb +2 -2
  42. data/lib/junos-ez/l1_ports.rb +0 -0
  43. data/lib/junos-ez/l1_ports/classic.rb +0 -0
  44. data/lib/junos-ez/l1_ports/switch.rb +0 -0
  45. data/lib/junos-ez/l2_ports.rb +18 -9
  46. data/lib/junos-ez/l2_ports/bridge_domain.rb +499 -0
  47. data/lib/junos-ez/l2_ports/vlan.rb +3 -3
  48. data/lib/junos-ez/l2_ports/vlan_l2ng.rb +502 -0
  49. data/lib/junos-ez/lag_ports.rb +268 -0
  50. data/lib/junos-ez/provider.rb +4 -8
  51. data/lib/junos-ez/stdlib.rb +2 -0
  52. data/lib/junos-ez/system.rb +0 -0
  53. data/lib/junos-ez/system/users.rb +5 -7
  54. data/lib/junos-ez/utils/config.rb +0 -0
  55. data/lib/junos-ez/utils/fs.rb +0 -0
  56. data/lib/junos-ez/utils/re.rb +0 -0
  57. data/lib/junos-ez/version.rb +4 -1
  58. data/lib/junos-ez/vlans.rb +4 -1
  59. data/lib/junos-ez/vlans/bridge_domain.rb +7 -3
  60. data/lib/junos-ez/vlans/vlan.rb +4 -3
  61. data/lib/junos-ez/vlans/vlan_l2ng.rb +126 -0
  62. metadata +142 -64
@@ -51,7 +51,7 @@ class Junos::Ez::L2ports::Provider::VLAN < Junos::Ez::L2ports::Provider
51
51
  xml_when_item(as_xml.xpath('description')){|i| as_hash[:description] = i.text}
52
52
 
53
53
  f_eth = as_xml.xpath('family/ethernet-switching')
54
- as_hash[:vlan_tagging] = f_eth.xpath('port-mode').text.chomp == 'trunk'
54
+ as_hash[:vlan_tagging] = f_eth.xpath('interface-mode').text.chomp == 'trunk'
55
55
 
56
56
  # obtain a copy of the running state, this is needed in case the config
57
57
  # is located under the [edit vlans] stanza vs. [edit interfaces]
@@ -138,8 +138,8 @@ class Junos::Ez::L2ports::Provider::VLAN < Junos::Ez::L2ports::Provider
138
138
  ## ----------------------------------------------------------------
139
139
 
140
140
  def xml_change_vlan_tagging( xml )
141
- port_mode = should_trunk? ? 'trunk' : 'access'
142
- xml.send(:'port-mode', port_mode )
141
+ interface_mode = should_trunk? ? 'trunk' : 'access'
142
+ xml.send(:'interface-mode', interface_mode )
143
143
 
144
144
  # when the vlan_tagging value changes then this method
145
145
  # will trigger updates to the untagged_vlan and tagged_vlans
@@ -0,0 +1,502 @@
1
+ class Junos::Ez::L2ports::Provider::VLAN_L2NG < Junos::Ez::L2ports::Provider
2
+
3
+ ### ---------------------------------------------------------------
4
+ ### XML top placement
5
+ ### ---------------------------------------------------------------
6
+
7
+ def xml_at_top
8
+ Nokogiri::XML::Builder.new {|xml| xml.configuration {
9
+ xml.interfaces {
10
+ return xml_at_element_top( xml, @name )
11
+ }
12
+ }}
13
+ end
14
+
15
+ # set the edit anchor inside the ethernet-switching stanza
16
+ # we will need to 'up-out' when making changes to the
17
+ # unit information, like description
18
+
19
+ def xml_at_element_top( xml, name )
20
+ xml.interface {
21
+ xml.name name
22
+ xml.send(:'native-vlan-id')
23
+ xml.unit {
24
+ xml.name '0'
25
+ return xml
26
+ }
27
+ }
28
+ end
29
+
30
+ ### ---------------------------------------------------------------
31
+ ### XML property readers
32
+ ### ---------------------------------------------------------------
33
+
34
+ def xml_get_has_xml( xml )
35
+ # second unit contains the family/ethernet-switching stanza
36
+ got = xml.xpath('//unit')[0]
37
+
38
+ # if this resource doesn't exist we need to default some
39
+ # values into has/should variables
40
+
41
+ unless got
42
+ @has[:vlan_tagging] = false
43
+ @should = @has.clone
44
+ end
45
+
46
+ got
47
+ end
48
+
49
+ def xml_read_parser( as_xml, as_hash )
50
+ ## reading is anchored at the [... unit 0 ...] level
51
+ set_has_status( as_xml, as_hash )
52
+
53
+ xml_when_item(as_xml.xpath('description')){|i| as_hash[:description] = i.text}
54
+
55
+ f_eth = as_xml.xpath('family/ethernet-switching')
56
+ as_hash[:vlan_tagging] = f_eth.xpath('interface-mode').text.chomp == 'trunk'
57
+
58
+ # obtain a copy of the running state, this is needed in case the config
59
+ # is located under the [edit vlans] stanza vs. [edit interfaces]
60
+
61
+ ifs_name = @name || as_xml.xpath('ancestor::interface/name').text.strip
62
+ eth_port_vlans = _get_eth_port_vlans_h( ifs_name )
63
+ @under_vlans = []
64
+
65
+ # --- access port
66
+
67
+ if as_hash[:vlan_tagging] == false
68
+ xml_when_item(f_eth.xpath('vlan/members')){ |i| as_hash[:untagged_vlan] = i.text.chomp }
69
+ unless as_hash[:untagged_vlan]
70
+ as_hash[:untagged_vlan] = eth_port_vlans[:untagged]
71
+ @under_vlans << eth_port_vlans[:untagged]
72
+ end
73
+ return
74
+ end
75
+
76
+ # --- trunk port
77
+
78
+ as_hash[:untagged_vlan] ||= eth_port_vlans[:untagged]
79
+ as_hash[:tagged_vlans] = f_eth.xpath('vlan/members').collect { |v| v.text.chomp }.to_set
80
+ (eth_port_vlans[:tagged] - as_hash[:tagged_vlans]).each do |vlan|
81
+ as_hash[:tagged_vlans] << vlan
82
+ @under_vlans << vlan
83
+ end
84
+
85
+ # native-vlan-id is set at the interface level, and is the VLAN-ID, not the vlan
86
+ # name. So we need to do a bit of translating here. The *ASSUMPTION* is that the
87
+ # native-vlan-id value is a given VLAN in the tagged_vlan list. So we will use
88
+ # that list to do the reverse lookup on the tag-id => name
89
+
90
+ xml_when_item(f_eth.xpath('ancestor::interface/native-vlan-id')){ |i|
91
+ as_hash[:untagged_vlan] = _vlan_tag_id_to_name( i.text.chomp, as_hash )
92
+ }
93
+ end
94
+
95
+ ### ---------------------------------------------------------------
96
+ ### XML on_create, on_delete handlers
97
+ ### ---------------------------------------------------------------
98
+
99
+ ## overload the xml_on_delete method since we may need
100
+ ## to do some cleanup work in the [edit vlans] stanza
101
+
102
+ def xml_on_delete( xml )
103
+ @ifd = xml.instance_variable_get(:@parent).at_xpath('ancestor::interface')
104
+ @ifd.xpath('//native-vlan-id').remove ## remove the element from the get-config
105
+
106
+ return unless @under_vlans
107
+ return if @under_vlans.empty?
108
+
109
+ _xml_rm_under_vlans( xml, @under_vlans )
110
+ end
111
+
112
+ ### ---------------------------------------------------------------
113
+ ### XML property writers
114
+ ### ---------------------------------------------------------------
115
+
116
+ def xml_at_here( xml )
117
+ @ifd = xml.instance_variable_get(:@parent).at_xpath('ancestor::interface')
118
+ @ifd.xpath('//native-vlan-id').remove ## remove the element from the get-config
119
+
120
+ xml.family {
121
+ xml.send(:'ethernet-switching') {
122
+ return xml
123
+ }
124
+ }
125
+ end
126
+
127
+ def xml_build_change( nop = nil )
128
+ @under_vlans ||= [] # handles case for create'd port
129
+
130
+ if mode_changed?
131
+ @should[:untagged_vlan] ||= @has[:untagged_vlan]
132
+ end
133
+
134
+ super xml_at_here( xml_at_top )
135
+ end
136
+
137
+ ## ----------------------------------------------------------------
138
+ ## :description
139
+ ## ----------------------------------------------------------------
140
+
141
+ ## overload default method since we need to "up-out" of the
142
+ ## ethernet-switching stanza
143
+
144
+ def xml_change_description( xml )
145
+ unit = xml.parent.xpath('ancestor::unit')[0]
146
+ Nokogiri::XML::Builder.with( unit ){ |x|
147
+ xml_set_or_delete( x, 'description', @should[:description] )
148
+ }
149
+ end
150
+
151
+ ## ----------------------------------------------------------------
152
+ ## :vlan_tagging
153
+ ## ----------------------------------------------------------------
154
+
155
+ def xml_change_vlan_tagging( xml )
156
+ port_mode = should_trunk? ? 'trunk' : 'access'
157
+ xml.send(:'interface-mode', port_mode )
158
+
159
+ # when the vlan_tagging value changes then this method
160
+ # will trigger updates to the untagged_vlan and tagged_vlans
161
+ # resource values as well.
162
+ # !!! DO NOT SWAP THIS ORDER untagged processing *MUST* BE FIRST!
163
+
164
+ upd_untagged_vlan( xml )
165
+ upd_tagged_vlans( xml )
166
+
167
+ return true
168
+ end
169
+
170
+ ## ----------------------------------------------------------------
171
+ ## :tagged_vlans
172
+ ## ----------------------------------------------------------------
173
+
174
+ def xml_change_tagged_vlans( xml )
175
+ return false if mode_changed?
176
+ upd_tagged_vlans( xml )
177
+ end
178
+
179
+ def upd_tagged_vlans( xml )
180
+ return false unless should_trunk?
181
+
182
+ @should[:tagged_vlans] = @should[:tagged_vlans].to_set if @should[:tagged_vlans].kind_of? Array
183
+ @has[:tagged_vlans] = @has[:tagged_vlans].to_set if @has[:tagged_vlans].kind_of? Array
184
+
185
+ v_should = @should[:tagged_vlans] || Set.new
186
+ v_has = @has[:tagged_vlans] || Set.new
187
+
188
+ del = v_has - v_should
189
+ add = v_should - v_has
190
+
191
+ del_under_vlans = del & @under_vlans
192
+
193
+ unless del_under_vlans.empty?
194
+ del = del ^ @under_vlans
195
+ _xml_rm_under_vlans( xml, del_under_vlans )
196
+ @under_vlans = []
197
+ end
198
+
199
+ if add or del
200
+ xml.vlan {
201
+ del.each { |v| xml.members v, Netconf::JunosConfig::DELETE }
202
+ add.each { |v| xml.members v }
203
+ }
204
+ end
205
+
206
+ return true
207
+ end
208
+
209
+ ## ----------------------------------------------------------------
210
+ ## :untagged_vlan
211
+ ## ----------------------------------------------------------------
212
+
213
+ def xml_change_untagged_vlan( xml )
214
+ return false if mode_changed?
215
+ upd_untagged_vlan( xml )
216
+ end
217
+
218
+ def upd_untagged_vlan( xml )
219
+ self.class.change_untagged_vlan( self, xml )
220
+ end
221
+
222
+ end
223
+
224
+ ##### ---------------------------------------------------------------
225
+ ##### Class methods for handling state-transitions between
226
+ ##### configurations (tagged/untagged)
227
+ ##### ---------------------------------------------------------------
228
+
229
+ class Junos::Ez::L2ports::Provider::VLAN_L2NG
230
+
231
+ # creating some class definitions ...
232
+ # this is a bit complicated because we need to handle port-mode
233
+ # change transitions; basically dealing with the fact that
234
+ # trunk ports use 'native-vlan-id' and access ports have a
235
+ # vlan member definition; i.e. they don't use native-vlan-id, ugh.
236
+ # Rather than doing all this logic as if/then/else statements,
237
+ # I've opted to using a proc jump-table technique. Lessons
238
+ # learned from lots of embedded systems programming :-)
239
+
240
+ def self.init_jump_table
241
+
242
+ # auto-hash table, majik!
243
+ hash = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)}))
244
+
245
+ # ------------------------------------------------------------------
246
+ # - jump table for handling various untagged vlan change use-cases
247
+ # ------------------------------------------------------------------
248
+ # There are three criteria for selection:
249
+ # | is_trunk | will_trunk | no_untg |
250
+ # ------------------------------------------------------------------
251
+
252
+ # - will not have untagged vlan
253
+ hash[false][false][true] = self.method(:ac_ac_nountg)
254
+ hash[false][true][true] = self.method(:ac_tr_nountg)
255
+ hash[true][false][true] = self.method(:tr_ac_nountg)
256
+ hash[true][true][true] = self.method(:tr_tr_nountg)
257
+
258
+ # - will have untagged vlan
259
+ hash[false][false][false] = self.method(:ac_ac_untg)
260
+ hash[false][true][false] = self.method(:ac_tr_untg)
261
+ hash[true][false][false] = self.method(:tr_ac_untg)
262
+ hash[true][true][false] = self.method(:tr_tr_untg)
263
+
264
+ hash
265
+ end
266
+
267
+ ### invoke the correct method from the jump table
268
+ ### based on the three criteria to select the action
269
+
270
+ def self.change_untagged_vlan( this, xml )
271
+ @@ez_l2_jmptbl ||= init_jump_table
272
+ proc = @@ez_l2_jmptbl[this.is_trunk?][this.should_trunk?][this.should[:untagged_vlan].nil?]
273
+ proc.call( this, xml )
274
+ end
275
+
276
+ ### -------------------------------------------------------------
277
+ ### The following are all the change transition functions for
278
+ ### each of the use-cases
279
+ ### -------------------------------------------------------------
280
+
281
+ def self.ac_ac_nountg( this, xml )
282
+ this._xml_rm_ac_untagged_vlan( xml )
283
+ end
284
+
285
+ def self.ac_tr_nountg( this, xml )
286
+ unless (untg_vlan = this.has[:untagged_vlan]).nil?
287
+ this._xml_rm_ac_untagged_vlan( xml )
288
+ end
289
+ end
290
+
291
+ def self.tr_ac_nountg( this, xml )
292
+ this._delete_native_vlan_id( xml )
293
+ this._xml_rm_these_vlans( xml, this.has[:tagged_vlans ] ) if this.has[:tagged_vlans]
294
+ end
295
+
296
+ def self.tr_tr_nountg( this, xml )
297
+ this._delete_native_vlan_id( xml )
298
+ end
299
+
300
+ ## ----------------------------------------------------------------
301
+ ## transition where port WILL-HAVE untagged-vlan
302
+ ## ----------------------------------------------------------------
303
+
304
+ def self.ac_ac_untg( this, xml )
305
+ this._xml_rm_ac_untagged_vlan( xml )
306
+ xml.vlan {
307
+ xml.members this.should[:untagged_vlan]
308
+ }
309
+ end
310
+
311
+ def self.ac_tr_untg( this, xml )
312
+ # move untagged vlan to native-vlan-id ...
313
+ was_untg_vlan = this.has[:untagged_vlan]
314
+ this._set_native_vlan_id( xml, this.should[:untagged_vlan] )
315
+ this._xml_rm_ac_untagged_vlan( xml ) if was_untg_vlan
316
+ end
317
+
318
+ def self.tr_ac_untg( this, xml )
319
+ this._delete_native_vlan_id( xml )
320
+ this._xml_rm_these_vlans( xml, this.has[:tagged_vlans ] ) if this.has[:tagged_vlans]
321
+ xml.vlan { xml.members this.should[:untagged_vlan] }
322
+ end
323
+
324
+ def self.tr_tr_untg( this, xml )
325
+ this._set_native_vlan_id( xml, this.should[:untagged_vlan] )
326
+ end
327
+ end
328
+
329
+ ##### ---------------------------------------------------------------
330
+ ##### Provider collection methods
331
+ ##### ---------------------------------------------------------------
332
+
333
+ class Junos::Ez::L2ports::Provider::VLAN_L2NG
334
+
335
+ def build_list
336
+ begin
337
+ got = @ndev.rpc.get_ethernet_switching_interface_information( :brief => true)
338
+ rescue => e
339
+ # in this case, no ethernet-switching is enabled so return empty list
340
+ return []
341
+ end
342
+ got.xpath('//l2iff-interface-name').collect{ |ifn| ifn.text.split('.')[0] }
343
+ end
344
+
345
+ def build_catalog
346
+ @catalog = {}
347
+ return @catalog if list!.empty?
348
+
349
+ list.each do |ifs_name|
350
+ @ndev.rpc.get_configuration{ |xml|
351
+ xml.interfaces {
352
+ xml_at_element_top( xml, ifs_name )
353
+ }
354
+ }.xpath('interfaces/interface').each do |ifs_xml|
355
+ @catalog[ifs_name] = {}
356
+ unit = xml_get_has_xml( ifs_xml )
357
+ xml_read_parser( unit, @catalog[ifs_name] )
358
+ end
359
+ end
360
+
361
+ @catalog
362
+ end
363
+
364
+ end
365
+
366
+ ##### ---------------------------------------------------------------
367
+ ##### !!!!! PRIVATE METHODS !!!!
368
+ ##### ---------------------------------------------------------------
369
+
370
+ class Junos::Ez::L2ports::Provider::VLAN_L2NG
371
+ private
372
+
373
+ def _get_eth_port_vlans_h( ifs_name )
374
+
375
+ got = @ndev.rpc.get_ethernet_switching_interface_information(:interface_name => ifs_name)
376
+ ret_h = {:untagged => nil, :tagged => Set.new }
377
+ got.xpath('//l2ng-l2ald-iff-interface-entry').each do |vlan|
378
+ # one of the node-set elements (the first one?) contains the interface name.
379
+ # this doesn't have any VLAN information, so skip it.
380
+ next if vlan.xpath('l2iff-interface-name')
381
+
382
+ vlan_name = vlan.xpath('l2iff-interface-vlan-name').text.strip
383
+ tgdy = vlan.xpath('l2iff-interface-vlan-member-tagness').text.strip
384
+ if tgdy == 'untagged'
385
+ ret_h[:untagged] = vlan_name
386
+ else
387
+ ret_h[:tagged] << vlan_name
388
+ end
389
+ end
390
+ ret_h
391
+ end
392
+
393
+ end
394
+
395
+
396
+ ### ---------------------------------------------------------------
397
+ ### [edit vlans] - for interfaces configured here ...
398
+ ### ---------------------------------------------------------------
399
+
400
+ class Junos::Ez::L2ports::Provider::VLAN_L2NG
401
+
402
+ def _xml_edit_under_vlans( xml )
403
+ Nokogiri::XML::Builder.with( xml.doc.root ) do |dot|
404
+ dot.vlans {
405
+ return dot
406
+ }
407
+ end
408
+ end
409
+
410
+ def _xml_rm_under_vlans( xml, vlans )
411
+ if vlans.any?
412
+ at_vlans = _xml_edit_under_vlans( xml )
413
+ vlans.each do |vlan_name|
414
+ Nokogiri::XML::Builder.with( at_vlans.parent ) do |this|
415
+ this.vlan {
416
+ this.name vlan_name
417
+ this.interface( Netconf::JunosConfig::DELETE ) { this.name @name }
418
+ }
419
+ end
420
+ end
421
+ end
422
+ end
423
+
424
+ def _xml_rm_ac_untagged_vlan( xml )
425
+ if @under_vlans.empty?
426
+ xml.vlan Netconf::JunosConfig::DELETE
427
+ else
428
+ _xml_rm_under_vlans( xml, [ @has[:untagged_vlan ] ] )
429
+ @under_vlans = []
430
+ end
431
+ end
432
+
433
+ def _xml_rm_these_vlans( xml, vlans )
434
+ if @under_vlans.empty?
435
+ xml.vlan( Netconf::JunosConfig::DELETE )
436
+ else
437
+ # could be a mix between [edit vlans] and [edit interfaces] ...
438
+ v_has = vlans.to_set
439
+ del_under_vlans = v_has & @under_vlans
440
+ _xml_rm_under_vlans( xml, del_under_vlans )
441
+ if v_has ^ @under_vlans
442
+ xml.vlan( Netconf::JunosConfig::DELETE )
443
+ end
444
+ @under_vlans = []
445
+ end
446
+ end
447
+
448
+ end
449
+
450
+
451
+ class Junos::Ez::L2ports::Provider::VLAN_L2NG
452
+
453
+ def _vlan_name_to_tag_id( vlan_name )
454
+ tag_id = @ndev.rpc.get_configuration { |xml|
455
+ xml.vlans { xml.vlan { xml.name vlan_name }}
456
+ }.xpath('//vlan-id').text.chomp
457
+
458
+ raise ArgumentError, "VLAN '#{vlan_name}' not found" if tag_id.empty?
459
+ return tag_id
460
+ end
461
+
462
+ def _vlan_tag_id_to_name( tag_id, my_hash )
463
+ # get the candidate configuration for each VLAN named in tagged_vlans and
464
+ # then map it to the corresponding vlan-id. this is not very effecient, but
465
+ # at present there is no other way without getting into a cache mech.
466
+ vlan_name = @ndev.rpc.get_configuration { |xml|
467
+ xml.vlans {
468
+ my_hash[:tagged_vlans].each do |v_name|
469
+ xml.vlan {
470
+ xml.name v_name
471
+ xml.send(:'vlan-id')
472
+ }
473
+ end
474
+ }
475
+ }.xpath("//vlan[vlan-id = '#{tag_id}']/name").text.chomp
476
+
477
+ raise ArgumentError, "VLAN-ID '#{tag_id}' not found" if vlan_name.empty?
478
+ return vlan_name
479
+ end
480
+
481
+ end
482
+
483
+ class Junos::Ez::L2ports::Provider::VLAN_L2NG
484
+ def _at_native_vlan_id( xml )
485
+
486
+ ifd
487
+ end
488
+
489
+ def _delete_native_vlan_id( xml )
490
+ Nokogiri::XML::Builder.with( @ifd ) do |dot|
491
+ dot.send :'native-vlan-id', Netconf::JunosConfig::DELETE
492
+ end
493
+ return true
494
+ end
495
+
496
+ def _set_native_vlan_id( xml, vlan_name )
497
+ Nokogiri::XML::Builder.with( @ifd ) do |dot|
498
+ dot.send :'native-vlan-id', _vlan_name_to_tag_id( vlan_name )
499
+ end
500
+ return true
501
+ end
502
+ end