shopify-junos-ez-stdlib 1.0.0
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 +7 -0
- data/CHANGELOG.md +91 -0
- data/LICENSE +26 -0
- data/README.md +199 -0
- data/docs/Facts.md +192 -0
- data/docs/Providers/Group.md +61 -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/LAGports.md +57 -0
- data/docs/Providers/StaticHosts.md +26 -0
- data/docs/Providers/StaticRoutes.md +37 -0
- data/docs/Providers/UserAuths.md +32 -0
- data/docs/Providers/Users.md +122 -0
- data/docs/Providers/Vlans.md +43 -0
- data/docs/Providers_Resources.md +353 -0
- data/docs/README_FIRST.md +27 -0
- data/docs/Utils/Config.md +160 -0
- data/docs/Utils/Filesystem.md +360 -0
- data/docs/Utils/Routing-Engine.md +379 -0
- data/docs/Utils/SCP.md +24 -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/lag_port.rb +27 -0
- data/examples/re_upgrade.rb +99 -0
- data/examples/re_utils.rb +33 -0
- data/examples/simple.rb +46 -0
- data/examples/st_hosts.rb +33 -0
- data/examples/user.rb +32 -0
- data/examples/vlans.rb +31 -0
- data/junos-ez-stdlib.gemspec +15 -0
- data/lib/junos-ez/exceptions.rb +3 -0
- data/lib/junos-ez/facts.rb +83 -0
- data/lib/junos-ez/facts/chassis.rb +51 -0
- data/lib/junos-ez/facts/ifd_style.rb +17 -0
- data/lib/junos-ez/facts/personality.rb +25 -0
- data/lib/junos-ez/facts/switch_style.rb +31 -0
- data/lib/junos-ez/facts/version.rb +58 -0
- data/lib/junos-ez/group.rb +206 -0
- data/lib/junos-ez/ip_ports.rb +30 -0
- data/lib/junos-ez/ip_ports/classic.rb +188 -0
- data/lib/junos-ez/l1_ports.rb +121 -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/l2_ports.rb +66 -0
- data/lib/junos-ez/l2_ports/bridge_domain.rb +499 -0
- data/lib/junos-ez/l2_ports/vlan.rb +433 -0
- 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 +619 -0
- data/lib/junos-ez/stdlib.rb +18 -0
- data/lib/junos-ez/system.rb +48 -0
- data/lib/junos-ez/system/st_hosts.rb +92 -0
- data/lib/junos-ez/system/st_routes.rb +159 -0
- data/lib/junos-ez/system/syscfg.rb +103 -0
- data/lib/junos-ez/system/userauths.rb +84 -0
- data/lib/junos-ez/system/users.rb +217 -0
- data/lib/junos-ez/utils/config.rb +236 -0
- data/lib/junos-ez/utils/fs.rb +385 -0
- data/lib/junos-ez/utils/re.rb +558 -0
- data/lib/junos-ez/version.rb +6 -0
- data/lib/junos-ez/vlans.rb +38 -0
- data/lib/junos-ez/vlans/bridge_domain.rb +89 -0
- data/lib/junos-ez/vlans/vlan.rb +119 -0
- data/lib/junos-ez/vlans/vlan_l2ng.rb +126 -0
- data/shipit.yml +4 -0
- data/tmp +7 -0
- metadata +129 -0
| @@ -0,0 +1,385 @@ | |
| 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 | 
            +
                  raise IOError, 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 | 
            +
                    xml_when_item(file.xpath('file-symlink-target')) { |i|
         | 
| 164 | 
            +
                      f_h[:symlink] = i.text.strip
         | 
| 165 | 
            +
                    }
         | 
| 166 | 
            +
                    
         | 
| 167 | 
            +
                    fp = file.xpath('file-permissions')[0]
         | 
| 168 | 
            +
                    f_h[:permissions_text] = fp.attribute('format').value
         | 
| 169 | 
            +
                    f_h[:permissions] = fp.text.to_i
         | 
| 170 | 
            +
                    
         | 
| 171 | 
            +
                    fd = file.xpath('file-date')[0]
         | 
| 172 | 
            +
                    f_h[:date] = fd.attribute('format').value
         | 
| 173 | 
            +
                    f_h[:date_epoc] = fd.text.to_i
         | 
| 174 | 
            +
                    
         | 
| 175 | 
            +
                  end # each directory file
         | 
| 176 | 
            +
                  ls_hash[ dir_name ] = dir_hash        
         | 
| 177 | 
            +
                end # each directory
         | 
| 178 | 
            +
                
         | 
| 179 | 
            +
                return nil if ls_hash.empty?
         | 
| 180 | 
            +
                ls_hash
         | 
| 181 | 
            +
              end # method: ls
         | 
| 182 | 
            +
              
         | 
| 183 | 
            +
             | 
| 184 | 
            +
              ### -------------------------------------------------------------
         | 
| 185 | 
            +
              ### cat - is used to obtain the text contents of the file
         | 
| 186 | 
            +
              ### -------------------------------------------------------------
         | 
| 187 | 
            +
              
         | 
| 188 | 
            +
              def cat( filename )                   
         | 
| 189 | 
            +
                begin
         | 
| 190 | 
            +
                  @ndev.rpc.file_show( :filename => filename ).text
         | 
| 191 | 
            +
                rescue => e
         | 
| 192 | 
            +
                  raise IOError, e.rsp.xpath('rpc-error/error-message').text.strip
         | 
| 193 | 
            +
                end
         | 
| 194 | 
            +
              end
         | 
| 195 | 
            +
              
         | 
| 196 | 
            +
             | 
| 197 | 
            +
              
         | 
| 198 | 
            +
              ### -------------------------------------------------------------
         | 
| 199 | 
            +
              ### df - shows the system storage information
         | 
| 200 | 
            +
              ###
         | 
| 201 | 
            +
              ### opts[:format] = [:text, :xml, :hash]
         | 
| 202 | 
            +
              ###    defaults :hash
         | 
| 203 | 
            +
              ###
         | 
| 204 | 
            +
              ### opts[:size_div] = value to device size values, 
         | 
| 205 | 
            +
              ###    valid only for :format == :hash
         | 
| 206 | 
            +
              ### -------------------------------------------------------------
         | 
| 207 | 
            +
              
         | 
| 208 | 
            +
              def df( opts = {} )
         | 
| 209 | 
            +
                    
         | 
| 210 | 
            +
                outf = {:format => 'text' } if opts[:format] == :text
         | 
| 211 | 
            +
                args = { :detail => true } if opts[:size_div]
         | 
| 212 | 
            +
                
         | 
| 213 | 
            +
                got = @ndev.rpc.get_system_storage( args, outf )
         | 
| 214 | 
            +
                
         | 
| 215 | 
            +
                return got.text if opts[:format] == :text
         | 
| 216 | 
            +
                return got if opts[:format] == :xml
         | 
