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
@@ -0,0 +1,268 @@
1
+ require "junos-ez/provider"
2
+
3
+ module Junos::Ez::LAGports
4
+
5
+ PROPERTIES = [
6
+ :links, # Set of interface names
7
+ :minimum_links, # nil or Number > 0 # optional
8
+ :lacp, # [ :active, :passive, :disabled ] # optional
9
+ ]
10
+
11
+ def self.Provider( ndev, varsym )
12
+ newbie = Junos::Ez::LAGports::Provider::new( ndev )
13
+ newbie.properties = Junos::Ez::Provider::PROPERTIES + PROPERTIES
14
+ Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
15
+ end
16
+
17
+ class Provider < Junos::Ez::Provider::Parent
18
+ # common parenting goes here ... if we were to
19
+ # subclass the objects ... not doing that now
20
+ end
21
+
22
+ end
23
+
24
+ class Junos::Ez::LAGports::Provider
25
+
26
+ ### ---------------------------------------------------------------
27
+ ### XML top placement
28
+ ### ---------------------------------------------------------------
29
+
30
+ # LAG ports sit at the toplevel interface
31
+
32
+ def xml_at_top
33
+ Nokogiri::XML::Builder.new {|xml| xml.configuration {
34
+ xml.interfaces { xml.interface {
35
+ xml.name @name
36
+ return xml
37
+ }}
38
+ }}
39
+ end
40
+
41
+ ###-----------------------------------------------------------
42
+ ###-----------------------------------------------------------
43
+ ### utilities
44
+ ###-----------------------------------------------------------
45
+
46
+ def get_cookie_links( cfg )
47
+ cfg.xpath( "apply-macro[name = 'netdev_lag[:links]']/data/name" ).collect { |n| n.text }
48
+ end
49
+
50
+ def set_cookie_links( cfg )
51
+ cfg.send(:'apply-macro', Netconf::JunosConfig::REPLACE ) {
52
+ cfg.name 'netdev_lag[:links]'
53
+ should[:links].each{ |ifd|
54
+ cfg.data { cfg.name ifd }
55
+ }
56
+ }
57
+ end
58
+
59
+ ### ---------------------------------------------------------------
60
+ ### XML property readers
61
+ ### ---------------------------------------------------------------
62
+
63
+ def xml_config_read!
64
+ database = {'database' => 'committed'}
65
+ @ndev.rpc.get_configuration(xml_at_top, database)
66
+ end
67
+
68
+ def xml_get_has_xml( xml )
69
+ if ndev.facts[:ifd_style] == "CLASSIC"
70
+ @ifd_ether_options = 'gigether-options'
71
+ else
72
+ @ifd_ether_options = 'ether-options'
73
+ end
74
+ xml.xpath('//interface')[0]
75
+ end
76
+
77
+ def xml_read_parser( as_xml, as_hash )
78
+ set_has_status( as_xml, as_hash )
79
+
80
+ # property :links
81
+ ae_name = as_xml.xpath('name').text
82
+ as_hash[:links] = Set.new(get_cookie_links(as_xml))
83
+
84
+ # property :lacp
85
+ ae_opts = as_xml.xpath('aggregated-ether-options')
86
+ if (lacp = ae_opts.xpath('lacp')[0])
87
+ as_hash[:lacp] = (lacp.xpath('active')[0]) ? :active : :passive
88
+ else
89
+ as_hash[:lacp] = :disabled
90
+ end
91
+
92
+ # property :minimum_links
93
+ as_hash[:minimum_links] = (min_links = ae_opts.xpath('minimum-links')[0]) ? min_links.text.to_i : 1
94
+ end
95
+
96
+ ### ---------------------------------------------------------------
97
+ ### XML property writers
98
+ ### ---------------------------------------------------------------
99
+ def update_ifd_should()
100
+ if @should[:links].empty?
101
+ raise Junos::Ez::NoProviderError, "\n *links* are compulsory for creating lag interface!!! \n"
102
+ else
103
+ ether_option = @should[:links][0].to_s
104
+ @ifd_ether_options = (ether_option.start_with? 'fe-') ? 'fastether-options' : 'gigether-options'
105
+ end
106
+ end
107
+
108
+ def update_ifd_has()
109
+ @has[:links] = @has[:links].to_a
110
+ if @has[:links].empty?
111
+ raise Junos::Ez::NoProviderError, "\n Either lag interface is not created or links associated with given lag interface is not supported \n"
112
+ else
113
+ ether_option = @has[:links][0].to_s
114
+ @ifd_ether_options = (ether_option.start_with? 'fe-') ? 'fastether-options' : 'gigether-options'
115
+ end
116
+ end
117
+
118
+ def xml_change_links( xml )
119
+ update_ifd_should()
120
+ @should[:links] = @should[:links].to_set if @should[:links].kind_of? Array
121
+
122
+ has = @has[:links] || Set.new
123
+ should = @should[:links] || Set.new
124
+
125
+ set_cookie_links( xml )
126
+
127
+ del = has - should
128
+ add = should - has
129
+
130
+ par = xml.instance_variable_get(:@parent)
131
+ dot_ifd = par.at_xpath('ancestor::interfaces')
132
+
133
+ add.each{ |new_ifd| Nokogiri::XML::Builder.with( dot_ifd ) {|dot|
134
+ dot.interface { dot.name new_ifd
135
+ dot.send(@ifd_ether_options.to_sym) {
136
+ dot.send(:'ieee-802.3ad') {
137
+ dot.bundle @name
138
+ }
139
+ }
140
+ }}}
141
+
142
+ del.each{ |new_ifd| Nokogiri::XML::Builder.with( dot_ifd ) {|dot|
143
+ dot.interface { dot.name new_ifd
144
+ dot.send(@ifd_ether_options) {
145
+ dot.send( :'ieee-802.3ad', Netconf::JunosConfig::DELETE )
146
+ }
147
+ }}}
148
+ end
149
+
150
+ def xml_change_lacp( xml )
151
+ if @should[:lacp] == :disabled or @should[:lacp].nil?
152
+ xml.send(:'aggregated-ether-options') {
153
+ xml.lacp( Netconf::JunosConfig::DELETE )
154
+ }
155
+ else
156
+ xml.send(:'aggregated-ether-options') {
157
+ xml.lacp { xml.send @should[:lacp] } # @@@ should validate :lacp value before doing this...
158
+ }
159
+ end
160
+ end
161
+
162
+ def xml_change_minimum_links( xml )
163
+ if @should[:minimum_links]
164
+ xml.send(:'aggregated-ether-options') {
165
+ xml.send( :'minimum-links', @should[:minimum_links] )
166
+ }
167
+ else
168
+ xml.send(:'aggregated-ether-options') {
169
+ xml.send(:'minimum-links', Netconf::JunosConfig::DELETE )
170
+ }
171
+ end
172
+ end
173
+
174
+ ### ---------------------------------------------------------------
175
+ ### XML on-create
176
+ ### ---------------------------------------------------------------
177
+
178
+ def xml_on_create( xml )
179
+ # make sure there is a 'unit 0' on the AE port
180
+ par = xml.instance_variable_get(:@parent)
181
+ Nokogiri::XML::Builder.with(par) do |dot|
182
+ dot.unit {
183
+ dot.name '0'
184
+ }
185
+ end
186
+ end
187
+
188
+ ### ---------------------------------------------------------------
189
+ ### XML on-delete
190
+ ### ---------------------------------------------------------------
191
+
192
+ def xml_on_delete( xml )
193
+ update_ifd_has()
194
+ par = xml.instance_variable_get(:@parent)
195
+ dot_ifd = par.at_xpath('ancestor::interfaces')
196
+
197
+ # remove the bindings from each of the physical interfaces
198
+ #
199
+ @has[:links].each do |new_ifd| Nokogiri::XML::Builder.with( dot_ifd ) do |dot|
200
+ dot.interface { dot.name new_ifd
201
+ dot.send(@ifd_ether_options) {
202
+ dot.send( :'ieee-802.3ad', Netconf::JunosConfig::DELETE )
203
+ }
204
+ }
205
+ end
206
+ end
207
+
208
+ # now remove the LAG interface
209
+ #
210
+ Nokogiri::XML::Builder.with( dot_ifd ) do |dot|
211
+ dot.interface( Netconf::JunosConfig::DELETE ) {
212
+ dot.name @name
213
+ }
214
+ end
215
+ end
216
+
217
+ end
218
+
219
+
220
+ ##### ---------------------------------------------------------------
221
+ ##### Provider collection methods
222
+ ##### ---------------------------------------------------------------
223
+
224
+ class Junos::Ez::LAGports::Provider
225
+
226
+ def build_list
227
+ @ndev.rpc.get_interface_information(
228
+ :terse => true,
229
+ :interface_name => 'ae*'
230
+ ).xpath('physical-interface/name').collect{ |name| name.text.strip }
231
+ end
232
+
233
+ def build_catalog
234
+ return @catalog if list!.empty?
235
+
236
+ list.each do |ae_name|
237
+ @ndev.rpc.get_configuration{ |xml|
238
+ xml.interfaces {
239
+ xml.interface {
240
+ xml.name ae_name
241
+ }
242
+ }
243
+ }.xpath('interfaces/interface').each do |as_xml|
244
+ @catalog[ae_name] = {}
245
+ xml_read_parser( as_xml, @catalog[ae_name] )
246
+ end
247
+ end
248
+
249
+ @catalog
250
+ end
251
+
252
+ end
253
+
254
+ ##### ---------------------------------------------------------------
255
+ ##### _PRIVATE methods
256
+ ##### ---------------------------------------------------------------
257
+
258
+ class Junos::Ez::LAGports::Provider
259
+ def _get_port_list( name )
260
+ @ndev.rpc.get_interface_information(
261
+ :detail => true,
262
+ :interface_name => name + '.0'
263
+ ).xpath('//lag-link/name').collect{ |name|
264
+ name.text.strip.split('.',2).first
265
+ }
266
+ end
267
+ end
268
+
@@ -6,10 +6,6 @@
6
6
  ##### ---------------------------------------------------------------
