junos-ez-stdlib 0.0.12 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +17 -3
- data/README.md +10 -0
- data/docs/Providers/IPports.md +61 -0
- data/docs/Providers/L1ports.md +29 -0
- data/docs/Providers/L2ports.md +43 -0
- data/docs/Providers/StaticHosts.md +26 -0
- data/docs/Providers/StaticRoutes.md +37 -0
- data/docs/Providers/UserAuths.md +32 -0
- data/docs/{Users.md → Providers/Users.md} +17 -0
- data/docs/Providers/Vlans.md +43 -0
- data/docs/Providers_Resources.md +24 -0
- data/docs/README_FIRST.md +27 -0
- data/docs/Utils/Config.md +161 -0
- data/docs/Utils/Filesystem.md +78 -0
- data/docs/Utils/Routing-Engine.md +248 -0
- data/examples/re_upgrade.rb +1 -1
- data/examples/re_utils.rb +1 -0
- data/examples/vlans.rb +7 -1
- data/lib/junos-ez/ip_ports.rb +3 -1
- data/lib/junos-ez/ip_ports/classic.rb +49 -14
- data/lib/junos-ez/l1_ports.rb +51 -11
- data/lib/junos-ez/l2_ports.rb +1 -1
- data/lib/junos-ez/l2_ports/vlan.rb +176 -60
- data/lib/junos-ez/provider.rb +4 -1
- data/lib/junos-ez/system/st_hosts.rb +0 -0
- data/lib/junos-ez/system/st_routes.rb +0 -0
- data/lib/junos-ez/system/userauths.rb +0 -0
- data/lib/junos-ez/system/users.rb +0 -0
- data/lib/junos-ez/utils/config.rb +33 -2
- data/lib/junos-ez/utils/re.rb +22 -3
- data/lib/junos-ez/vlans.rb +5 -3
- data/lib/junos-ez/vlans/vlan.rb +6 -0
- metadata +14 -13
- data/docs/Config_Utils.md +0 -3
- data/docs/Filesys_Utils.md +0 -3
- data/docs/IPports.md +0 -3
- data/docs/L1ports.md +0 -3
- data/docs/L2ports.md +0 -3
- data/docs/RE_utils.md +0 -3
- data/docs/StaticHosts.md +0 -3
- data/docs/StaticRoutes.md +0 -3
- data/docs/Vlans.md +0 -3
- data/lib/junos-ez/system/user_ssh_keys.rb +0 -113
data/lib/junos-ez/l1_ports.rb
CHANGED
@@ -10,6 +10,8 @@ module Junos::Ez::L1ports
|
|
10
10
|
:duplex, # [ :auto, :half, :full ]
|
11
11
|
:unit_count, # number of configured units
|
12
12
|
]
|
13
|
+
|
14
|
+
IFS_NAME_FILTER = '[fgx]e-*'
|
13
15
|
|
14
16
|
def self.Provider( ndev, varsym )
|
15
17
|
newbie = case ndev.fact( :ifd_style )
|
@@ -47,7 +49,7 @@ class Junos::Ez::L1ports::Provider < Junos::Ez::Provider::Parent
|
|
47
49
|
@ndev.rpc.get_interface_information({
|
48
50
|
:media => true,
|
49
51
|
:terse => true,
|
50
|
-
:interface_name =>
|
52
|
+
:interface_name => Junos::Ez::L1ports::IFS_NAME_FILTER
|
51
53
|
}).xpath('physical-interface/name').collect do |ifs|
|
52
54
|
ifs.text.strip
|
53
55
|
end
|
@@ -56,24 +58,62 @@ class Junos::Ez::L1ports::Provider < Junos::Ez::Provider::Parent
|
|
56
58
|
def build_catalog
|
57
59
|
@catalog = {}
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
-
|
61
|
+
# we could have a large list of interfaces, so
|
62
|
+
# we need to break this up into individual "gets"
|
63
|
+
|
64
|
+
list!.each do |ifs_name|
|
65
|
+
@ndev.rpc.get_configuration{ |xml|
|
66
|
+
xml.interfaces {
|
62
67
|
xml.interface {
|
63
|
-
xml.name
|
68
|
+
xml.name ifs_name
|
64
69
|
xml_read_filter( xml )
|
65
70
|
}
|
66
|
-
|
67
|
-
}
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
xml_read_parser( ifs_xml, @catalog[ifs_name] )
|
71
|
+
}
|
72
|
+
}.xpath('interfaces/interface').each do |ifs_xml|
|
73
|
+
@catalog[ifs_name] = {}
|
74
|
+
xml_read_parser( ifs_xml, @catalog[ifs_name] )
|
75
|
+
end
|
72
76
|
end
|
73
77
|
|
74
78
|
return @catalog
|
75
79
|
end
|
76
80
|
|
81
|
+
### ---------------------------------------------------------------
|
82
|
+
### Resource methods
|
83
|
+
### ---------------------------------------------------------------
|
84
|
+
|
85
|
+
## returns a Hash of status information, from "show interface ..."
|
86
|
+
## basic information, not absolutely everything. but if a
|
87
|
+
## block is given, then pass the XML to the block.
|
88
|
+
|
89
|
+
def status
|
90
|
+
|
91
|
+
got = @ndev.rpc.get_interface_information(:interface_name => @name, :media => true )
|
92
|
+
phy = got.xpath('physical-interface')[0]
|
93
|
+
return nil unless phy
|
94
|
+
|
95
|
+
ret_h = {}
|
96
|
+
ret_h[:macaddr] = phy.xpath('current-physical-address').text.strip
|
97
|
+
xml_when_item(phy.xpath('description')){|i| ret_h[:description] = i.text.strip }
|
98
|
+
ret_h[:oper_status] = phy.xpath('oper-status').text.strip
|
99
|
+
ret_h[:admin_status] = phy.xpath('admin-status').text.strip
|
100
|
+
ret_h[:mtu] = phy.xpath('mtu').text.to_i
|
101
|
+
ret_h[:speed] = {:admin => phy.xpath('speed').text.strip }
|
102
|
+
ret_h[:duplex] = {:admin => phy.xpath('duplex').text.strip }
|
103
|
+
ret_h[:autoneg] = phy.xpath('if-auto-negotiation').text.strip
|
104
|
+
|
105
|
+
if ret_h[:autoneg] == "enabled"
|
106
|
+
autoneg = phy.xpath('ethernet-autonegotiation')[0]
|
107
|
+
ret_h[:speed][:oper] = autoneg.xpath('link-partner-speed').text.strip
|
108
|
+
ret_h[:duplex][:oper] = autoneg.xpath('link-partner-duplexity').text.strip
|
109
|
+
end
|
110
|
+
|
111
|
+
# if a block is given, then it means the caller wants to process the XML data.
|
112
|
+
yield( phy ) if block_given?
|
113
|
+
|
114
|
+
ret_h
|
115
|
+
end
|
116
|
+
|
77
117
|
end
|
78
118
|
|
79
119
|
require 'junos-ez/l1_ports/switch'
|
data/lib/junos-ez/l2_ports.rb
CHANGED
@@ -52,27 +52,56 @@ class Junos::Ez::L2ports::Provider::VLAN < Junos::Ez::L2ports::Provider
|
|
52
52
|
|
53
53
|
f_eth = as_xml.xpath('family/ethernet-switching')
|
54
54
|
as_hash[:vlan_tagging] = f_eth.xpath('port-mode').text.chomp == 'trunk'
|
55
|
-
|
55
|
+
|
56
|
+
# obtain a copy of the running state, this is needed in case the config
|
57
|
+
# is located under the [edit vlans] stanza vs. [edit interfaces]
|
58
|
+
|
59
|
+
ifs_name = @name || as_xml.xpath('ancestor::interface/name').text.strip
|
60
|
+
eth_port_vlans = _get_eth_port_vlans_h( ifs_name )
|
61
|
+
@under_vlans = []
|
62
|
+
|
56
63
|
# --- access port
|
64
|
+
|
57
65
|
if as_hash[:vlan_tagging] == false
|
58
|
-
xml_when_item(f_eth.xpath('vlan/members')){|i| as_hash[:untagged_vlan] = i.text.chomp }
|
66
|
+
xml_when_item(f_eth.xpath('vlan/members')){ |i| as_hash[:untagged_vlan] = i.text.chomp }
|
67
|
+
unless as_hash[:untagged_vlan]
|
68
|
+
as_hash[:untagged_vlan] = eth_port_vlans[:untagged]
|
69
|
+
@under_vlans << eth_port_vlans[:untagged]
|
70
|
+
end
|
59
71
|
return
|
60
72
|
end
|
61
73
|
|
62
74
|
# --- trunk port
|
75
|
+
|
63
76
|
xml_when_item(f_eth.xpath('native-vlan-id')){|i| as_hash[:untagged_vlan] = i.text.chomp }
|
64
|
-
as_hash[:
|
77
|
+
as_hash[:untagged_vlan] ||= eth_port_vlans[:untagged]
|
78
|
+
as_hash[:tagged_vlans] = f_eth.xpath('vlan/members').collect { |v| v.text.chomp }.to_set
|
79
|
+
(eth_port_vlans[:tagged] - as_hash[:tagged_vlans]).each do |vlan|
|
80
|
+
as_hash[:tagged_vlans] << vlan
|
81
|
+
@under_vlans << vlan
|
82
|
+
end
|
83
|
+
|
65
84
|
end
|
66
85
|
|
86
|
+
### ---------------------------------------------------------------
|
87
|
+
### XML on_create, on_delete handlers
|
88
|
+
### ---------------------------------------------------------------
|
89
|
+
|
90
|
+
## overload the xml_on_delete method since we may need
|
91
|
+
## to do some cleanup work in the [edit vlans] stanza
|
92
|
+
|
93
|
+
def xml_on_delete( xml )
|
94
|
+
return unless @under_vlans
|
95
|
+
return if @under_vlans.empty?
|
96
|
+
|
97
|
+
_xml_rm_under_vlans( xml, @under_vlans )
|
98
|
+
end
|
99
|
+
|
67
100
|
### ---------------------------------------------------------------
|
68
101
|
### XML property writers
|
69
102
|
### ---------------------------------------------------------------
|
70
103
|
|
71
|
-
|
72
|
-
## some of the has -> should values. this way we don't need
|
73
|
-
## to munge all of the state-transition code.
|
74
|
-
|
75
|
-
def xml_build_at_here( xml )
|
104
|
+
def xml_at_here( xml )
|
76
105
|
xml.family {
|
77
106
|
xml.send(:'ethernet-switching') {
|
78
107
|
return xml
|
@@ -80,11 +109,16 @@ class Junos::Ez::L2ports::Provider::VLAN < Junos::Ez::L2ports::Provider
|
|
80
109
|
}
|
81
110
|
end
|
82
111
|
|
83
|
-
def xml_build_change(
|
84
|
-
@
|
85
|
-
|
86
|
-
|
87
|
-
|
112
|
+
def xml_build_change( nop = nil )
|
113
|
+
@under_vlans ||= [] # handles case for create'd port
|
114
|
+
|
115
|
+
if mode_changed?
|
116
|
+
@should[:untagged_vlan] ||= @has[:untagged_vlan]
|
117
|
+
end
|
118
|
+
|
119
|
+
super xml_at_here( xml_at_top )
|
120
|
+
end
|
121
|
+
|
88
122
|
## ----------------------------------------------------------------
|
89
123
|
## :description
|
90
124
|
## ----------------------------------------------------------------
|
@@ -110,6 +144,7 @@ class Junos::Ez::L2ports::Provider::VLAN < Junos::Ez::L2ports::Provider
|
|
110
144
|
# when the vlan_tagging value changes then this method
|
111
145
|
# will trigger updates to the untagged_vlan and tagged_vlans
|
112
146
|
# resource values as well.
|
147
|
+
# !!! DO NOT SWAP THIS ORDER untagged processing *MUST* BE FIRST!
|
113
148
|
|
114
149
|
upd_untagged_vlan( xml )
|
115
150
|
upd_tagged_vlans( xml )
|
@@ -129,20 +164,23 @@ class Junos::Ez::L2ports::Provider::VLAN < Junos::Ez::L2ports::Provider
|
|
129
164
|
def upd_tagged_vlans( xml )
|
130
165
|
return false unless should_trunk?
|
131
166
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
v_has = @has[:tagged_vlans] || []
|
140
|
-
v_has = v_has.map(&:to_s)
|
141
|
-
v_should = v_should.map(&:to_s)
|
167
|
+
@should[:tagged_vlans] = @should[:tagged_vlans].to_set if @should[:tagged_vlans].kind_of? Array
|
168
|
+
@has[:tagged_vlans] = @has[:tagged_vlans].to_set if @has[:tagged_vlans].kind_of? Array
|
169
|
+
|
170
|
+
v_should = @should[:tagged_vlans] || Set.new
|
171
|
+
v_has = @has[:tagged_vlans] || Set.new
|
142
172
|
|
143
173
|
del = v_has - v_should
|
144
174
|
add = v_should - v_has
|
145
|
-
|
175
|
+
|
176
|
+
del_under_vlans = del & @under_vlans
|
177
|
+
|
178
|
+
unless del_under_vlans.empty?
|
179
|
+
del = del ^ @under_vlans
|
180
|
+
_xml_rm_under_vlans( xml, del_under_vlans )
|
181
|
+
@under_vlans = []
|
182
|
+
end
|
183
|
+
|
146
184
|
if add or del
|
147
185
|
xml.vlan {
|
148
186
|
del.each { |v| xml.members v, Netconf::JunosConfig::DELETE }
|
@@ -226,46 +264,46 @@ class Junos::Ez::L2ports::Provider::VLAN
|
|
226
264
|
### -------------------------------------------------------------
|
227
265
|
|
228
266
|
def self.ac_ac_nountg( this, xml )
|
229
|
-
|
267
|
+
this._xml_rm_ac_untagged_vlan( xml )
|
230
268
|
end
|
231
269
|
|
232
270
|
def self.ac_tr_nountg( this, xml )
|
233
|
-
unless (untg_vlan = this.has[:
|
234
|
-
|
235
|
-
xml.members untg_vlan, Netconf::JunosConfig::DELETE
|
236
|
-
}
|
271
|
+
unless (untg_vlan = this.has[:untagged_vlan]).nil?
|
272
|
+
this._xml_rm_ac_untagged_vlan( xml )
|
237
273
|
end
|
238
274
|
end
|
239
275
|
|
240
276
|
def self.tr_ac_nountg( this, xml )
|
241
|
-
xml.send :'native-vlan-id', Netconf::JunosConfig::DELETE
|
242
|
-
|
277
|
+
xml.send :'native-vlan-id', Netconf::JunosConfig::DELETE
|
278
|
+
this._xml_rm_these_vlans( xml, this.has[:tagged_vlans ] ) if this.has[:tagged_vlans]
|
243
279
|
end
|
244
280
|
|
245
281
|
def self.tr_tr_nountg( this, xml )
|
246
282
|
xml.send :'native-vlan-id', Netconf::JunosConfig::DELETE
|
247
283
|
end
|
248
284
|
|
285
|
+
## ----------------------------------------------------------------
|
286
|
+
## transition where port WILL-HAVE untagged-vlan
|
287
|
+
## ----------------------------------------------------------------
|
288
|
+
|
249
289
|
def self.ac_ac_untg( this, xml )
|
250
|
-
|
290
|
+
this._xml_rm_ac_untagged_vlan( xml )
|
291
|
+
xml.vlan {
|
251
292
|
xml.members this.should[:untagged_vlan]
|
252
293
|
}
|
253
294
|
end
|
254
295
|
|
255
296
|
def self.ac_tr_untg( this, xml )
|
297
|
+
# move untagged vlan to native-vlan-id ...
|
256
298
|
was_untg_vlan = this.has[:untagged_vlan]
|
257
|
-
|
258
|
-
|
259
|
-
xml.members was_untg_vlan, Netconf::JunosConfig::DELETE if was_untg_vlan
|
260
|
-
}
|
261
|
-
xml.send :'native-vlan-id', this.should[:untagged_vlan]
|
299
|
+
xml.send :'native-vlan-id', this.should[:untagged_vlan]
|
300
|
+
this._xml_rm_ac_untagged_vlan( xml ) if was_untg_vlan
|
262
301
|
end
|
263
302
|
|
264
|
-
def self.tr_ac_untg( this, xml )
|
265
|
-
xml.send :'native-vlan-id', Netconf::JunosConfig::DELETE
|
266
|
-
|
267
|
-
|
268
|
-
}
|
303
|
+
def self.tr_ac_untg( this, xml )
|
304
|
+
xml.send :'native-vlan-id', Netconf::JunosConfig::DELETE
|
305
|
+
this._xml_rm_these_vlans( xml, this.has[:tagged_vlans ] ) if this.has[:tagged_vlans]
|
306
|
+
xml.vlan { xml.members this.should[:untagged_vlan] }
|
269
307
|
end
|
270
308
|
|
271
309
|
def self.tr_tr_untg( this, xml )
|
@@ -293,25 +331,103 @@ class Junos::Ez::L2ports::Provider::VLAN
|
|
293
331
|
|
294
332
|
def build_catalog
|
295
333
|
@catalog = {}
|
296
|
-
return @catalog if list
|
334
|
+
return @catalog if list!.empty?
|
335
|
+
|
336
|
+
list.each do |ifs_name|
|
337
|
+
@ndev.rpc.get_configuration{ |xml|
|
338
|
+
xml.interfaces {
|
339
|
+
xml.interface {
|
340
|
+
xml.name ifs_name
|
341
|
+
xml.unit { xml.name '0' }
|
342
|
+
}
|
343
|
+
}
|
344
|
+
}.xpath('interfaces/interface').each do |ifs_xml|
|
345
|
+
@catalog[ifs_name] = {}
|
346
|
+
unit = ifs_xml.xpath('unit')[0]
|
347
|
+
xml_read_parser( unit, @catalog[ifs_name] )
|
348
|
+
end
|
349
|
+
end
|
297
350
|
|
298
|
-
@ndev.rpc.get_configuration{ |xml|
|
299
|
-
xml.interfaces {
|
300
|
-
list.each do |port_name|
|
301
|
-
Nokogiri::XML::Builder.with( xml.parent ) do |x1|
|
302
|
-
x1.interface { x1.name port_name
|
303
|
-
x1.unit { x1.name '0' }
|
304
|
-
}
|
305
|
-
end
|
306
|
-
end
|
307
|
-
}
|
308
|
-
}.xpath('interfaces/interface').each do |ifs|
|
309
|
-
ifs_name = ifs.xpath('name').text
|
310
|
-
unit = ifs.xpath('unit')[0]
|
311
|
-
@catalog[ifs_name] = {}
|
312
|
-
xml_read_parser( unit, @catalog[ifs_name] )
|
313
|
-
end
|
314
351
|
@catalog
|
315
352
|
end
|
316
353
|
|
317
|
-
end
|
354
|
+
end
|
355
|
+
|
356
|
+
##### ---------------------------------------------------------------
|
357
|
+
##### !!!!! PRIVATE METHODS !!!!
|
358
|
+
##### ---------------------------------------------------------------
|
359
|
+
|
360
|
+
class Junos::Ez::L2ports::Provider::VLAN
|
361
|
+
private
|
362
|
+
|
363
|
+
def _get_eth_port_vlans_h( ifs_name )
|
364
|
+
|
365
|
+
got = @ndev.rpc.get_ethernet_switching_interface_information(:interface_name => ifs_name)
|
366
|
+
ret_h = {:untagged => nil, :tagged => Set.new }
|
367
|
+
got.xpath('//interface-vlan-member').each do |vlan|
|
368
|
+
vlan_name = vlan.xpath('interface-vlan-name').text.strip
|
369
|
+
tgdy = vlan.xpath('interface-vlan-member-tagness').text.strip
|
370
|
+
if tgdy == 'untagged'
|
371
|
+
ret_h[:untagged] = vlan_name
|
372
|
+
else
|
373
|
+
ret_h[:tagged] << vlan_name
|
374
|
+
end
|
375
|
+
end
|
376
|
+
ret_h
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|
380
|
+
|
381
|
+
|
382
|
+
### ---------------------------------------------------------------
|
383
|
+
### [edit vlans] - for interfaces configured here ...
|
384
|
+
### ---------------------------------------------------------------
|
385
|
+
|
386
|
+
class Junos::Ez::L2ports::Provider::VLAN
|
387
|
+
|
388
|
+
def _xml_edit_under_vlans( xml )
|
389
|
+
Nokogiri::XML::Builder.with( xml.doc.root ) do |dot|
|
390
|
+
dot.vlans {
|
391
|
+
return dot
|
392
|
+
}
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
def _xml_rm_under_vlans( xml, vlans )
|
397
|
+
at_vlans = _xml_edit_under_vlans( xml )
|
398
|
+
vlans.each do |vlan_name|
|
399
|
+
Nokogiri::XML::Builder.with( at_vlans.parent ) do |this|
|
400
|
+
this.vlan {
|
401
|
+
this.name vlan_name
|
402
|
+
this.interface( Netconf::JunosConfig::DELETE ) { this.name @name }
|
403
|
+
}
|
404
|
+
end
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
def _xml_rm_ac_untagged_vlan( xml )
|
409
|
+
if @under_vlans.empty?
|
410
|
+
xml.vlan Netconf::JunosConfig::DELETE
|
411
|
+
else
|
412
|
+
_xml_rm_under_vlans( xml, [ @has[:untagged_vlan ] ] )
|
413
|
+
@under_vlans = []
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
def _xml_rm_these_vlans( xml, vlans )
|
418
|
+
if @under_vlans.empty?
|
419
|
+
xml.vlan( Netconf::JunosConfig::DELETE )
|
420
|
+
else
|
421
|
+
# could be a mix between [edit vlans] and [edit interfaces] ...
|
422
|
+
v_has = vlans.to_set
|
423
|
+
del_under_vlans = v_has & @under_vlans
|
424
|
+
_xml_rm_under_vlans( xml, del_under_vlans )
|
425
|
+
if v_has ^ @under_vlans
|
426
|
+
xml.vlan( Netconf::JunosConfig::DELETE )
|
427
|
+
end
|
428
|
+
@under_vlans = []
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
end
|
433
|
+
|
data/lib/junos-ez/provider.rb
CHANGED
@@ -5,11 +5,13 @@
|
|
5
5
|
##### scope of impact. Thank you.
|
6
6
|
##### ---------------------------------------------------------------
|
7
7
|
|
8
|
+
require 'set'
|
9
|
+
|
8
10
|
module Junos; end
|
9
11
|
|
10
12
|
module Junos::Ez
|
11
13
|
|
12
|
-
VERSION = "0.0.
|
14
|
+
VERSION = "0.0.15"
|
13
15
|
|
14
16
|
### ---------------------------------------------------------------
|
15
17
|
### rpc_errors - decodes the XML into an array of error/Hash
|
@@ -286,6 +288,7 @@ class Junos::Ez::Provider::Parent
|
|
286
288
|
xml = xml_at_top
|
287
289
|
par = xml.instance_variable_get(:@parent)
|
288
290
|
par['delete'] = 'delete'
|
291
|
+
xml_on_delete( xml )
|
289
292
|
rsp = write_xml_config!( xml.doc.root )
|
290
293
|
@has[:_exist] = false
|
291
294
|
true # rsp ... don't return XML, but let's hear from the community...
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -10,6 +10,7 @@ configuration files/templates and software images
|
|
10
10
|
lock! - take exclusive lock on config
|
11
11
|
unlock! - release exclusive lock on config
|
12
12
|
rollback! - perform a config rollback
|
13
|
+
get_config - returns requested config in "text" format-style
|
13
14
|
|
14
15
|
---------------------------------------------------------------------
|
15
16
|
=end
|
@@ -162,7 +163,7 @@ class Junos::Ez::Config::Provider < Junos::Ez::Provider::Parent
|
|
162
163
|
### current candidate configuration loaded and the rollback_id
|
163
164
|
###
|
164
165
|
### --- returns ---
|
165
|
-
###
|
166
|
+
### nil if no diff
|
166
167
|
### String of diff output otherwise
|
167
168
|
### ---------------------------------------------------------------
|
168
169
|
|
@@ -170,7 +171,7 @@ class Junos::Ez::Config::Provider < Junos::Ez::Provider::Parent
|
|
170
171
|
raise ArgumentError, "invalid rollback #{rollback_id}" unless ( rollback_id >= 0 and rollback_id <= 50 )
|
171
172
|
got = ndev.rpc.get_configuration( :compare=>'rollback', :rollback=> rollback_id.to_s )
|
172
173
|
diff = got.xpath('configuration-output').text
|
173
|
-
return
|
174
|
+
return nil if diff == "\n"
|
174
175
|
diff
|
175
176
|
end
|
176
177
|
|
@@ -200,6 +201,36 @@ class Junos::Ez::Config::Provider < Junos::Ez::Provider::Parent
|
|
200
201
|
true
|
201
202
|
end
|
202
203
|
|
204
|
+
### ---------------------------------------------------------------
|
205
|
+
### get_config - returns String of requested (or entire) config
|
206
|
+
### in "text" (curly-brace) format. The 'rqst' argument
|
207
|
+
### identifies the scope of the config, for example:
|
208
|
+
###
|
209
|
+
### .get_config( "interfaces ge-0/0/0" )
|
210
|
+
###
|
211
|
+
### If there is no configuration available, 'nil' is returned
|
212
|
+
###
|
213
|
+
### If there is an error in the request, that will be returned
|
214
|
+
### as a String with "ERROR!" prepended
|
215
|
+
### ---------------------------------------------------------------
|
216
|
+
|
217
|
+
def get_config( rqst = nil )
|
218
|
+
scope = "show configuration"
|
219
|
+
scope.concat( " " + rqst ) if rqst
|
220
|
+
begin
|
221
|
+
@ndev.rpc.command( scope, :format => 'text' ).xpath('configuration-output').text
|
222
|
+
rescue NoMethodError
|
223
|
+
# indicates no configuration found
|
224
|
+
nil
|
225
|
+
rescue => e
|
226
|
+
# indicates error in request
|
227
|
+
err = e.rsp.xpath('rpc-error')[0]
|
228
|
+
err_info = err.xpath('error-info/bad-element').text
|
229
|
+
err_msg = err.xpath('error-message').text
|
230
|
+
"ERROR! " + err_msg + ": " + err_info
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
203
234
|
end # class Provider
|
204
235
|
|
205
236
|
|