| 217 | 
            +
                
         | 
| 218 | 
            +
                df_h = {}
         | 
| 219 | 
            +
                ### need to turn this into a Hash
         | 
| 220 | 
            +
                got.xpath('filesystem').each do |fs|
         | 
| 221 | 
            +
                  fs_name = fs.xpath('filesystem-name').text.strip
         | 
| 222 | 
            +
                  fs_h = {}
         | 
| 223 | 
            +
                  df_h[fs_name] = fs_h
         | 
| 224 | 
            +
                  
         | 
| 225 | 
            +
                  fs_h[:mounted_on] = fs.xpath('mounted-on').text.strip        
         | 
| 226 | 
            +
                  datum = fs.xpath('total-blocks')
         | 
| 227 | 
            +
                  fs_h[:total_blocks] = datum.text.to_i
         | 
| 228 | 
            +
                  fs_h[:total_size] = datum.attribute('format').value
         | 
| 229 | 
            +
                  
         | 
| 230 | 
            +
                  datum = fs.xpath('used-blocks')
         | 
| 231 | 
            +
                  fs_h[:used_blocks] = datum.text.to_i
         | 
| 232 | 
            +
                  fs_h[:used_size] = datum.attribute('format').value
         | 
| 233 | 
            +
                  fs_h[:used_percent] = fs.xpath('used-percent').text.to_i
         | 
| 234 | 
            +
                  
         | 
| 235 | 
            +
                  datum = fs.xpath('available-blocks')
         | 
| 236 | 
            +
                  fs_h[:avail_blocks] = datum.text.to_i
         | 
| 237 | 
            +
                  fs_h[:avail_size] = datum.attribute('format').value
         | 
| 238 | 
            +
                  if opts[:size_div]
         | 
| 239 | 
            +
                    fs_h[:total_size] = fs_h[:total_size].to_i / opts[:size_div]
         | 
| 240 | 
            +
                    fs_h[:used_size] = fs_h[:used_size].to_i / opts[:size_div]
         | 
| 241 | 
            +
                    fs_h[:avail_size] = fs_h[:avail_size].to_i / opts[:size_div]
         | 
| 242 | 
            +
                  end
         | 
| 243 | 
            +
                end
         | 
| 244 | 
            +
                df_h
         | 
| 245 | 
            +
              end
         | 
| 246 | 
            +
              
         | 
| 247 | 
            +
              ### -------------------------------------------------------------
         | 
| 248 | 
            +
              ### cleanup! will perform the 'request system storage cleanup'
         | 
| 249 | 
            +
              ### command and remove the files.  If you want to check which
         | 
| 250 | 
            +
              ### files will be removed, use the cleanup? method first
         | 
| 251 | 
            +
              ### -------------------------------------------------------------
         | 
| 252 | 
            +
              
         | 
| 253 | 
            +
              def cleanup!
         | 
| 254 | 
            +
                got = @ndev.rpc.request_system_storage_cleanup
         | 
| 255 | 
            +
                gone_h = {}
         | 
| 256 | 
            +
                got.xpath('file-list/file').each do |file|
         | 
| 257 | 
            +
                  _cleanup_file_to_h( file, gone_h )
         | 
| 258 | 
            +
                end
         | 
| 259 | 
            +
                gone_h
         | 
| 260 | 
            +
              end
         | 
| 261 | 
            +
              
         | 
| 262 | 
            +
              ### -------------------------------------------------------------
         | 
| 263 | 
            +
              ### 'cleanup?' will return information on files that would be
         | 
| 264 | 
            +
              ### removed if cleanup! was executed
         | 
| 265 | 
            +
              ### -------------------------------------------------------------
         | 
| 266 | 
            +
              
         | 
| 267 | 
            +
              def cleanup?
         | 
| 268 | 
            +
                got = @ndev.rpc.request_system_storage_cleanup( :dry_run => true )
         | 
| 269 | 
            +
                dryrun_h = {}
         | 
| 270 | 
            +
                got.xpath('file-list/file').each do |file|
         | 
| 271 | 
            +
                  _cleanup_file_to_h( file, dryrun_h )
         | 
| 272 | 
            +
                end
         | 
| 273 | 
            +
                dryrun_h    
         | 
| 274 | 
            +
              end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
              ### -------------------------------------------------------------
         | 
| 277 | 
            +
              ### cp! - copies a file.  The from_file and to_file can be
         | 
| 278 | 
            +
              ### URL parameters, yo!
         | 
| 279 | 
            +
              ###
         | 
| 280 | 
            +
              ### opts[:source_address] will set the source address of the
         | 
| 281 | 
            +
              ### copy command, useful when URL contain SCP, HTTP
         | 
| 282 | 
            +
              ### -------------------------------------------------------------
         | 
| 283 | 
            +
              
         | 
| 284 | 
            +
              def cp!( from_file, to_file, opts = {} )
         | 
| 285 | 
            +
                args = { :source => from_file, :destination => to_file }
         | 
| 286 | 
            +
                args[:source_address] = opts[:source_address] if opts[:source_address]
         | 
| 287 | 
            +
                
         | 
| 288 | 
            +
                begin
         | 
| 289 | 
            +
                  got = @ndev.rpc.file_copy( args )
         | 
| 290 | 
            +
                rescue => e
         | 
| 291 | 
            +
                  raise IOError, e.rsp.xpath('rpc-error/error-message').text.strip
         | 
| 292 | 
            +
                else
         | 
| 293 | 
            +
                  return true
         | 
| 294 | 
            +
                end
         | 
| 295 | 
            +
              end
         | 
| 296 | 
            +
              
         | 
| 297 | 
            +
              ### -------------------------------------------------------------
         | 
| 298 | 
            +
              ### 'mv' - just like unix, moves/renames a file
         | 
| 299 | 
            +
              ### -------------------------------------------------------------
         | 
| 300 | 
            +
              
         | 
| 301 | 
            +
              def mv!( from_path, to_path )
         | 
| 302 | 
            +
                got = @ndev.rpc.command( "file rename #{from_path} #{to_path}" )
         | 
| 303 | 
            +
                return true if got.nil?     # got no error
         | 
| 304 | 
            +
                raise IOError, got.text
         | 
| 305 | 
            +
              end  
         | 
| 306 | 
            +
              
         | 
| 307 | 
            +
              ### -------------------------------------------------------------
         | 
| 308 | 
            +
              ### rm! - just like unix, removes files
         | 
| 309 | 
            +
              ### -------------------------------------------------------------
         | 
| 310 | 
            +
              
         | 
| 311 | 
            +
              def rm!( path )
         | 
| 312 | 
            +
                got = @ndev.rpc.file_delete( :path => path )
         | 
| 313 | 
            +
                return true if got.nil?     # got no error
         | 
| 314 | 
            +
                # otherwise, there was an error, check output
         | 
| 315 | 
            +
                raise IOError, got.text
         | 