7
7
 
8
8
  require 'set'
9
-
10
- module Junos; end
11
- module Junos::Ez; end
12
-
13
9
  require 'junos-ez/version.rb'
14
10
  require 'junos-ez/exceptions.rb'
15
11
 
@@ -208,7 +204,7 @@ class Junos::Ez::Provider::Parent
208
204
  ## can use 'create!' which does write to the device.
209
205
  ## ----------------------------------------------------------------
210
206
 
211
- def create( name = nil, prop_hash = {}, &block )
207
+ def create( name = nil, prop_hash = {} )
212
208
 
213
209
  ## if this is an existing object, then we shouldn't
214
210
  ## allow the caller to create something.
@@ -248,8 +244,8 @@ class Junos::Ez::Provider::Parent
248
244
  ## the config assuming create returns ok.
249
245
  ## ----------------------------------------------------------------
250
246
 
251
- def create!( name = nil, prop_hash = {}, &block )
252
- newbie = create( name, prop_hash, block )
247
+ def create!( *args )
248
+ newbie = create( *args )
253
249
  return nil unless newbie
254
250
  newbie.write!
255
251
  newbie
@@ -548,7 +544,7 @@ class Junos::Ez::Provider::Parent
548
544
  action = {'action' => 'replace' }
549
545
  result = @ndev.rpc.load_configuration( xml, action )
