junos-ez-stdlib 0.0.12 → 0.0.15
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.
- 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
|
|