| 316 | 
            +
              end
         | 
| 317 | 
            +
                
         | 
| 318 | 
            +
              
         | 
| 319 | 
            +
            end # class Provider    
         | 
| 320 | 
            +
             | 
| 321 | 
            +
            ### -----------------------------------------------------------------
         | 
| 322 | 
            +
            ###                        PRIVATE METHODS
         | 
| 323 | 
            +
            ### -----------------------------------------------------------------
         | 
| 324 | 
            +
            ### These are helper/private methods, or methods that are current
         | 
| 325 | 
            +
            ### work-in-progress/under-investigation
         | 
| 326 | 
            +
            ### -----------------------------------------------------------------
         | 
| 327 | 
            +
             | 
| 328 | 
            +
            class Junos::Ez::FS::Provider
         | 
| 329 | 
            +
              private
         | 
| 330 | 
            +
              
         | 
| 331 | 
            +
              ### private method used to convert 'cleanup' file XML
         | 
| 332 | 
            +
              ### to hash structure and bind it to collecting hash
         | 
| 333 | 
            +
              
         | 
| 334 | 
            +
              def _cleanup_file_to_h( file, attach_h )
         | 
| 335 | 
            +
                file_name = file.xpath('file-name').text.strip
         | 
| 336 | 
            +
                file_h = {}
         | 
| 337 | 
            +
                data = file.xpath('size')
         | 
| 338 | 
            +
                file_h[:size_text] = data.attribute('format').value
         | 
| 339 | 
            +
                file_h[:size] = data.text.to_i
         | 
| 340 | 
            +
                file_h[:date] = file.xpath('date').text.strip
         | 
| 341 | 
            +
                attach_h[file_name] = file_h
         | 
| 342 | 
            +
                file_h    
         | 
| 343 | 
            +
              end
         | 
| 344 | 
            +
              
         | 
| 345 | 
            +
              ##### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 346 | 
            +
              ##### ... HERE THERE BE MONSTERS ....
         | 
| 347 | 
            +
              ##### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         | 
| 348 | 
            +
              
         | 
| 349 | 
            +
              ### -------------------------------------------------------------
         | 
| 350 | 
            +
              ### 'diff' just like unix; patch output
         | 
| 351 | 
            +
              ### @@@ something is getting messed up in the XML translation
         | 
| 352 | 
            +
              ### @@@ as control characters like (<,>) are getting munged.
         | 
| 353 | 
            +
              ### @@@ need to investigate with Nokogiri ....
         | 
| 354 | 
            +
              ### -------------------------------------------------------------
         | 
| 355 | 
            +
              
         | 
| 356 | 
            +
              def diff___( from_file, to_file )
         | 
| 357 | 
            +
                raise StandardError, "Under investigation"      
         | 
| 358 | 
            +
                got = @ndev.rpc.file_compare( :from_file => from_file, :to_file => to_file )
         | 
| 359 | 
            +
              end  
         | 
| 360 | 
            +
              
         | 
| 361 | 
            +
              # create a .tar file from the files in the given directory.
         | 
| 362 | 
            +
              # the filename does not need to include the .tar extension, but
         | 
| 363 | 
            +
              # if you include it, that's ok.
         | 
| 364 | 
            +
              # NOTE: cannot specify an arbitrary list of files, per Junos RPC
         | 
| 365 | 
            +
              
         | 
| 366 | 
            +
              ### !!!! these are only allowed from the CLI, at least as tested 
         | 
| 367 | 
            +
              ### !!!! on an vSRX.  Need to check on other platforms, etc.
         | 
| 368 | 
            +
              
         | 
| 369 | 
            +
              def tar___( directory, filename )
         | 
| 370 | 
            +
                raise StandardError, "Under investigation"
         | 
| 371 | 
            +
                got = @ndev.rpc.file_archive( :destination => filename, :source => directory )
         | 
| 372 | 
            +
              end
         | 
| 373 | 
            +
              
         | 
| 374 | 
            +
              # create a .tgz file from the files in the given directory.
         | 
| 375 | 
            +
              # the filename does not need to include the .tgz extension, but
         | 
| 376 | 
            +
              # if you include it, that's ok.
         | 
| 377 | 
            +
              # NOTE: cannot specify an arbitrary list of files, per Junos RPC
         | 
| 378 | 
            +
              
         | 
| 379 | 
            +
              def tgz___(  directory, filename )
         | 
| 380 | 
            +
                raise StandardError, "Under investigation"      
         | 
| 381 | 
            +
                got = @ndev.rpc.file_archive( :destination => filename, :source => directory, :compress => true )
         | 
| 382 | 
            +
              end
         | 
| 383 | 
            +
              
         | 
| 384 | 
            +
            end
         | 
| 385 | 
            +
             | 
| @@ -0,0 +1,558 @@ | |
| 1 | 
            +
            =begin
         | 
| 2 | 
            +
            ---------------------------------------------------------------------
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            This file contains routing-engine utility methods.  These are
         | 
| 5 | 
            +
            a misc. collection of methods that perform basic automation tasks
         | 
| 6 | 
            +
            like upgrading software or getting process information.  The 
         | 
| 7 | 
            +
            following lists the methods and the equivalent Junos CLI commands
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            - status            show chassis routing-engine
         | 
| 10 | 
            +
            - uptime            show system uptime
         | 
| 11 | 
            +
            - system_alarms     show system alarms
         | 
| 12 | 
            +
            - chassis_alarms    show chassis alarms
         | 
| 13 | 
            +
            - memory            show system memeory
         | 
| 14 | 
            +
            - users             show system users
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            - software_install!     request system software add 
         | 
| 17 | 
            +
            - software_rollback!    request system software rollback
         | 
| 18 | 
            +
            - software_validate?    request system software validate
         | 
| 19 | 
            +
            - software_images       - provides image file names for current/rollback
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            - license_install!      request system license add          !! TBD !!
         | 
| 22 | 
            +
            - license_rm!           request system license delete
         | 
| 23 | 
            +
            - license_save          request system license save         !! TBD !!
         | 
| 24 | 
            +
            - licenses              show system license
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            - reboot!: request system reboot (no confirm!!)
         | 
| 27 | 
            +
            - shutdown!: request system power-off (no confirm!!)
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
            ---------------------------------------------------------------------
         | 
| 30 | 
            +
            =end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            module Junos::Ez::RE
         | 
| 33 | 
            +
              def self.Utils( ndev, varsym )            
         | 
| 34 | 
            +
                newbie = Junos::Ez::RE::Provider.new( ndev )      
         | 
| 35 | 
            +
                Junos::Ez::Provider.attach_instance_variable( ndev, varsym, newbie )    
         | 
| 36 | 
            +
              end          
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            ### -----------------------------------------------------------------
         | 
| 40 | 
            +
            ###                        PUBLIC METHODS
         | 
