Class: Junos::Ez::L2ports::Provider::VLAN_L2NG
- Inherits:
-
Junos::Ez::L2ports::Provider
show all
- Defined in:
- lib/junos-ez/l2_ports/vlan_l2ng.rb,
lib/junos-ez/l2_ports/vlan_l2ng.rb,
lib/junos-ez/l2_ports/vlan_l2ng.rb,
lib/junos-ez/l2_ports/vlan_l2ng.rb,
lib/junos-ez/l2_ports/vlan_l2ng.rb,
lib/junos-ez/l2_ports/vlan_l2ng.rb,
lib/junos-ez/l2_ports/vlan_l2ng.rb
Overview
Instance Attribute Summary
#catalog, #has, #list, #name, #ndev, #parent, #properties, #providers, #should
Class Method Summary
collapse
Instance Method Summary
collapse
#is_trunk?, #mode_changed?, #should_trunk?, #xml_change__active
#[], #[]=, #activate!, #active?, #catalog!, #create, #create!, #create_from_hash!, #create_from_yaml!, #deactivate!, #delete!, #each, #exists?, #init_has, #initialize, #is_new?, #is_provider?, #list!, #name_decorated, #need_write?, #read!, #rename!, #reorder!, #select, #to_h, #to_h_expanded, #to_yaml, #with, #write!, #xml_at_edit, #xml_change__active, #xml_change__exist, #xml_change_admin, #xml_config_read!, #xml_element_newname, #xml_on_create
Class Method Details
.ac_ac_nountg(this, xml) ⇒ Object
The following are all the change transition functions for each of the use-cases
281
282
283
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 281
def self.ac_ac_nountg( this, xml )
this._xml_rm_ac_untagged_vlan( xml )
end
|
.ac_ac_untg(this, xml) ⇒ Object
transition where port WILL-HAVE untagged-vlan
304
305
306
307
308
309
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 304
def self.ac_ac_untg( this, xml )
this._xml_rm_ac_untagged_vlan( xml )
xml.vlan {
xml.members this.should[:untagged_vlan]
}
end
|
.ac_tr_nountg(this, xml) ⇒ Object
285
286
287
288
289
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 285
def self.ac_tr_nountg( this, xml )
unless (untg_vlan = this.has[:untagged_vlan]).nil?
this._xml_rm_ac_untagged_vlan( xml )
end
end
|
.ac_tr_untg(this, xml) ⇒ Object
311
312
313
314
315
316
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 311
def self.ac_tr_untg( this, xml )
was_untg_vlan = this.has[:untagged_vlan]
this._set_native_vlan_id( xml, this.should[:untagged_vlan] )
this._xml_rm_ac_untagged_vlan( xml ) if was_untg_vlan
end
|
.change_untagged_vlan(this, xml) ⇒ Object
invoke the correct method from the jump table based on the three criteria to select the action
270
271
272
273
274
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 270
def self.change_untagged_vlan( this, xml )
@@ez_l2_jmptbl ||= init_jump_table
proc = @@ez_l2_jmptbl[this.is_trunk?][this.should_trunk?][this.should[:untagged_vlan].nil?]
proc.call( this, xml )
end
|
.init_jump_table ⇒ Object
creating some class definitions … this is a bit complicated because we need to handle port-mode change transitions; basically dealing with the fact that trunk ports use ‘native-vlan-id’ and access ports have a vlan member definition; i.e. they don’t use native-vlan-id, ugh. Rather than doing all this logic as if/then/else statements, I’ve opted to using a proc jump-table technique. Lessons learned from lots of embedded systems programming :-)
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 240
def self.init_jump_table
hash = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)}))
hash[false][false][true] = self.method(:ac_ac_nountg)
hash[false][true][true] = self.method(:ac_tr_nountg)
hash[true][false][true] = self.method(:tr_ac_nountg)
hash[true][true][true] = self.method(:tr_tr_nountg)
hash[false][false][false] = self.method(:ac_ac_untg)
hash[false][true][false] = self.method(:ac_tr_untg)
hash[true][false][false] = self.method(:tr_ac_untg)
hash[true][true][false] = self.method(:tr_tr_untg)
hash
end
|
.tr_ac_nountg(this, xml) ⇒ Object
291
292
293
294
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 291
def self.tr_ac_nountg( this, xml )
this._delete_native_vlan_id( xml )
this._xml_rm_these_vlans( xml, this.has[:tagged_vlans ] ) if this.has[:tagged_vlans]
end
|
.tr_ac_untg(this, xml) ⇒ Object
318
319
320
321
322
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 318
def self.tr_ac_untg( this, xml )
this._delete_native_vlan_id( xml )
this._xml_rm_these_vlans( xml, this.has[:tagged_vlans ] ) if this.has[:tagged_vlans]
xml.vlan { xml.members this.should[:untagged_vlan] }
end
|
.tr_tr_nountg(this, xml) ⇒ Object
296
297
298
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 296
def self.tr_tr_nountg( this, xml )
this._delete_native_vlan_id( xml )
end
|
.tr_tr_untg(this, xml) ⇒ Object
324
325
326
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 324
def self.tr_tr_untg( this, xml )
this._set_native_vlan_id( xml, this.should[:untagged_vlan] )
end
|
Instance Method Details
#_at_native_vlan_id(xml) ⇒ Object
484
485
486
487
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 484
def _at_native_vlan_id( xml )
ifd
end
|
#_delete_native_vlan_id(xml) ⇒ Object
489
490
491
492
493
494
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 489
def _delete_native_vlan_id( xml )
Nokogiri::XML::Builder.with( @ifd ) do |dot|
dot.send :'native-vlan-id', Netconf::JunosConfig::DELETE
end
return true
end
|
#_set_native_vlan_id(xml, vlan_name) ⇒ Object
496
497
498
499
500
501
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 496
def _set_native_vlan_id( xml, vlan_name )
Nokogiri::XML::Builder.with( @ifd ) do |dot|
dot.send :'native-vlan-id', _vlan_name_to_tag_id( vlan_name )
end
return true
end
|
#_vlan_name_to_tag_id(vlan_name) ⇒ Object
453
454
455
456
457
458
459
460
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 453
def _vlan_name_to_tag_id( vlan_name )
tag_id = @ndev.rpc.get_configuration { |xml|
xml.vlans { xml.vlan { xml.name vlan_name }}
}.xpath('//vlan-id').text.chomp
raise ArgumentError, "VLAN '#{vlan_name}' not found" if tag_id.empty?
return tag_id
end
|
#_vlan_tag_id_to_name(tag_id, my_hash) ⇒ Object
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 462
def _vlan_tag_id_to_name( tag_id, my_hash )
vlan_name = @ndev.rpc.get_configuration { |xml|
xml.vlans {
my_hash[:tagged_vlans].each do |v_name|
xml.vlan {
xml.name v_name
xml.send(:'vlan-id')
}
end
}
}.xpath("//vlan[vlan-id = '#{tag_id}']/name").text.chomp
raise ArgumentError, "VLAN-ID '#{tag_id}' not found" if vlan_name.empty?
return vlan_name
end
|
#_xml_edit_under_vlans(xml) ⇒ Object
402
403
404
405
406
407
408
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 402
def _xml_edit_under_vlans( xml )
Nokogiri::XML::Builder.with( xml.doc.root ) do |dot|
dot.vlans {
return dot
}
end
end
|
#_xml_rm_ac_untagged_vlan(xml) ⇒ Object
424
425
426
427
428
429
430
431
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 424
def _xml_rm_ac_untagged_vlan( xml )
if @under_vlans.empty?
xml.vlan Netconf::JunosConfig::DELETE
else
_xml_rm_under_vlans( xml, [ @has[:untagged_vlan ] ] )
@under_vlans = []
end
end
|
#_xml_rm_these_vlans(xml, vlans) ⇒ Object
433
434
435
436
437
438
439
440
441
442
443
444
445
446
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 433
def _xml_rm_these_vlans( xml, vlans )
if @under_vlans.empty?
xml.vlan( Netconf::JunosConfig::DELETE )
else
v_has = vlans.to_set
del_under_vlans = v_has & @under_vlans
_xml_rm_under_vlans( xml, del_under_vlans )
if v_has ^ @under_vlans
xml.vlan( Netconf::JunosConfig::DELETE )
end
@under_vlans = []
end
end
|
#_xml_rm_under_vlans(xml, vlans) ⇒ Object
410
411
412
413
414
415
416
417
418
419
420
421
422
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 410
def _xml_rm_under_vlans( xml, vlans )
if vlans.any?
at_vlans = _xml_edit_under_vlans( xml )
vlans.each do |vlan_name|
Nokogiri::XML::Builder.with( at_vlans.parent ) do |this|
this.vlan {
this.name vlan_name
this.interface( Netconf::JunosConfig::DELETE ) { this.name @name }
}
end
end
end
end
|
#build_catalog ⇒ Object
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 345
def build_catalog
@catalog = {}
return @catalog if list!.empty?
list.each do |ifs_name|
@ndev.rpc.get_configuration{ |xml|
xml.interfaces {
xml_at_element_top( xml, ifs_name )
}
}.xpath('interfaces/interface').each do |ifs_xml|
@catalog[ifs_name] = {}
unit = xml_get_has_xml( ifs_xml )
xml_read_parser( unit, @catalog[ifs_name] )
end
end
@catalog
end
|
#build_list ⇒ Object
335
336
337
338
339
340
341
342
343
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 335
def build_list
begin
got = @ndev.rpc.get_ethernet_switching_interface_information( :brief => true)
rescue => e
return []
end
got.xpath('//l2iff-interface-name').collect{ |ifn| ifn.text.split('.')[0] }
end
|
#upd_tagged_vlans(xml) ⇒ Object
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 179
def upd_tagged_vlans( xml )
return false unless should_trunk?
@should[:tagged_vlans] = @should[:tagged_vlans].to_set if @should[:tagged_vlans].kind_of? Array
@has[:tagged_vlans] = @has[:tagged_vlans].to_set if @has[:tagged_vlans].kind_of? Array
v_should = @should[:tagged_vlans] || Set.new
v_has = @has[:tagged_vlans] || Set.new
del = v_has - v_should
add = v_should - v_has
del_under_vlans = del & @under_vlans
unless del_under_vlans.empty?
del = del ^ @under_vlans
_xml_rm_under_vlans( xml, del_under_vlans )
@under_vlans = []
end
if add or del
xml.vlan {
del.each { |v| xml.members v, Netconf::JunosConfig::DELETE }
add.each { |v| xml.members v }
}
end
return true
end
|
#upd_untagged_vlan(xml) ⇒ Object
218
219
220
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 218
def upd_untagged_vlan( xml )
self.class.change_untagged_vlan( self, xml )
end
|
#xml_at_element_top(xml, name) ⇒ Object
set the edit anchor inside the ethernet-switching stanza we will need to ‘up-out’ when making changes to the unit information, like description
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 19
def xml_at_element_top( xml, name )
xml.interface {
xml.name name
xml.send(:'native-vlan-id')
xml.unit {
xml.name '0'
return xml
}
}
end
|
#xml_at_here(xml) ⇒ Object
116
117
118
119
120
121
122
123
124
125
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 116
def xml_at_here( xml )
@ifd = xml.instance_variable_get(:@parent).at_xpath('ancestor::interface')
@ifd.xpath('//native-vlan-id').remove
xml.family {
xml.send(:'ethernet-switching') {
return xml
}
}
end
|
#xml_at_top ⇒ Object
7
8
9
10
11
12
13
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 7
def xml_at_top
Nokogiri::XML::Builder.new {|xml| xml.configuration {
xml.interfaces {
return xml_at_element_top( xml, @name )
}
}}
end
|
#xml_build_change(nop = nil) ⇒ Object
127
128
129
130
131
132
133
134
135
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 127
def xml_build_change( nop = nil )
@under_vlans ||= []
if mode_changed?
@should[:untagged_vlan] ||= @has[:untagged_vlan]
end
super xml_at_here( xml_at_top )
end
|
#xml_change_description(xml) ⇒ Object
overload default method since we need to “up-out” of the ethernet-switching stanza
144
145
146
147
148
149
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 144
def xml_change_description( xml )
unit = xml.parent.xpath('ancestor::unit')[0]
Nokogiri::XML::Builder.with( unit ){ |x|
xml_set_or_delete( x, 'description', @should[:description] )
}
end
|
#xml_change_tagged_vlans(xml) ⇒ Object
174
175
176
177
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 174
def xml_change_tagged_vlans( xml )
return false if mode_changed?
upd_tagged_vlans( xml )
end
|
#xml_change_untagged_vlan(xml) ⇒ Object
213
214
215
216
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 213
def xml_change_untagged_vlan( xml )
return false if mode_changed?
upd_untagged_vlan( xml )
end
|
#xml_change_vlan_tagging(xml) ⇒ Object
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 155
def xml_change_vlan_tagging( xml )
port_mode = should_trunk? ? 'trunk' : 'access'
xml.send(:'interface-mode', port_mode )
upd_untagged_vlan( xml )
upd_tagged_vlans( xml )
return true
end
|
#xml_get_has_xml(xml) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 34
def xml_get_has_xml( xml )
got = xml.xpath('//unit')[0]
unless got
@has[:vlan_tagging] = false
@should = @has.clone
end
got
end
|
#xml_on_delete(xml) ⇒ Object
overload the xml_on_delete method since we may need to do some cleanup work in the [edit vlans] stanza
102
103
104
105
106
107
108
109
110
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 102
def xml_on_delete( xml )
@ifd = xml.instance_variable_get(:@parent).at_xpath('ancestor::interface')
@ifd.xpath('//native-vlan-id').remove
return unless @under_vlans
return if @under_vlans.empty?
_xml_rm_under_vlans( xml, @under_vlans )
end
|
#xml_read_parser(as_xml, as_hash) ⇒ Object
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
# File 'lib/junos-ez/l2_ports/vlan_l2ng.rb', line 49
def xml_read_parser( as_xml, as_hash )
set_has_status( as_xml, as_hash )
xml_when_item(as_xml.xpath('description')){|i| as_hash[:description] = i.text}
f_eth = as_xml.xpath('family/ethernet-switching')
as_hash[:vlan_tagging] = f_eth.xpath('interface-mode').text.chomp == 'trunk'
ifs_name = @name || as_xml.xpath('ancestor::interface/name').text.strip
eth_port_vlans = _get_eth_port_vlans_h( ifs_name )
@under_vlans = []
if as_hash[:vlan_tagging] == false
xml_when_item(f_eth.xpath('vlan/members')){ |i| as_hash[:untagged_vlan] = i.text.chomp }
unless as_hash[:untagged_vlan]
as_hash[:untagged_vlan] = eth_port_vlans[:untagged]
@under_vlans << eth_port_vlans[:untagged]
end
return
end
as_hash[:untagged_vlan] ||= eth_port_vlans[:untagged]
as_hash[:tagged_vlans] = f_eth.xpath('vlan/members').collect { |v| v.text.chomp }.to_set
(eth_port_vlans[:tagged] - as_hash[:tagged_vlans]).each do |vlan|
as_hash[:tagged_vlans] << vlan
@under_vlans << vlan
end
xml_when_item(f_eth.xpath('ancestor::interface/native-vlan-id')){ |i|
as_hash[:untagged_vlan] = _vlan_tag_id_to_name( i.text.chomp, as_hash )
}
end
|