550
546
  rescue Netconf::RpcError => e
551
- errs = e.rsp.xpath('//rpc-error[error-severity = "error"]')
547
+ errs = e.rsp.xpath('//rpc-error')
552
548
  raise e unless errs.empty?
553
549
  e.rsp
554
550
  else
@@ -6,6 +6,8 @@ require 'junos-ez/l1_ports' # physical ports
6
6
  require 'junos-ez/vlans' # vlans
7
7
  require 'junos-ez/l2_ports' # switch ports
8
8
  require 'junos-ez/ip_ports' # ip ports (v4)
9
+ require 'junos-ez/lag_ports' # Link Aggregation Groups
10
+ require 'junos-ez/group'
9
11
 
10
12
  # -------------------------------------------------------------------
11
13
  # utility libraries, not providers
File without changes
@@ -66,12 +66,12 @@ class Junos::Ez::Users::Provider
66
66
 
67
67
  # READ-ONLY capture the keys
68
68
  unless (keys = as_xml.xpath('authentication/ssh-rsa')).empty?
69
- @has[:ssh_keys] ||= {}
70
- @has[:ssh_keys]['ssh-rsa'] = keys.collect{|key| key.text.strip}
69
+ as_hash[:ssh_keys] ||= {}
70
+ as_hash[:ssh_keys]['ssh-rsa'] = keys.collect{|key| key.text.strip}
71
71
  end