| 41 | 
            +
            ### -----------------------------------------------------------------
         | 
| 42 | 
            +
            ### class containing filesystem public utility functions
         | 
| 43 | 
            +
            ### these are not in alphabetical order, but I should do that, yo!
         | 
| 44 | 
            +
            ### -----------------------------------------------------------------
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            class Junos::Ez::RE::Provider < Junos::Ez::Provider::Parent
         | 
| 47 | 
            +
                
         | 
| 48 | 
            +
              ### ---------------------------------------------------------------
         | 
| 49 | 
            +
              ### status - show chassis routing-engine information
         | 
| 50 | 
            +
              ### ---------------------------------------------------------------
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              def status( opts = {} )
         | 
| 53 | 
            +
                got = @ndev.rpc.get_route_engine_information
         | 
| 54 | 
            +
                status_h = {}
         | 
| 55 | 
            +
                got.xpath('//route-engine').each do |re|
         | 
| 56 | 
            +
                  re_h = {}      
         | 
| 57 | 
            +
                  slot_id = "re" + re.xpath('slot').text
         | 
| 58 | 
            +
                  status_h[slot_id] = re_h
         | 
| 59 | 
            +
                  
         | 
| 60 | 
            +
                  re_h[:model] = re.xpath('model').text.strip
         | 
| 61 | 
            +
                  re_h[:serialnumber] = re.xpath('serial-number').text.strip
         | 
| 62 | 
            +
                  
         | 
| 63 | 
            +
                  xml_when_item(re.xpath('mastership-state')){|i| re_h[:mastership] = i.text.strip}
         | 
| 64 | 
            +
                  
         | 
| 65 | 
            +
                  re_h[:temperature] = {
         | 
| 66 | 
            +
                    :system => re.xpath('temperature').text.strip,
         | 
| 67 | 
            +
                    :cpu => re.xpath('cpu-temperature').text.strip
         | 
| 68 | 
            +
                  }
         | 
| 69 | 
            +
                  re_h[:memory] = {
         | 
| 70 | 
            +
                    :total_size => re.xpath('memory-dram-size').text.to_i,
         | 
| 71 | 
            +
                    :buffer_util => re.xpath('memory-buffer-itilization').text.to_i
         | 
| 72 | 
            +
                  }
         | 
| 73 | 
            +
                  re_h[:cpu_util] = {
         | 
| 74 | 
            +
                    :user => re.xpath('cpu-user').text.to_i,
         | 
| 75 | 
            +
                    :background => re.xpath('cpu-background').text.to_i,
         | 
| 76 | 
            +
                    :system => re.xpath('cpu-system').text.to_i,
         | 
| 77 | 
            +
                    :interrupt => re.xpath('cpu-interrupt').text.to_i,
         | 
| 78 | 
            +
                    :idle => re.xpath('cpu-idle').text.to_i,
         | 
| 79 | 
            +
                  }
         | 
| 80 | 
            +
                  re_h[:uptime] = {
         | 
| 81 | 
            +
                    :at => re.xpath('start-time').text.strip,
         | 
| 82 | 
            +
                    :ago => re.xpath('up-time').text.strip,
         | 
| 83 | 
            +
                    :reboot_reason => re.xpath('last-reboot-reason').text.strip
         | 
| 84 | 
            +
                  }
         | 
| 85 | 
            +
                  re_h[:load_avg] = [
         | 
| 86 | 
            +
                    re.xpath('load-average-one').text.to_f,
         | 
| 87 | 
            +
                    re.xpath('load-average-five').text.to_f,
         | 
| 88 | 
            +
                    re.xpath('load-average-fifteen').text.to_f
         | 
| 89 | 
            +
                  ]
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
                status_h
         | 
| 92 | 
            +
              end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
              ### ---------------------------------------------------------------
         | 
| 95 | 
            +
              ### uptime - show system uptime information
         | 
| 96 | 
            +
              ### ---------------------------------------------------------------
         | 
| 97 | 
            +
              
         | 
| 98 | 
            +
              def uptime
         | 
| 99 | 
            +
                up_h = {}    
         | 
| 100 | 
            +
                got = @ndev.rpc.get_system_uptime_information
         | 
| 101 | 
            +
                unless (n_re = got.xpath('multi-routing-engine-item')).empty?
         | 
| 102 | 
            +
                  n_re.each do |this_re|
         | 
| 103 | 
            +
                    as_xml = this_re.xpath('system-uptime-information')
         | 
| 104 | 
            +
                    re_name = this_re.xpath('re-name').text.strip
         | 
| 105 | 
            +
                    up_h[re_name] = {}
         | 
| 106 | 
            +
                    _uptime_to_h( as_xml, up_h[re_name] )
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
                else
         | 
| 109 | 
            +
                  up_h['re0'] = {}
         | 
| 110 | 
            +
                  _uptime_to_h( got, up_h['re0'] )
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
                up_h        
         | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              ### ---------------------------------------------------------------
         | 
| 116 | 
            +
              ### system_alarms - show system alarms
         | 
| 117 | 
            +
              ### ---------------------------------------------------------------
         | 
| 118 | 
            +
              
         | 
| 119 | 
            +
              def system_alarms
         | 
| 120 | 
            +
                got = @ndev.rpc.get_system_alarm_information
         | 
| 121 | 
            +
                alarms_a = []
         | 
| 122 | 
            +
                got.xpath('alarm-detail').each do |alarm|
         | 
| 123 | 
            +
                  alarm_h = {}      
         | 
| 124 | 
            +
                  _alarm_info_to_h( alarm, alarm_h )
         | 
| 125 | 
            +
                  alarms_a << alarm_h
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
                return nil if alarms_a.empty?
         | 
| 128 | 
            +
                alarms_a    
         | 
| 129 | 
            +
              end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
              ### ---------------------------------------------------------------
         | 
| 132 | 
            +
              ### chassis_alarms - show chassis alarms
         | 
| 133 | 
            +
              ### ---------------------------------------------------------------
         | 
| 134 | 
            +
              
         | 
| 135 | 
            +
              def chassis_alarms
         | 
| 136 | 
            +
                got = @ndev.rpc.get_alarm_information  
         | 
| 137 | 
            +
                alarms_a = []
         | 
| 138 | 
            +
                got.xpath('alarm-detail').each do |alarm|
         | 
| 139 | 
            +
                  alarm_h = {}
         | 
| 140 | 
            +
                  _alarm_info_to_h( alarm, alarm_h )
         | 
| 141 | 
            +
                  alarms_a << alarm_h
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
                return nil if alarms_a.empty?
         | 
| 144 | 
            +
                alarms_a
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
              ### ---------------------------------------------------------------
         | 
| 148 | 
            +
              ### memory - show system memory
         | 
| 149 | 
            +
              ### ---------------------------------------------------------------
         | 
| 150 | 
            +
              
         | 
| 151 | 
            +
              def memory
         | 
