Class: Junos::Ez::L2ports::Provider::VLAN
- Inherits:
-
Junos::Ez::L2ports::Provider
- Object
- Provider::Parent
- Junos::Ez::L2ports::Provider
- Junos::Ez::L2ports::Provider::VLAN
- Defined in:
- lib/junos-ez/l2_ports/vlan.rb,
lib/junos-ez/l2_ports/vlan.rb,
lib/junos-ez/l2_ports/vlan.rb,
lib/junos-ez/l2_ports/vlan.rb,
lib/junos-ez/l2_ports/vlan.rb
Overview
- edit vlans
-
for interfaces configured here …
-
Instance Attribute Summary
Attributes inherited from Provider::Parent
#catalog, #has, #list, #name, #ndev, #parent, #properties, #providers, #should
Class Method Summary collapse
-
.ac_ac_nountg(this, xml) ⇒ Object
————————————————————- The following are all the change transition functions for each of the use-cases ————————————————————-.
-
.ac_ac_untg(this, xml) ⇒ Object
—————————————————————- transition where port WILL-HAVE untagged-vlan —————————————————————-.
- .ac_tr_nountg(this, xml) ⇒ Object
- .ac_tr_untg(this, xml) ⇒ Object
-
.change_untagged_vlan(this, xml) ⇒ Object
invoke the correct method from the jump table based on the three criteria to select the action.
-
.init_jump_table ⇒ Object
creating some class definitions …
- .tr_ac_nountg(this, xml) ⇒ Object
- .tr_ac_untg(this, xml) ⇒ Object
- .tr_tr_nountg(this, xml) ⇒ Object
- .tr_tr_untg(this, xml) ⇒ Object
Instance Method Summary collapse
- #_xml_edit_under_vlans(xml) ⇒ Object
- #_xml_rm_ac_untagged_vlan(xml) ⇒ Object
- #_xml_rm_these_vlans(xml, vlans) ⇒ Object
- #_xml_rm_under_vlans(xml, vlans) ⇒ Object
- #build_catalog ⇒ Object
- #build_list ⇒ Object
- #upd_tagged_vlans(xml) ⇒ Object
- #upd_untagged_vlan(xml) ⇒ Object
-
#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.
-
#xml_at_here(xml) ⇒ Object
————————————————————— XML property writers —————————————————————.
-
#xml_at_top ⇒ Object
————————————————————— XML top placement —————————————————————.
- #xml_build_change(nop = nil) ⇒ Object
-
#xml_change_description(xml) ⇒ Object
overload default method since we need to “up-out” of the ethernet-switching stanza.
-
#xml_change_tagged_vlans(xml) ⇒ Object
—————————————————————- :tagged_vlans —————————————————————-.
-
#xml_change_untagged_vlan(xml) ⇒ Object
—————————————————————- :untagged_vlan —————————————————————-.
-
#xml_change_vlan_tagging(xml) ⇒ Object
—————————————————————- :vlan_tagging —————————————————————-.
-
#xml_get_has_xml(xml) ⇒ Object
————————————————————— XML property readers —————————————————————.
-
#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.
- #xml_read_parser(as_xml, as_hash) ⇒ Object
Methods inherited from Junos::Ez::L2ports::Provider
#is_trunk?, #mode_changed?, #should_trunk?, #xml_change__active
Methods inherited from Provider::Parent
#[], #[]=, #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
Constructor Details
This class inherits a constructor from Junos::Ez::Provider::Parent
Class Method Details
.ac_ac_nountg(this, xml) ⇒ Object
The following are all the change transition functions for each of the use-cases
266 267 268 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 266 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
289 290 291 292 293 294 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 289 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
270 271 272 273 274 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 270 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
296 297 298 299 300 301 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 296 def self.ac_tr_untg( this, xml ) # move untagged vlan to native-vlan-id ... was_untg_vlan = this.has[:untagged_vlan] xml.send :'native-vlan-id', 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
255 256 257 258 259 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 255 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 :-)
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 225 def self.init_jump_table # auto-hash table, majik! hash = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)})) # ------------------------------------------------------------------ # - jump table for handling various untagged vlan change use-cases # ------------------------------------------------------------------ # There are three criteria for selection: # | is_trunk | will_trunk | no_untg | # ------------------------------------------------------------------ # - will not have untagged vlan 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) # - will have untagged vlan 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
276 277 278 279 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 276 def self.tr_ac_nountg( this, xml ) xml.send :'native-vlan-id', Netconf::JunosConfig::DELETE this._xml_rm_these_vlans( xml, this.has[:tagged_vlans ] ) if this.has[:tagged_vlans] end |
.tr_ac_untg(this, xml) ⇒ Object
303 304 305 306 307 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 303 def self.tr_ac_untg( this, xml ) xml.send :'native-vlan-id', Netconf::JunosConfig::DELETE 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
281 282 283 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 281 def self.tr_tr_nountg( this, xml ) xml.send :'native-vlan-id', Netconf::JunosConfig::DELETE end |
.tr_tr_untg(this, xml) ⇒ Object
309 310 311 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 309 def self.tr_tr_untg( this, xml ) xml.send :'native-vlan-id', this.should[:untagged_vlan] end |
Instance Method Details
#_xml_edit_under_vlans(xml) ⇒ Object
388 389 390 391 392 393 394 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 388 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
408 409 410 411 412 413 414 415 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 408 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
417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 417 def _xml_rm_these_vlans( xml, vlans ) if @under_vlans.empty? xml.vlan( Netconf::JunosConfig::DELETE ) else # could be a mix between [edit vlans] and [edit interfaces] ... 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
396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 396 def _xml_rm_under_vlans( xml, vlans ) 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 |
#build_catalog ⇒ Object
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 332 def build_catalog @catalog = {} return @catalog if list!.empty? list.each do |ifs_name| @ndev.rpc.get_configuration{ |xml| xml.interfaces { xml.interface { xml.name ifs_name xml.unit { xml.name '0' } } } }.xpath('interfaces/interface').each do |ifs_xml| @catalog[ifs_name] = {} unit = ifs_xml.xpath('unit')[0] xml_read_parser( unit, @catalog[ifs_name] ) end end @catalog end |
#build_list ⇒ Object
320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 320 def build_list begin got = @ndev.rpc.get_ethernet_switching_interface_information(:summary=>true) rescue => e # in this case, no ethernet-switching is enabled so return empty list return [] end got.xpath('interface/interface-name').collect{ |ifn| ifn.text.split('.')[0] } end |
#upd_tagged_vlans(xml) ⇒ Object
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 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 164 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
203 204 205 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 203 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 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 19 def xml_at_element_top( xml, name ) xml.interface { xml.name name xml.unit { xml.name '0' return xml } } end |
#xml_at_here(xml) ⇒ Object
XML property writers
104 105 106 107 108 109 110 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 104 def xml_at_here( xml ) xml.family { xml.send(:'ethernet-switching') { return xml } } end |
#xml_at_top ⇒ Object
XML top placement
7 8 9 10 11 12 13 |
# File 'lib/junos-ez/l2_ports/vlan.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
112 113 114 115 116 117 118 119 120 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 112 def xml_build_change( nop = nil ) @under_vlans ||= [] # handles case for create'd port 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
129 130 131 132 133 134 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 129 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
:tagged_vlans
159 160 161 162 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 159 def xml_change_tagged_vlans( xml ) return false if mode_changed? upd_tagged_vlans( xml ) end |
#xml_change_untagged_vlan(xml) ⇒ Object
:untagged_vlan
198 199 200 201 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 198 def xml_change_untagged_vlan( xml ) return false if mode_changed? upd_untagged_vlan( xml ) end |
#xml_change_vlan_tagging(xml) ⇒ Object
:vlan_tagging
140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 140 def xml_change_vlan_tagging( xml ) interface_mode = should_trunk? ? 'trunk' : 'access' xml.send(:'interface-mode', interface_mode ) # when the vlan_tagging value changes then this method # will trigger updates to the untagged_vlan and tagged_vlans # resource values as well. # !!! DO NOT SWAP THIS ORDER untagged processing *MUST* BE FIRST! upd_untagged_vlan( xml ) upd_tagged_vlans( xml ) return true end |
#xml_get_has_xml(xml) ⇒ Object
XML property readers
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 33 def xml_get_has_xml( xml ) # second unit contains the family/ethernet-switching stanza got = xml.xpath('//unit')[0] # if this resource doesn't exist we need to default some # values into has/should variables 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
93 94 95 96 97 98 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 93 def xml_on_delete( xml ) 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
48 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 |
# File 'lib/junos-ez/l2_ports/vlan.rb', line 48 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' # obtain a copy of the running state, this is needed in case the config # is located under the [edit vlans] stanza vs. [edit interfaces] ifs_name = @name || as_xml.xpath('ancestor::interface/name').text.strip eth_port_vlans = _get_eth_port_vlans_h( ifs_name ) @under_vlans = [] # --- access port 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 # --- trunk port xml_when_item(f_eth.xpath('native-vlan-id')){|i| as_hash[:untagged_vlan] = i.text.chomp } 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 end |