72
72
  unless (keys = as_xml.xpath('authentication/ssh-dsa')).empty?
73
- @has[:ssh_keys] ||= {}
74
- @has[:ssh_keys]['ssh-dsa'] = keys.collect{|key| key.text.strip}
73
+ as_hash[:ssh_keys] ||= {}
74
+ as_hash[:ssh_keys]['ssh-dsa'] = keys.collect{|key| key.text.strip}
75
75
  end
76
76
  end
77
77
 
@@ -127,9 +127,7 @@ class Junos::Ez::Users::Provider
127
127
  def build_catalog
128
128
  @catalog = {}
129
129
  @ndev.rpc.get_configuration{ |x| x.system {
130
- x.login {
131
- x.user
132
- }
130
+ x.login
133
131
  }}
134
132
  .xpath('//user').each do |user|
135
133
  name = user.xpath('name').text
File without changes
File without changes
File without changes
@@ -1,3 +1,6 @@
1
+ module Junos; end
2
+ module Junos::Ez; end
3
+
1
4
  module Junos::Ez
2
- VERSION = "0.1.2"
5
+ VERSION = '1.0.3'.freeze
3
6
  end
@@ -11,8 +11,10 @@ module Junos::Ez::Vlans
11
11
 
12
12
  def self.Provider( ndev, varsym )
13
13
  newbie = case ndev.fact :switch_style
14
- when :VLAN, :VLAN_NG
14
+ when :VLAN
15
15
  Junos::Ez::Vlans::Provider::VLAN.new( ndev )
16
+ when :VLAN_L2NG
17
+ Junos::Ez::Vlans::Provider::VLAN_L2NG.new( ndev )
16
18
  when :BRIDGE_DOMAIN
17
19
  Junos::Ez::Vlans::Provider::BRIDGE_DOMAIN.new( ndev )
18
20
  else
@@ -30,6 +32,7 @@ module Junos::Ez::Vlans
30
32
  end
31
33
 
32
34
  require 'junos-ez/vlans/vlan'
35
+ require 'junos-ez/vlans/vlan_l2ng'
33
36
  require 'junos-ez/vlans/bridge_domain'
34
37
 
35
38
 
@@ -21,12 +21,16 @@ class Junos::Ez::Vlans::Provider::BRIDGE_DOMAIN < Junos::Ez::Vlans::Provider
21
21
  return nil unless (@has_xml = cfg_xml.xpath('//domain')[0])
22
22
  xml_read_parser( @has_xml, @has )
23
23
  end
24
+
25
+ def xml_get_has_xml( xml )
26
+ xml.xpath('//domain')[0]
27
+ end
24
28
 
25
29
  def xml_read_parser( as_xml, as_hash )
26
- status_from_junos( as_xml, as_hash )
30
+ set_has_status( as_xml, as_hash )
27
31
  as_hash[:vlan_id] = as_xml.xpath('vlan-id').text.to_i