| 152 | 
            +
                got = @ndev.rpc.get_system_memory_information
         | 
| 153 | 
            +
                ret_h = {}
         | 
| 154 | 
            +
                unless (n_re = got.xpath('multi-routing-engine-item')).empty?
         | 
| 155 | 
            +
                  n_re.each do |this_re|
         | 
| 156 | 
            +
                    as_xml = this_re.xpath('system-memory-information')[0]
         | 
| 157 | 
            +
                    re_name = this_re.xpath('re-name').text.strip
         | 
| 158 | 
            +
                    ret_h[re_name] = {}
         | 
| 159 | 
            +
                    _system_memory_to_h( as_xml, ret_h[re_name] )
         | 
| 160 | 
            +
                  end      
         | 
| 161 | 
            +
                else
         | 
| 162 | 
            +
                  ret_h['re0'] = {}
         | 
| 163 | 
            +
                  _system_memory_to_h( got, ret_h['re0'] )      
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
                ret_h
         | 
| 166 | 
            +
              end
         | 
| 167 | 
            +
             | 
| 168 | 
            +
              ### ---------------------------------------------------------------
         | 
| 169 | 
            +
              ### users - show system users
         | 
| 170 | 
            +
              ### ---------------------------------------------------------------
         | 
| 171 | 
            +
              
         | 
| 172 | 
            +
              def users
         | 
| 173 | 
            +
                got = @ndev.rpc.get_system_users_information
         | 
| 174 | 
            +
                users_a = []
         | 
| 175 | 
            +
                got.xpath('uptime-information/user-table/user-entry').each do |user|
         | 
| 176 | 
            +
                  user_h = {}
         | 
| 177 | 
            +
                  users_a << user_h
         | 
| 178 | 
            +
                  
         | 
| 179 | 
            +
                  user_h[:name] = user.xpath('user').text.strip
         | 
| 180 | 
            +
                  user_h[:tty] = user.xpath('tty').text.strip
         | 
| 181 | 
            +
                  user_h[:from] = user.xpath('from').text.strip
         | 
| 182 | 
            +
                  user_h[:login_time] = user.xpath('login-time').text.strip
         | 
| 183 | 
            +
                  user_h[:idle_time] = user.xpath('idel-time').text.strip
         | 
| 184 | 
            +
                  user_h[:idle_time] = nil if user_h[:idle_time].empty?
         | 
| 185 | 
            +
                  user_h[:command] = user.xpath('command').text.strip
         | 
| 186 | 
            +
                end
         | 
| 187 | 
            +
                users_a
         | 
| 188 | 
            +
              end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
              ### ===============================================================
         | 
| 191 | 
            +
              ###
         | 
| 192 | 
            +
              ###                   Software related methods
         | 
| 193 | 
            +
              ###
         | 
| 194 | 
            +
              ### ===============================================================
         | 
| 195 | 
            +
              
         | 
| 196 | 
            +
              ### ---------------------------------------------------------------
         | 
| 197 | 
            +
              ### software_validate? - request system software validate ...
         | 
| 198 | 
            +
              ### ---------------------------------------------------------------
         | 
| 199 | 
            +
              
         | 
| 200 | 
            +
              def software_validate?( package )
         | 
| 201 | 
            +
                got = @ndev.rpc.request_package_validate(:package_name => package).parent
         | 
| 202 | 
            +
                errcode = got.xpath('package-result').text.to_i
         | 
| 203 | 
            +
                return true if errcode == 0
         | 
| 204 | 
            +
                
         | 
| 205 | 
            +
                # otherwise return the output error message
         | 
| 206 | 
            +
                got.xpath('output').text.strip    
         | 
| 207 | 
            +
              end
         | 
| 208 | 
            +
             | 
| 209 | 
            +
              ### ---------------------------------------------------------------
         | 
| 210 | 
            +
              ### software_install! - request system software add ...
         | 
| 211 | 
            +
              ### ---------------------------------------------------------------
         | 
| 212 | 
            +
              
         | 
| 213 | 
            +
              def software_install!( opts = {} )
         | 
| 214 | 
            +
                raise ArgumentError "missing :package" unless opts[:package]
         | 
| 215 | 
            +
                
         | 
| 216 | 
            +
                args = { :package_name => opts[:package] }
         | 
| 217 | 
            +
                args[:no_validate] = true if opts[:no_validate]
         | 
| 218 | 
            +
                args[:unlink] = true if opts[:unlink]
         | 
| 219 | 
            +
                args[:reboot] = true if opts[:reboot]
         | 
| 220 | 
            +
                
         | 
| 221 | 
            +
                got = @ndev.rpc.request_package_add( args ).parent
         | 
| 222 | 
            +
                errcode = got.xpath('package-result').text.to_i
         | 
| 223 | 
            +
                return true if errcode == 0
         | 
| 224 | 
            +
                
         | 
| 225 | 
            +
                # otherwise return the output error message
         | 
| 226 | 
            +
                got.xpath('output').text.strip    
         | 
| 227 | 
            +
              end
         | 
| 228 | 
            +
             | 
| 229 | 
            +
              ### ---------------------------------------------------------------
         | 
| 230 | 
            +
              ### software_rollback! - request system software rollback
         | 
| 231 | 
            +
              ### ---------------------------------------------------------------
         | 
| 232 | 
            +
              
         | 
| 233 | 
            +
              def software_rollback!
         | 
| 234 | 
            +
                got = @ndev.rpc.request_package_rollback
         | 
| 235 | 
            +
                got.text.strip
         | 
| 236 | 
            +
              end
         | 
| 237 | 
            +
              
         | 
| 238 | 
            +
              def software_images
         | 
| 239 | 
            +
                ls_pkgs = @ndev.rpc.file_list(:path=>'/packages')
         | 
| 240 | 
            +
                symlink = ls_pkgs.xpath('//file-symlink-target')[0]
         | 
| 241 | 
            +
                if symlink
         | 
| 242 | 
            +
                  ls_pkgs = @ndev.rpc.file_list(:path => symlink.text.strip)
         | 
| 243 | 
            +
                end
         | 
| 244 | 
            +
                
         | 
| 245 | 
            +
                junos_symlink = ls_pkgs.xpath('//file-information[normalize-space(file-name) = "junos"]')[0]
         | 
| 246 | 
            +
                junos_old_symlink = ls_pkgs.xpath('//file-information[normalize-space(file-name) = "junos.old"]')[0]
         | 
| 247 | 
            +
                
         | 
| 248 | 
            +
                ret_h = {}    
         | 
| 249 | 
            +
                ret_h[:rollback] = (junos_old_symlink) ? junos_old_symlink.xpath('file-symlink-target').text.strip : nil
         | 
| 250 | 
            +
                ret_h[:current] = (junos_symlink) ? junos_symlink.xpath('file-symlink-target').text.strip : ret_h[:rollback]
         | 
| 251 | 
            +
                
         | 
