junos-ez-stdlib 0.1.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +6 -14
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +18 -0
- data/CHANGELOG.md +60 -19
- data/Gemfile +7 -0
- data/README.md +41 -30
- data/Rakefile +6 -0
- data/SUGGESTION-BOX/README.md +32 -0
- data/docs/Providers/Group.md +61 -0
- data/docs/Providers/L2ports.md +1 -1
- data/docs/Providers/LAGports.md +57 -0
- data/docs/Providers/Vlans.md +1 -1
- data/examples/config/config_file.rb +0 -0
- data/examples/config/config_template_object.rb +0 -0
- data/examples/config/config_template_simple.rb +0 -0
- data/examples/config/load_sample.conf +129 -0
- data/examples/config/load_sample.set +3 -0
- data/examples/config/load_template_main.conf +7 -0
- data/examples/config/load_template_object.conf +7 -0
- data/examples/config/multi_config.rb +0 -0
- data/examples/fs_utils.rb +0 -0
- data/examples/lag_port.rb +27 -0
- data/examples/re_upgrade.rb +0 -0
- data/examples/re_utils.rb +0 -0
- data/examples/simple.rb +0 -1
- data/examples/st_hosts.rb +0 -0
- data/examples/user.rb +0 -0
- data/examples/vlans.rb +4 -4
- data/junos-ez-stdlib.gemspec +25 -14
- data/lib/junos-ez/exceptions.rb +0 -0
- data/lib/junos-ez/facts.rb +5 -7
- data/lib/junos-ez/facts/chassis.rb +6 -0
- data/lib/junos-ez/facts/ifd_style.rb +6 -3
- data/lib/junos-ez/facts/personality.rb +6 -6
- data/lib/junos-ez/facts/switch_style.rb +11 -2
- data/lib/junos-ez/facts/version.rb +24 -9
- data/lib/junos-ez/group.rb +206 -0
- data/lib/junos-ez/ip_ports.rb +0 -0
- data/lib/junos-ez/ip_ports/classic.rb +2 -2
- data/lib/junos-ez/l1_ports.rb +0 -0
- data/lib/junos-ez/l1_ports/classic.rb +0 -0
- data/lib/junos-ez/l1_ports/switch.rb +0 -0
- data/lib/junos-ez/l2_ports.rb +18 -9
- data/lib/junos-ez/l2_ports/bridge_domain.rb +499 -0
- data/lib/junos-ez/l2_ports/vlan.rb +3 -3
- data/lib/junos-ez/l2_ports/vlan_l2ng.rb +502 -0
- data/lib/junos-ez/lag_ports.rb +268 -0
- data/lib/junos-ez/provider.rb +4 -8
- data/lib/junos-ez/stdlib.rb +2 -0
- data/lib/junos-ez/system.rb +0 -0
- data/lib/junos-ez/system/users.rb +5 -7
- data/lib/junos-ez/utils/config.rb +0 -0
- data/lib/junos-ez/utils/fs.rb +0 -0
- data/lib/junos-ez/utils/re.rb +0 -0
- data/lib/junos-ez/version.rb +4 -1
- data/lib/junos-ez/vlans.rb +4 -1
- data/lib/junos-ez/vlans/bridge_domain.rb +7 -3
- data/lib/junos-ez/vlans/vlan.rb +4 -3
- data/lib/junos-ez/vlans/vlan_l2ng.rb +126 -0
- 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
|
+
|
data/lib/junos-ez/provider.rb
CHANGED
@@ -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 = {}
|
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!(
|
252
|
-
newbie = create(
|
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
|
547
|
+
errs = e.rsp.xpath('//rpc-error')
|
552
548
|
raise e unless errs.empty?
|
553
549
|
e.rsp
|
554
550
|
else
|
data/lib/junos-ez/stdlib.rb
CHANGED
@@ -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
|
data/lib/junos-ez/system.rb
CHANGED
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
|
-
|
70
|
-
|
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
|
-
|
74
|
-
|
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
|
data/lib/junos-ez/utils/fs.rb
CHANGED
File without changes
|
data/lib/junos-ez/utils/re.rb
CHANGED
File without changes
|
data/lib/junos-ez/version.rb
CHANGED
data/lib/junos-ez/vlans.rb
CHANGED
@@ -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
|
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
|
-
|
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? ?
|
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
|
|
data/lib/junos-ez/vlans/vlan.rb
CHANGED
@@ -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] =
|
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
|