28
32
  as_hash[:description] = as_xml.xpath('description').text
29
- as_hash[:no_mac_learning] = as_xml.xpath('bridge-options/no-mac-learning').empty? ? false : true
33
+ as_hash[:no_mac_learning] = as_xml.xpath('bridge-options/no-mac-learning').empty? ? :disable : :enable
30
34
  return true
31
35
  end
32
36
 
@@ -42,7 +46,7 @@ class Junos::Ez::Vlans::Provider::BRIDGE_DOMAIN < Junos::Ez::Vlans::Provider
42
46
  no_ml = @should[:no_mac_learning]
43
47
  return unless ( exists? and no_ml )
44
48
  xml.send(:'bridge-options') {
45
- xml.send(:'no-mac-learning', no_ml ? nil : Netconf::JunosConfig::DELETE )
49
+ xml.send(:'no-mac-learning', (no_ml == :enable) ? nil : Netconf::JunosConfig::DELETE )
46
50
  }
47
51
  end
48
52
 
@@ -22,9 +22,10 @@ class Junos::Ez::Vlans::Provider::VLAN < Junos::Ez::Vlans::Provider
22
22
 
23
23
  def xml_read_parser( as_xml, as_hash )
24
24
  set_has_status( as_xml, as_hash )
25
+
25
26
  as_hash[:vlan_id] = as_xml.xpath('vlan-id').text.to_i
26
- xml_when_item(as_xml.xpath('description')){ |i| as_hash[:description] = i.text }
27
- xml_when_item(as_xml.xpath('no-mac-learning')){ as_hash[:no_mac_learning] = true }
27
+ xml_when_item(as_xml.xpath('description')){ |i| as_hash[:description] = i.text }
28
+ xml_when_item(as_xml.xpath('no-mac-learning')){ as_hash[:no_mac_learning] = :enable }
28
29
 
29
30
  # get a brief list of the interfaces on this vlan
30
31
  got = @ndev.rpc.get_vlan_information( :vlan_name => @name || as_xml.xpath('name').text )
@@ -40,7 +41,7 @@ class Junos::Ez::Vlans::Provider::VLAN < Junos::Ez::Vlans::Provider
40
41
 
41
42
  def xml_change_no_mac_learning( xml )
42
43
  no_ml = @should[:no_mac_learning]
43
- return unless exists? and no_ml
44
+ return unless exists? and no_ml
44
45
  xml.send(:'no-mac-learning', no_ml ? nil : Netconf::JunosConfig::DELETE )
45
46
  end
46
47
 