| 252 | 
            +
                ret_h
         | 
| 253 | 
            +
              end
         | 
| 254 | 
            +
             | 
| 255 | 
            +
              ### ===============================================================
         | 
| 256 | 
            +
              ###
         | 
| 257 | 
            +
              ###             Misc Routing Engine Commands & Controls
         | 
| 258 | 
            +
              ###
         | 
| 259 | 
            +
              ### ===============================================================
         | 
| 260 | 
            +
              
         | 
| 261 | 
            +
              ### ---------------------------------------------------------------
         | 
| 262 | 
            +
              ### reboot! - request system reboot (no confirm!!)
         | 
| 263 | 
            +
              ### ---------------------------------------------------------------
         | 
| 264 | 
            +
              
         | 
| 265 | 
            +
              def reboot!( opts = {} )    
         | 
| 266 | 
            +
                arg_options = [:in, :at]
         | 
| 267 | 
            +
                args = {}
         | 
| 268 | 
            +
                opts.each do |k,v|
         | 
| 269 | 
            +
                  if arg_options.include? k
         | 
| 270 | 
            +
                    args[k] = v
         | 
| 271 | 
            +
                  else
         | 
| 272 | 
            +
                    raise ArgumentError, "unrecognized option #{k}"
         | 
| 273 | 
            +
                  end
         | 
| 274 | 
            +
                end    
         | 
| 275 | 
            +
                got = @ndev.rpc.request_reboot( args )
         | 
| 276 | 
            +
                got.xpath('request-reboot-status').text.strip
         | 
| 277 | 
            +
              end
         | 
| 278 | 
            +
             | 
| 279 | 
            +
              ### ---------------------------------------------------------------
         | 
| 280 | 
            +
              ### shutdown! - request system power-off (no confirm!!)
         | 
| 281 | 
            +
              ### ---------------------------------------------------------------
         | 
| 282 | 
            +
              
         | 
| 283 | 
            +
              def shutdown!( opts = {} )
         | 
| 284 | 
            +
                arg_options = [:in, :at]
         | 
| 285 | 
            +
                args = {}
         | 
| 286 | 
            +
                opts.each do |k,v|
         | 
| 287 | 
            +
                  if arg_options.include? k
         | 
| 288 | 
            +
                    args[k] = v
         | 
| 289 | 
            +
                  else
         | 
| 290 | 
            +
                    raise ArgumentError, "unrecognized option #{k}"
         | 
| 291 | 
            +
                  end
         | 
| 292 | 
            +
                end        
         | 
| 293 | 
            +
                ## some Junos devices will throw an RPC error exception which is really
         | 
| 294 | 
            +
                ## a warning, and some do not.  So we need to trap that here.
         | 
| 295 | 
            +
                begin
         | 
| 296 | 
            +
                  got = @ndev.rpc.request_power_off( args )
         | 
| 297 | 
            +
                rescue => e
         | 
| 298 | 
            +
                  retmsg = e.rsp.xpath('//error-message').text.strip + "\n"  
         | 
| 299 | 
            +
                  return retmsg + e.rsp.xpath('//request-reboot-status').text.strip
         | 
| 300 | 
            +
                end
         | 
| 301 | 
            +
                got.xpath('//request-reboot-status').text.strip
         | 
| 302 | 
            +
              end
         | 
| 303 | 
            +
              
         | 
| 304 | 
            +
              def ping( host, opts = {} )
         | 
| 305 | 
            +
                arg_options = [ 
         | 
| 306 | 
            +
                  :do_not_fragment, :inet, :inet6, :strict,      
         | 
| 307 | 
            +
                  :count, :interface, :interval, :mac_address,
         | 
| 308 | 
            +
                  :routing_instance, :size, :source, :tos, :ttl, :wait
         | 
| 309 | 
            +
                ]
         | 
| 310 | 
            +
                
         | 
| 311 | 
            +
                args = {:host => host}
         | 
| 312 | 
            +
                opts.each do |k,v|
         | 
| 313 | 
            +
                  if arg_options.include? k
         | 
| 314 | 
            +
                    args[k] = v
         | 
| 315 | 
            +
                  else
         | 
| 316 | 
            +
                    raise ArgumentError, "unrecognized option #{k}"
         | 
| 317 | 
            +
                  end
         | 
| 318 | 
            +
                end
         | 
| 319 | 
            +
                
         | 
| 320 | 
            +
                args[:count] ||= 1
         | 
| 321 | 
            +
                    
         | 
| 322 | 
            +
                got = @ndev.rpc.ping( args )
         | 
| 323 | 
            +
                return true if got.xpath('ping-success')[0]
         | 
| 324 | 
            +
                
         | 
| 325 | 
            +
                # if the caller privded a 'failure block' then call that now,
         | 
| 326 | 
            +
                # otherwise, just return false
         | 
| 327 | 
            +
                
         | 
| 328 | 
            +
                return (block_given?) ? yield(got) : false
         | 
| 329 | 
            +
              end
         | 
| 330 | 
            +
              
         | 
| 331 | 
            +
              ### ===============================================================
         | 
| 332 | 
            +
              ###
         | 
| 333 | 
            +
              ###                   License related methods
         | 
| 334 | 
            +
              ###
         | 
| 335 | 
            +
              ### ===============================================================
         | 
| 336 | 
            +
              
         | 
| 337 | 
            +
              ## ----------------------------------------------------------------
         | 
| 338 | 
            +
              ## - retrieve Hash of license information.  
         | 
| 339 | 
            +
              ##
         | 
| 340 | 
            +
              ## By default this will provide the license installed
         | 
| 341 | 
            +
              ## information.  
         | 
| 342 | 
            +
              ## 
         | 
| 343 | 
            +
              ## --- returns ---
         | 
| 344 | 
            +
              ## - Hash of data if there are licenses
         | 
| 345 | 
            +
              ## - nil if no licenses
         | 
| 346 | 
            +
              ##
         | 
| 347 | 
            +
              ## --- options ---
         | 
| 348 | 
            +
              ## :keys => true
         | 
| 349 | 
            +
              ##    Will include the key-text for the license
         | 
| 350 | 
            +
              ##
         | 
| 351 | 
            +
              ## ----------------------------------------------------------------
         | 
| 352 | 
            +
              
         | 
| 353 | 
            +
              def licenses( opts = {} )
         | 
| 354 | 
            +
                
         | 
| 355 | 
            +
                got = @ndev.rpc.get_license_summary_information
         | 
| 356 | 
            +
                licenses = got.xpath('license-information/license')
         | 
| 357 | 
            +
                return nil if licenses.empty?
         | 
| 358 | 
            +
                
         | 
| 359 | 
            +
                ret_h = {}
         | 
| 360 | 
            +
                licenses.each do |lic|
         | 
| 361 | 
            +
                  lic_h = {}
         | 
