junos-ez-stdlib 0.0.10

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.
Files changed (52) hide show
  1. data/LICENSE +26 -0
  2. data/README.md +181 -0
  3. data/docs/Config_Utils.md +3 -0
  4. data/docs/Facts.md +106 -0
  5. data/docs/Filesys_Utils.md +3 -0
  6. data/docs/IPports.md +3 -0
  7. data/docs/L1ports.md +3 -0
  8. data/docs/L2ports.md +3 -0
  9. data/docs/Providers_Resources.md +304 -0
  10. data/docs/RE_utils.md +3 -0
  11. data/docs/StaticHosts.md +3 -0
  12. data/docs/StaticRoutes.md +3 -0
  13. data/docs/Vlans.md +3 -0
  14. data/examples/config/config_file.rb +72 -0
  15. data/examples/config/config_template_object.rb +81 -0
  16. data/examples/config/config_template_simple.rb +76 -0
  17. data/examples/config/multi_config.rb +60 -0
  18. data/examples/fs_utils.rb +31 -0
  19. data/examples/re_upgrade.rb +90 -0
  20. data/examples/re_utils.rb +30 -0
  21. data/examples/simple.rb +47 -0
  22. data/examples/st_hosts.rb +33 -0
  23. data/examples/vlans.rb +25 -0
  24. data/junos-ez-stdlib.gemspec +15 -0
  25. data/lib/junos-ez/facts/chassis.rb +45 -0
  26. data/lib/junos-ez/facts/ifd_style.rb +14 -0
  27. data/lib/junos-ez/facts/personality.rb +22 -0
  28. data/lib/junos-ez/facts/switch_style.rb +22 -0
  29. data/lib/junos-ez/facts/version.rb +32 -0
  30. data/lib/junos-ez/facts.rb +85 -0
  31. data/lib/junos-ez/ip_ports/classic.rb +149 -0
  32. data/lib/junos-ez/ip_ports.rb +28 -0
  33. data/lib/junos-ez/l1_ports/classic.rb +87 -0
  34. data/lib/junos-ez/l1_ports/switch.rb +134 -0
  35. data/lib/junos-ez/l1_ports.rb +81 -0
  36. data/lib/junos-ez/l2_ports/bridge_domain.rb +0 -0
  37. data/lib/junos-ez/l2_ports/vlan.rb +317 -0
  38. data/lib/junos-ez/l2_ports/vlan_l2ng.rb +0 -0
  39. data/lib/junos-ez/l2_ports.rb +57 -0
  40. data/lib/junos-ez/provider.rb +608 -0
  41. data/lib/junos-ez/stdlib.rb +16 -0
  42. data/lib/junos-ez/system/st_hosts.rb +74 -0
  43. data/lib/junos-ez/system/st_routes.rb +135 -0
  44. data/lib/junos-ez/system/syscfg.rb +103 -0
  45. data/lib/junos-ez/system.rb +98 -0
  46. data/lib/junos-ez/utils/config.rb +205 -0
  47. data/lib/junos-ez/utils/fs.rb +376 -0
  48. data/lib/junos-ez/utils/re.rb +371 -0
  49. data/lib/junos-ez/vlans/bridge_domain.rb +85 -0
  50. data/lib/junos-ez/vlans/vlan.rb +112 -0
  51. data/lib/junos-ez/vlans.rb +31 -0
  52. 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
+