@@ -0,0 +1,126 @@
1
+ class Junos::Ez::Vlans::Provider::VLAN_L2NG < Junos::Ez::Vlans::Provider
2
+
3
+ ### ---------------------------------------------------------------
4
+ ### XML top placement
5
+ ### ---------------------------------------------------------------
6
+
7
+ def xml_at_top
8
+ Nokogiri::XML::Builder.new{|x| x.configuration{
9
+ x.vlans { x.vlan { x.name @name
10
+ return x
11
+ }}
12
+ }}
13
+ end
14
+
15
+ ### ---------------------------------------------------------------
16
+ ### XML readers
17
+ ### ---------------------------------------------------------------
18
+
19
+ def xml_get_has_xml( xml )
20
+ xml.xpath('//vlan')[0]
21
+ end
22
+
23
+ def xml_read_parser( as_xml, as_hash )
24
+ set_has_status( as_xml, as_hash )
25
+
26
+ as_hash[:vlan_id] = as_xml.xpath('vlan-id').text.to_i
27
+ xml_when_item(as_xml.xpath('description')){ |i| as_hash[:description] = i.text }
28
+
29
+ xml_when_item(as_xml.xpath('switch-options/no-mac-learning')) {
30
+ as_hash[:no_mac_learning] = :enable
31
+ }
32
+
33
+ # get a brief list of the interfaces on this vlan
34
+ got = @ndev.rpc.get_vlan_information( :vlan_name => @name || as_xml.xpath('name').text )
35
+ as_hash[:interfaces] = got.xpath('//l2ng-l2rtb-vlan-member-interface').collect{|ifs| ifs.text.strip }
36
+ as_hash[:interfaces] = nil if as_hash[:interfaces][0] == "None"
37
+
38
+ return true
39
+ end
40
+
41
+ ### ---------------------------------------------------------------
42
+ ### XML writers
43
+ ### ---------------------------------------------------------------
44
+
45
+ def xml_change_no_mac_learning( xml )
46
+ no_ml = @should[:no_mac_learning]
47
+ return unless exists? and no_ml
48
+ xml.send(:'switch-options') {
49
+ xml.send(:'no-mac-learning', no_ml == :enable ? nil : Netconf::JunosConfig::DELETE )
50
+ }
51
+ end
52
+
53
+ def xml_change_vlan_id( xml )
54
+ xml.send(:'vlan-id', @should[:vlan_id] )
55
+ end
56
+
57
+ def xml_change_description( xml )
58
+ value = @should[:description]
59
+ xml.description value ? value : Netconf::JunosConfig::DELETE
60
+ end
61
+
62
+ end
63
+
64
+ ##### ---------------------------------------------------------------
65
+ ##### Provider collection methods
66
+ ##### ---------------------------------------------------------------
67
+
68
+ class Junos::Ez::Vlans::Provider::VLAN_L2NG
69
+
70
+ def build_list
71
+ xml_cfgs = @ndev.rpc.get_configuration{ |x| x.send :'vlans' }
72
+ xml_cfgs.xpath('vlans/vlan').collect do |vlan|
73
+ vlan.xpath('name').text
74
+ end
75
+ end
76
+
77
+ def build_catalog
78
+ @catalog = {}
79
+ xml_cfgs = @ndev.rpc.get_configuration{ |x| x.send :'vlans' }
80
+ xml_cfgs.xpath('vlans/vlan').collect do |vlan|
81
+ name = vlan.xpath('name').text
82
+ @catalog[name] = {}
83
+ xml_read_parser( vlan, @catalog[name] )
84
+ end
85
+ return @catalog
86
+ end
87
+
88
+ end
89
+
90
+ ##### ---------------------------------------------------------------
91
+ ##### Provider operational methods
92
+ ##### ---------------------------------------------------------------
93
+
94
+ class Junos::Ez::Vlans::Provider::VLAN_L2NG
95
+
96
+ ### ---------------------------------------------------------------
97
+ ### interfaces - returns a Hash of each interface in the VLAN
98
+ ### each interface (key) will identify:
99
+ ### :mode = [ :access | :trunk ]
100
+ ### :native = true if (:mode == :trunk) and this VLAN is the
101
+ ### native vlan-id (untagged packets)
102
+ ### ---------------------------------------------------------------
103
+
104
+ def interfaces( opts = {} )
105
+ raise ArgumentError, "not a resource" if is_provider?
106
+
107
+ args = {}
108
+ args[:vlan_name] = @name
109
+ args[:extensive] = true
110
+ got = @ndev.rpc.get_vlan_information( args )
111
+
112
+ member_pfx = 'l2ng-l2rtb-vlan-member'
113
+ members = got.xpath("//#{member_pfx}-interface")
114
+ ifs_h = {}
115
+ members.each do |port|
116
+ port_name = port.text.split('.')[0]
117
+ port_h = {}
118
+ port_h[:mode] = port.xpath("following-sibling::#{member_pfx}-interface-mode[1]").text.to_sym
119
+ tgd = port.xpath("following-sibling::#{member_pfx}-tagness[1]").text
120
+ native = (tgd == 'untagged')
121
+ port_h[:native] = true if( native and port_h[:mode] == :trunk)
122
+ ifs_h[port_name] = port_h
123
+ end
124
+ ifs_h
125
+ end
126
+ end