| 362 | 
            +
                  ret_h[lic.xpath('name').text.strip] = lic_h
         | 
| 363 | 
            +
                  
         | 
| 364 | 
            +
                  lic_h[:state] = lic.xpath('license-state').text.strip
         | 
| 365 | 
            +
                  lic_h[:version] = lic.xpath('license-version').text.strip
         | 
| 366 | 
            +
                  lic_h[:serialnumber] = lic.xpath('software-sn').text.strip
         | 
| 367 | 
            +
                  lic_h[:customer] = lic.xpath('customer-reference').text.strip
         | 
| 368 | 
            +
                  
         | 
| 369 | 
            +
                  features = lic.xpath('feature-block/feature')
         | 
| 370 | 
            +
                  unless features.empty?
         | 
| 371 | 
            +
                    feats_h = {}
         | 
| 372 | 
            +
                    lic_h[:features] = feats_h
         | 
| 373 | 
            +
                    features.each do |feat|
         | 
| 374 | 
            +
                      feat_h = {}
         | 
| 375 | 
            +
                      feats_h[feat.xpath('name').text.strip] = feat_h
         | 
| 376 | 
            +
                      feat_h[:description] = feat.xpath('description').text.strip
         | 
| 377 | 
            +
                      v_info = feat.xpath('validity-information')[0]
         | 
| 378 | 
            +
                      case v_info.xpath('validity-type').text.strip
         | 
| 379 | 
            +
                      when 'date-based'
         | 
| 380 | 
            +
                        feat_h[:date_start] = v_info.xpath('start-date').text.strip
         | 
| 381 | 
            +
                        feat_h[:date_end] = v_info.xpath('end-date').text.strip
         | 
| 382 | 
            +
                      end
         | 
| 383 | 
            +
                    end # each features
         | 
| 384 | 
            +
                  end # if features
         | 
| 385 | 
            +
                end # each license
         | 
| 386 | 
            +
                
         | 
| 387 | 
            +
                ## now check to see if the :keys have been requested.  if so
         | 
| 388 | 
            +
                ## then get that data, and store back into the return Hash.
         | 
| 389 | 
            +
                
         | 
| 390 | 
            +
                if opts[:keys]
         | 
| 391 | 
            +
                  got = @ndev.rpc.get_license_key_information
         | 
| 392 | 
            +
                  got.xpath('license-key').each do |key|
         | 
| 393 | 
            +
                    name = key.xpath('name').text.strip
         | 
| 394 | 
            +
                    ret_h[name][:key] = key.xpath('key-data').text
         | 
| 395 | 
            +
                  end
         | 
| 396 | 
            +
                end    
         | 
| 397 | 
            +
                
         | 
| 398 | 
            +
                ret_h
         | 
| 399 | 
            +
              end
         | 
| 400 | 
            +
             | 
| 401 | 
            +
              ## ----------------------------------------------------------------  
         | 
| 402 | 
            +
              ## add a license 
         | 
| 403 | 
            +
              ##
         | 
| 404 | 
            +
              ## --- returns ---
         | 
| 405 | 
            +
              ## true - key added OK
         | 
| 406 | 
            +
              ## String - error message otherwise
         | 
| 407 | 
            +
              ##
         | 
| 408 | 
            +
              ## --- options ---
         | 
| 409 | 
            +
              ## :key => String
         | 
| 410 | 
            +
              ##    The key text
         | 
| 411 | 
            +
              ##
         | 
| 412 | 
            +
              ## :filename => String
         | 
| 413 | 
            +
              ##    Path to licence-file on server
         | 
| 414 | 
            +
              ## ----------------------------------------------------------------
         | 
| 415 | 
            +
              
         | 
| 416 | 
            +
              def license_install!( opts = {} )
         | 
| 417 | 
            +
                args = {}
         | 
| 418 | 
            +
                if opts[:key]
         | 
| 419 | 
            +
                  args[:key_data] = opts[:key]
         | 
| 420 | 
            +
                elsif opts[:filename]
         | 
| 421 | 
            +
                  args[:key_data] = File.read(opts[:filename]).strip
         | 
| 422 | 
            +
                end
         | 
| 423 | 
            +
                got = @ndev.rpc.request_license_add( args )
         | 
| 424 | 
            +
                success = got.xpath('add-success')[0]
         | 
| 425 | 
            +
                return true if success
         | 
| 426 | 
            +
                got.xpath('//message').text.strip
         | 
| 427 | 
            +
              end
         | 
| 428 | 
            +
             | 
| 429 | 
            +
              ## ----------------------------------------------------------------  
         | 
| 430 | 
            +
              ## remove a license 
         | 
| 431 | 
            +
              ##
         | 
| 432 | 
            +
              ## license_id is the String license-id or the special name :all
         | 
| 433 | 
            +
              ## ----------------------------------------------------------------
         | 
| 434 | 
            +
              
         | 
| 435 | 
            +
              def license_rm!( license_id )
         | 
| 436 | 
            +
                args = {}
         | 
| 437 | 
            +
                if license_id == :all
         | 
| 438 | 
            +
                  args[:all] = true
         | 
| 439 | 
            +
                else
         | 
| 440 | 
            +
                  args[:license_identifier] = license_id
         | 
| 441 | 
            +
                end
         | 
| 442 | 
            +
                got = @ndev.rpc.request_license_delete( args )
         | 
| 443 | 
            +
                ### @@@ need to test return cases ... for now, just return
         | 
| 444 | 
            +
                ### the 'got' XML
         | 
| 445 | 
            +
                got
         | 
| 446 | 
            +
              end
         | 
| 447 | 
            +
             | 
| 448 | 
            +
              ## ----------------------------------------------------------------  
         | 
| 449 | 
            +
              ## save licenses (plr!) to a file 
         | 
| 450 | 
            +
              ## ----------------------------------------------------------------
         | 
| 451 | 
            +
              
         | 
| 452 | 
            +
              def license_save( opts = {} )
         | 
| 453 | 
            +
                raise StandardError, "not implemented yet"
         | 
| 454 | 
            +
              end
         | 
| 455 | 
            +
              
         | 
| 456 | 
            +
            end
         | 
| 457 | 
            +
             | 
| 458 | 
            +
            ### -----------------------------------------------------------------
         | 
| 459 | 
            +
            ###                        PRIVATE METHODS
         | 
| 460 | 
            +
            ### -----------------------------------------------------------------
         | 
| 461 | 
            +
             | 
| 462 | 
            +
            class Junos::Ez::RE::Provider
         | 
| 463 | 
            +
              private
         | 
| 464 | 
            +
              
         | 
| 465 | 
            +
              def _uptime_to_h( as_xml, up_h )    
         | 
| 466 | 
            +
                up_h[:time_now] = as_xml.xpath('current-time/date-time').text.strip
         | 
| 467 | 
            +
                
         | 
| 468 | 
            +
                data = as_xml.xpath('uptime-information')[0]    
         | 
