junos-ez-stdlib 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +26 -0
- data/README.md +181 -0
- data/docs/Config_Utils.md +3 -0
- data/docs/Facts.md +106 -0
- data/docs/Filesys_Utils.md +3 -0
- data/docs/IPports.md +3 -0
- data/docs/L1ports.md +3 -0
- data/docs/L2ports.md +3 -0
- data/docs/Providers_Resources.md +304 -0
- data/docs/RE_utils.md +3 -0
- data/docs/StaticHosts.md +3 -0
- data/docs/StaticRoutes.md +3 -0
- data/docs/Vlans.md +3 -0
- data/examples/config/config_file.rb +72 -0
- data/examples/config/config_template_object.rb +81 -0
- data/examples/config/config_template_simple.rb +76 -0
- data/examples/config/multi_config.rb +60 -0
- data/examples/fs_utils.rb +31 -0
- data/examples/re_upgrade.rb +90 -0
- data/examples/re_utils.rb +30 -0
- data/examples/simple.rb +47 -0
- data/examples/st_hosts.rb +33 -0
- data/examples/vlans.rb +25 -0
- data/junos-ez-stdlib.gemspec +15 -0
- data/lib/junos-ez/facts/chassis.rb +45 -0
- data/lib/junos-ez/facts/ifd_style.rb +14 -0
- data/lib/junos-ez/facts/personality.rb +22 -0
- data/lib/junos-ez/facts/switch_style.rb +22 -0
- data/lib/junos-ez/facts/version.rb +32 -0
- data/lib/junos-ez/facts.rb +85 -0
- data/lib/junos-ez/ip_ports/classic.rb +149 -0
- data/lib/junos-ez/ip_ports.rb +28 -0
- data/lib/junos-ez/l1_ports/classic.rb +87 -0
- data/lib/junos-ez/l1_ports/switch.rb +134 -0
- data/lib/junos-ez/l1_ports.rb +81 -0
- data/lib/junos-ez/l2_ports/bridge_domain.rb +0 -0
- data/lib/junos-ez/l2_ports/vlan.rb +317 -0
- data/lib/junos-ez/l2_ports/vlan_l2ng.rb +0 -0
- data/lib/junos-ez/l2_ports.rb +57 -0
- data/lib/junos-ez/provider.rb +608 -0
- data/lib/junos-ez/stdlib.rb +16 -0
- data/lib/junos-ez/system/st_hosts.rb +74 -0
- data/lib/junos-ez/system/st_routes.rb +135 -0
- data/lib/junos-ez/system/syscfg.rb +103 -0
- data/lib/junos-ez/system.rb +98 -0
- data/lib/junos-ez/utils/config.rb +205 -0
- data/lib/junos-ez/utils/fs.rb +376 -0
- data/lib/junos-ez/utils/re.rb +371 -0
- data/lib/junos-ez/vlans/bridge_domain.rb +85 -0
- data/lib/junos-ez/vlans/vlan.rb +112 -0
- data/lib/junos-ez/vlans.rb +31 -0
- metadata +111 -0
@@ -0,0 +1,376 @@
|
|
1
|
+
=begin
|
2
|
+
---------------------------------------------------------------------
|
3
|
+
FS::Utils is a collection of filesystem utility routines. These do
|
4
|
+
not map to configuration resources. However, the provider framework
|
5
|
+
lends itself well in case we need to do something later, yo!
|
6
|
+
|
7
|
+
Each of the FS::Util methods will provide back a rubyized structure
|
8
|
+
by default. The 'options' hash to each method will allow you to
|
9
|
+
change the return result in either :text or Junos :xml as well.
|
10
|
+
|
11
|
+
The following is a quick list of the filesystem utility methods,
|
12
|
+
these following the unix naming counterparts (mostly)
|
13
|
+
|
14
|
+
cat - returns the contents of the file (String)
|
15
|
+
checksum - returns the checksum of a file
|
16
|
+
cleanup? - returns Hash info of files that would be removed by ...
|
17
|
+
cleanup! - performs a system storage cleanup
|
18
|
+
cp! - local file copy (use 'scp' if you want to copy remote/local)
|
19
|
+
cwd - change the working directory (String)
|
20
|
+
df - shows the system storage (Hash)
|
21
|
+
ls - returns a filesystem listing (Hash)
|
22
|
+
mv! - rename/move files (true | String error)
|
23
|
+
pwd - return the current working directory (String)
|
24
|
+
rm! - remove files (String)
|
25
|
+
|
26
|
+
---------------------------------------------------------------------
|
27
|
+
=end
|
28
|
+
|
29
|
+
module Junos::Ez::FS
|
30
|
+
def self.Utils( ndev, varsym )
|
31
|
+
newbie = Junos::Ez::FS::Provider.new( ndev )
|
32
|
+
Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
### -----------------------------------------------------------------
|
37
|
+
### PUBLIC METHODS
|
38
|
+
### -----------------------------------------------------------------
|
39
|
+
### class containing filesystem public utility functions
|
40
|
+
### these are not in alphabetical order, but I should do that, yo!
|
41
|
+
### -----------------------------------------------------------------
|
42
|
+
|
43
|
+
class Junos::Ez::FS::Provider < Junos::Ez::Provider::Parent
|
44
|
+
|
45
|
+
### -------------------------------------------------------------
|
46
|
+
### cwd - change the current working directory. This method will
|
47
|
+
### return the String of the new working directory or raise
|
48
|
+
### and IOError exception if the directory is invalid
|
49
|
+
### -------------------------------------------------------------
|
50
|
+
|
51
|
+
def cwd( directory )
|
52
|
+
begin
|
53
|
+
got = @ndev.rpc.set_cli_working_directory( :directory => directory )
|
54
|
+
rescue => e
|
55
|
+
raise IOError, "invalid directory: #{directory}"
|
56
|
+
else
|
57
|
+
got.xpath('working-directory').text
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
### -------------------------------------------------------------
|
62
|
+
### pwd - retrieve current working directory, return String
|
63
|
+
### -------------------------------------------------------------
|
64
|
+
|
65
|
+
def pwd
|
66
|
+
ndev.rpc.command("show cli directory").text.strip
|
67
|
+
end
|
68
|
+
|
69
|
+
def checksum( method, path )
|
70
|
+
got = case method
|
71
|
+
when :md5
|
72
|
+
@ndev.rpc.get_checksum_information( :path => path )
|
73
|
+
when :sha256
|
74
|
+
@ndev.rpc.get_sha256_checksum_information( :path => path )
|
75
|
+
when :sha1
|
76
|
+
@ndev.rpc.get_sha1_checksum_information( :path => path )
|
77
|
+
end
|
78
|
+
|
79
|
+
f_chk = got.xpath('file-checksum')
|
80
|
+
if (err = f_chk.xpath('rpc-error/error-message')[0])
|
81
|
+
return err.text.strip
|
82
|
+
end
|
83
|
+
f_chk.xpath('checksum').text.strip
|
84
|
+
end
|
85
|
+
|
86
|
+
### -------------------------------------------------------------
|
87
|
+
## ls - provides directory listing of files/subdirs. if
|
88
|
+
## directory is nil, then the current working directory
|
89
|
+
## is used. The following options (opts) are supported
|
90
|
+
##
|
91
|
+
## :format => [:text, :xml, :hash], default = :hash
|
92
|
+
## :recurse => true - recursive listing thru subdirs
|
93
|
+
## :detail => true - file details, on if :recurse
|
94
|
+
### -------------------------------------------------------------
|
95
|
+
|
96
|
+
def ls( *args )
|
97
|
+
|
98
|
+
directory = nil
|
99
|
+
opts = {}
|
100
|
+
|
101
|
+
case args.count
|
102
|
+
when 1
|
103
|
+
if args[0].kind_of? Hash
|
104
|
+
opts = args[0]
|
105
|
+
else
|
106
|
+
directory = args[0]
|
107
|
+
end
|
108
|
+
when 2
|
109
|
+
directory = args[0]
|
110
|
+
opts = args[1]
|
111
|
+
end
|
112
|
+
|
113
|
+
# args are the RPC arguments ...
|
114
|
+
args = {}
|
115
|
+
args[:path] = directory if directory
|
116
|
+
args[:recursive] = true if opts[:recurse]
|
117
|
+
args[:detail] = true if opts[:detail]
|
118
|
+
args.delete(:detail) if( args[:detail] and args[:recursive])
|
119
|
+
|
120
|
+
# RPC output format, default is XML
|
121
|
+
outf = { :format => 'text' } if opts[:format] == :text
|
122
|
+
|
123
|
+
got = @ndev.rpc.file_list( args, outf )
|
124
|
+
return nil unless got
|
125
|
+
|
126
|
+
return got.text if opts[:format] == :text
|
127
|
+
return got if opts[:format] == :xml
|
128
|
+
|
129
|
+
# if we're here, then we need to conver the output
|
130
|
+
# to a Hash. Joy!
|
131
|
+
|
132
|
+
collect_detail = args[:detail] || args[:recursive]
|
133
|
+
|
134
|
+
ls_hash = {}
|
135
|
+
got.xpath('directory').each do |dir|
|
136
|
+
|
137
|
+
dir_name = dir.xpath('directory-name').text.strip
|
138
|
+
dir_hash = {}
|
139
|
+
|
140
|
+
dir_hash[:fileblocks] = dir.xpath('total-file-blocks').text.to_i
|
141
|
+
files_info = dir.xpath('file-information')
|
142
|
+
|
143
|
+
dir_hash[:files] = {}
|
144
|
+
dir_hash[:dirs] = {} # sub-directories
|
145
|
+
|
146
|
+
files_info.each do |file|
|
147
|
+
f_name = file.xpath('file-name').text.strip
|
148
|
+
f_h = {}
|
149
|
+
|
150
|
+
if file.xpath('file-directory')[0]
|
151
|
+
dir_hash[:dirs][f_name] = f_h
|
152
|
+
else
|
153
|
+
dir_hash[:files][f_name] = f_h
|
154
|
+
end
|
155
|
+
|
156
|
+
next unless collect_detail
|
157
|
+
|
158
|
+
f_h[:owner] = file.xpath('file-owner').text.strip
|
159
|
+
f_h[:group] = file.xpath('file-group').text.strip
|
160
|
+
f_h[:links] = file.xpath('file-links').text.to_i
|
161
|
+
f_h[:size] = file.xpath('file-size').text.to_i
|
162
|
+
|
163
|
+
fp = file.xpath('file-permissions')[0]
|
164
|
+
f_h[:permissions_text] = fp.attribute('format').value
|
165
|
+
f_h[:permissions] = fp.text.to_i
|
166
|
+
|
167
|
+
fd = file.xpath('file-date')[0]
|
168
|
+
f_h[:date] = fd.attribute('format').value
|
169
|
+
f_h[:date_epoc] = fd.text.to_i
|
170
|
+
|
171
|
+
end # each directory file
|
172
|
+
ls_hash[ dir_name ] = dir_hash
|
173
|
+
end # each directory
|
174
|
+
|
175
|
+
ls_hash
|
176
|
+
end # method: ls
|
177
|
+
|
178
|
+
### -------------------------------------------------------------
|
179
|
+
### rm! - just like unix, removes files
|
180
|
+
### -------------------------------------------------------------
|
181
|
+
|
182
|
+
def rm!( path )
|
183
|
+
got = @ndev.rpc.file_delete( :path => path )
|
184
|
+
return true if got.nil? # got no error
|
185
|
+
# otherwise, there was an error, check output
|
186
|
+
got.text
|
187
|
+
end
|
188
|
+
|
189
|
+
### -------------------------------------------------------------
|
190
|
+
### cat - is used to obtain the text contents of the file
|
191
|
+
### -------------------------------------------------------------
|
192
|
+
|
193
|
+
def cat( filename )
|
194
|
+
begin
|
195
|
+
@ndev.rpc.file_show( :filename => filename ).text
|
196
|
+
rescue => e
|
197
|
+
raise IOError, e.rsp.xpath('rpc-error/error-message').text.strip
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
### -------------------------------------------------------------
|
202
|
+
### 'mv' - just like unix, moves/renames a file
|
203
|
+
### -------------------------------------------------------------
|
204
|
+
|
205
|
+
def mv!( from_path, to_path )
|
206
|
+
got = @ndev.rpc.command( "file rename #{from_path} #{to_path}" )
|
207
|
+
return true if got.nil? # got no error
|
208
|
+
got.text
|
209
|
+
end
|
210
|
+
|
211
|
+
### -------------------------------------------------------------
|
212
|
+
### df - shows the system storage information
|
213
|
+
###
|
214
|
+
### opts[:format] = [:text, :xml, :hash]
|
215
|
+
### defaults :hash
|
216
|
+
###
|
217
|
+
### opts[:size_div] = value to device size values,
|
218
|
+
### valid only for :format == :hash
|
219
|
+
### -------------------------------------------------------------
|
220
|
+
|
221
|
+
def df( opts = {} )
|
222
|
+
|
223
|
+
outf = {:format => 'text' } if opts[:format] == :text
|
224
|
+
args = { :detail => true } if opts[:size_div]
|
225
|
+
|
226
|
+
got = @ndev.rpc.get_system_storage( args, outf )
|
227
|
+
|
228
|
+
return got.text if opts[:format] == :text
|
229
|
+
return got if opts[:format] == :xml
|
230
|
+
|
231
|
+
df_h = {}
|
232
|
+
### need to turn this into a Hash
|
233
|
+
got.xpath('filesystem').each do |fs|
|
234
|
+
fs_name = fs.xpath('filesystem-name').text.strip
|
235
|
+
fs_h = {}
|
236
|
+
df_h[fs_name] = fs_h
|
237
|
+
|
238
|
+
fs_h[:mounted_on] = fs.xpath('mounted-on').text.strip
|
239
|
+
datum = fs.xpath('total-blocks')
|
240
|
+
fs_h[:total_blocks] = datum.text.to_i
|
241
|
+
fs_h[:total_size] = datum.attribute('format').value
|
242
|
+
|
243
|
+
datum = fs.xpath('used-blocks')
|
244
|
+
fs_h[:used_blocks] = datum.text.to_i
|
245
|
+
fs_h[:used_size] = datum.attribute('format').value
|
246
|
+
fs_h[:used_percent] = fs.xpath('used-percent').text.to_i
|
247
|
+
|
248
|
+
datum = fs.xpath('available-blocks')
|
249
|
+
fs_h[:avail_blocks] = datum.text.to_i
|
250
|
+
fs_h[:avail_size] = datum.attribute('format').value
|
251
|
+
if opts[:size_div]
|
252
|
+
fs_h[:total_size] = fs_h[:total_size].to_i / opts[:size_div]
|
253
|
+
fs_h[:used_size] = fs_h[:used_size].to_i / opts[:size_div]
|
254
|
+
fs_h[:avail_size] = fs_h[:avail_size].to_i / opts[:size_div]
|
255
|
+
end
|
256
|
+
end
|
257
|
+
df_h
|
258
|
+
end
|
259
|
+
|
260
|
+
### -------------------------------------------------------------
|
261
|
+
### cleanup! will perform the 'request system storage cleanup'
|
262
|
+
### command and remove the files. If you want to check which
|
263
|
+
### files will be removed, use the cleanup? method first
|
264
|
+
### -------------------------------------------------------------
|
265
|
+
|
266
|
+
def cleanup!
|
267
|
+
got = @ndev.rpc.request_system_storage_cleanup
|
268
|
+
gone_h = {}
|
269
|
+
got.xpath('file-list/file').each do |file|
|
270
|
+
_cleanup_file_to_h( file, gone_h )
|
271
|
+
end
|
272
|
+
gone_h
|
273
|
+
end
|
274
|
+
|
275
|
+
### -------------------------------------------------------------
|
276
|
+
### 'cleanup?' will return information on files that would be
|
277
|
+
### removed if cleanup! was executed
|
278
|
+
### -------------------------------------------------------------
|
279
|
+
|
280
|
+
def cleanup?
|
281
|
+
got = @ndev.rpc.request_system_storage_cleanup( :dry_run => true )
|
282
|
+
dryrun_h = {}
|
283
|
+
got.xpath('file-list/file').each do |file|
|
284
|
+
_cleanup_file_to_h( file, dryrun_h )
|
285
|
+
end
|
286
|
+
dryrun_h
|
287
|
+
end
|
288
|
+
|
289
|
+
### -------------------------------------------------------------
|
290
|
+
### cp! - copies a file. The from_file and to_file can be
|
291
|
+
### URL parameters, yo!
|
292
|
+
###
|
293
|
+
### opts[:source_address] will set the source address of the
|
294
|
+
### copy command, useful when URL contain SCP, HTTP
|
295
|
+
### -------------------------------------------------------------
|
296
|
+
|
297
|
+
def cp!( from_file, to_file, opts = {} )
|
298
|
+
args = { :source => from_file, :destination => to_file }
|
299
|
+
args[:source_address] = opts[:source_address] if opts[:source_address]
|
300
|
+
|
301
|
+
begin
|
302
|
+
got = @ndev.rpc.file_copy( args )
|
303
|
+
rescue => e
|
304
|
+
raise IOError, e.rsp.xpath('rpc-error/error-message').text.strip
|
305
|
+
else
|
306
|
+
return true
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
end # class Provider
|
311
|
+
|
312
|
+
### -----------------------------------------------------------------
|
313
|
+
### PRIVATE METHODS
|
314
|
+
### -----------------------------------------------------------------
|
315
|
+
### These are helper/private methods, or methods that are current
|
316
|
+
### work-in-progress/under-investigation
|
317
|
+
### -----------------------------------------------------------------
|
318
|
+
|
319
|
+
class Junos::Ez::FS::Provider
|
320
|
+
private
|
321
|
+
|
322
|
+
### private method used to convert 'cleanup' file XML
|
323
|
+
### to hash structure and bind it to collecting hash
|
324
|
+
|
325
|
+
def _cleanup_file_to_h( file, attach_h )
|
326
|
+
file_name = file.xpath('file-name').text.strip
|
327
|
+
file_h = {}
|
328
|
+
data = file.xpath('size')
|
329
|
+
file_h[:size_text] = data.attribute('format').value
|
330
|
+
file_h[:size] = data.text.to_i
|
331
|
+
file_h[:date] = file.xpath('date').text.strip
|
332
|
+
attach_h[file_name] = file_h
|
333
|
+
file_h
|
334
|
+
end
|
335
|
+
|
336
|
+
##### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
337
|
+
##### ... HERE THERE BE MONSTERS ....
|
338
|
+
##### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
339
|
+
|
340
|
+
### -------------------------------------------------------------
|
341
|
+
### 'diff' just like unix; patch output
|
342
|
+
### @@@ something is getting messed up in the XML translation
|
343
|
+
### @@@ as control characters like (<,>) are getting munged.
|
344
|
+
### @@@ need to investigate with Nokogiri ....
|
345
|
+
### -------------------------------------------------------------
|
346
|
+
|
347
|
+
def diff___( from_file, to_file )
|
348
|
+
raise StandardError, "Under investigation"
|
349
|
+
got = @ndev.rpc.file_compare( :from_file => from_file, :to_file => to_file )
|
350
|
+
end
|
351
|
+
|
352
|
+
# create a .tar file from the files in the given directory.
|
353
|
+
# the filename does not need to include the .tar extension, but
|
354
|
+
# if you include it, that's ok.
|
355
|
+
# NOTE: cannot specify an arbitrary list of files, per Junos RPC
|
356
|
+
|
357
|
+
### !!!! these are only allowed from the CLI, at least as tested
|
358
|
+
### !!!! on an vSRX. Need to check on other platforms, etc.
|
359
|
+
|
360
|
+
def tar___( directory, filename )
|
361
|
+
raise StandardError, "Under investigation"
|
362
|
+
got = @ndev.rpc.file_archive( :destination => filename, :source => directory )
|
363
|
+
end
|
364
|
+
|
365
|
+
# create a .tgz file from the files in the given directory.
|
366
|
+
# the filename does not need to include the .tgz extension, but
|
367
|
+
# if you include it, that's ok.
|
368
|
+
# NOTE: cannot specify an arbitrary list of files, per Junos RPC
|
369
|
+
|
370
|
+
def tgz___( directory, filename )
|
371
|
+
raise StandardError, "Under investigation"
|
372
|
+
got = @ndev.rpc.file_archive( :destination => filename, :source => directory, :compress => true )
|
373
|
+
end
|
374
|
+
|
375
|
+
end
|
376
|
+
|