| 469 | 
            +
                up_h[:active_users] = data.xpath('active-user-count').text.to_i    
         | 
| 470 | 
            +
                up_h[:load_avg] = [
         | 
| 471 | 
            +
                  data.xpath('load-average-1').text.to_f,
         | 
| 472 | 
            +
                  data.xpath('load-average-5').text.to_f,
         | 
| 473 | 
            +
                  data.xpath('load-average-15').text.to_f,    
         | 
| 474 | 
            +
                ]
         | 
| 475 | 
            +
                up_h[:uptime] = {
         | 
| 476 | 
            +
                  :at => data.xpath('date-time').text.strip,
         | 
| 477 | 
            +
                  :ago => data.xpath('up-time').text.strip,    
         | 
| 478 | 
            +
                }
         | 
| 479 | 
            +
                
         | 
| 480 | 
            +
                data = as_xml.xpath('system-booted-time')[0]
         | 
| 481 | 
            +
                up_h[:time_boot] = { 
         | 
| 482 | 
            +
                  :at => data.xpath('date-time').text.strip,
         | 
| 483 | 
            +
                  :ago => data.xpath('time-length').text.strip
         | 
| 484 | 
            +
                }
         | 
| 485 | 
            +
                
         | 
| 486 | 
            +
                data = as_xml.xpath('protocols-started-time')[0]
         | 
| 487 | 
            +
                up_h[:protocols_started] = {
         | 
| 488 | 
            +
                  :at => data.xpath('date-time').text.strip,
         | 
| 489 | 
            +
                  :ago => data.xpath('time-length').text.strip      
         | 
| 490 | 
            +
                }
         | 
| 491 | 
            +
                
         | 
| 492 | 
            +
                data = as_xml.xpath('last-configured-time')[0]
         | 
| 493 | 
            +
                up_h[:last_config] = {
         | 
| 494 | 
            +
                  :at => data.xpath('date-time').text.strip,
         | 
| 495 | 
            +
                  :ago => data.xpath('time-length').text.strip,
         | 
| 496 | 
            +
                  :by => data.xpath('user').text.strip      
         | 
| 497 | 
            +
                }    
         | 
| 498 | 
            +
              end  
         | 
| 499 | 
            +
              
         | 
| 500 | 
            +
              def _system_memory_to_h( as_xml, as_h )
         | 
| 501 | 
            +
                
         | 
| 502 | 
            +
                summary = as_xml.xpath('system-memory-summary-information')[0]
         | 
| 503 | 
            +
                as_h[:memory_summary] = {
         | 
| 504 | 
            +
                  :total => {
         | 
| 505 | 
            +
                    :size => summary.xpath('system-memory-total').text.to_i,
         | 
| 506 | 
            +
                    :percentage => summary.xpath('system-memory-total-percent').text.to_i
         | 
| 507 | 
            +
                  },
         | 
| 508 | 
            +
                  :reserved => {
         | 
| 509 | 
            +
                    :size => summary.xpath('system-memory-reserved').text.to_i,
         | 
| 510 | 
            +
                    :percentage => summary.xpath('system-memory-reserved-percent').text.to_i      
         | 
| 511 | 
            +
                  },
         | 
| 512 | 
            +
                  :wired => {
         | 
| 513 | 
            +
                    :size => summary.xpath('system-memory-wired').text.to_i,
         | 
| 514 | 
            +
                    :percentage => summary.xpath('system-memory-wired-percent').text.to_i            
         | 
| 515 | 
            +
                  },
         | 
| 516 | 
            +
                  :active => {
         | 
| 517 | 
            +
                    :size => summary.xpath('system-memory-active').text.to_i,
         | 
| 518 | 
            +
                    :percentage => summary.xpath('system-memory-active-percent').text.to_i                  
         | 
| 519 | 
            +
                  },
         | 
| 520 | 
            +
                  :inactive => {
         | 
| 521 | 
            +
                    :size => summary.xpath('system-memory-inactive').text.to_i,
         | 
| 522 | 
            +
                    :percentage => summary.xpath('system-memory-inactive-percent').text.to_i                  
         | 
| 523 | 
            +
                  },
         | 
| 524 | 
            +
                  :cache => {
         | 
| 525 | 
            +
                    :size => summary.xpath('system-memory-cache').text.to_i,
         | 
| 526 | 
            +
                    :percentage => summary.xpath('system-memory-cache-percent').text.to_i                  
         | 
| 527 | 
            +
                  },
         | 
| 528 | 
            +
                  :free => {
         | 
| 529 | 
            +
                    :size => summary.xpath('system-memory-free').text.to_i,
         | 
| 530 | 
            +
                    :percentage => summary.xpath('system-memory-free-percent').text.to_i                  
         | 
| 531 | 
            +
                  }
         | 
| 532 | 
            +
                }
         | 
| 533 | 
            +
                
         | 
| 534 | 
            +
                # create an Array of process information.  The process-names are 
         | 
| 535 | 
            +
                # not guaranteed to be unique, so do this as an Array vs. Hash
         | 
| 536 | 
            +
                
         | 
| 537 | 
            +
                as_h[:procs] = []
         | 
| 538 | 
            +
                as_xml.xpath('pmap-terse-information/pmap-terse-summary').each do |proc|
         | 
| 539 | 
            +
                  proc_h = {}
         | 
| 540 | 
            +
                  as_h[:procs] << proc_h
         | 
| 541 | 
            +
                  
         | 
| 542 | 
            +
                  proc_h[:name] = proc.xpath('map-name | process-name').text.strip 
         | 
| 543 | 
            +
                  proc_h[:pid] = proc.xpath('pid').text.to_i
         | 
| 544 | 
            +
                  proc_h[:size] = proc.xpath('size').text.to_i
         | 
| 545 | 
            +
                  proc_h[:size_pct] = proc.xpath('size-percent').text.to_f
         | 
| 546 | 
            +
                  proc_h[:resident] = proc.xpath('resident').text.to_i
         | 
| 547 | 
            +
                  proc_h[:resident_pct] = proc.xpath('resident-percent').text.to_f
         | 
| 548 | 
            +
                end 
         | 
| 549 | 
            +
                
         | 
| 550 | 
            +
              end
         | 
| 551 | 
            +
              
         | 
| 552 | 
            +
              def _alarm_info_to_h( alarm, alarm_h )
         | 
| 553 | 
            +
                alarm_h[:at] = alarm.xpath('alarm-time').text.strip
         | 
| 554 | 
            +
                alarm_h[:class] = alarm.xpath('alarm-class').text.strip
         | 
| 555 | 
            +
                alarm_h[:description] = alarm.xpath('alarm-description').text.strip
         | 
| 556 | 
            +
                alarm_h[:type] = alarm.xpath('alarm-type').text.strip
         | 
| 557 | 
            +
              end
         | 
| 558 | 
            +
            end
         |