boris 1.0.0.beta.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/CHANGELOG.md +11 -0
  2. data/README.md +114 -32
  3. data/Rakefile +19 -0
  4. data/lib/boris.rb +0 -13
  5. data/lib/boris/connectors.rb +25 -7
  6. data/lib/boris/connectors/snmp.rb +24 -4
  7. data/lib/boris/connectors/ssh.rb +32 -6
  8. data/lib/boris/connectors/wmi.rb +109 -54
  9. data/lib/boris/errors.rb +1 -1
  10. data/lib/boris/helpers/array.rb +62 -62
  11. data/lib/boris/helpers/constants.rb +22 -19
  12. data/lib/boris/helpers/hash.rb +7 -7
  13. data/lib/boris/helpers/network.rb +68 -0
  14. data/lib/boris/helpers/scrubber.rb +53 -51
  15. data/lib/boris/helpers/string.rb +148 -26
  16. data/lib/boris/lumberjack.rb +74 -47
  17. data/lib/boris/options.rb +28 -16
  18. data/lib/boris/profiler.rb +19 -0
  19. data/lib/boris/profilers/linux/redhat.rb +74 -0
  20. data/lib/boris/{profiles → profilers}/linux_core.rb +13 -4
  21. data/lib/boris/{profiles → profilers}/unix/solaris.rb +25 -15
  22. data/lib/boris/{profiles → profilers}/unix_core.rb +90 -85
  23. data/lib/boris/profilers/windows/windows2003.rb +11 -0
  24. data/lib/boris/profilers/windows/windows2008.rb +26 -0
  25. data/lib/boris/profilers/windows/windows2012.rb +11 -0
  26. data/lib/boris/{profiles → profilers}/windows_core.rb +36 -14
  27. data/lib/boris/structure.rb +173 -167
  28. data/lib/boris/target.rb +110 -168
  29. data/lib/boris/version.rb +3 -0
  30. metadata +32 -115
  31. data/boris.gemspec +0 -28
  32. data/doc/Array.html +0 -437
  33. data/doc/Boris.html +0 -230
  34. data/doc/Boris/ConnectionAlreadyActive.html +0 -123
  35. data/doc/Boris/ConnectionFailed.html +0 -127
  36. data/doc/Boris/Connector.html +0 -794
  37. data/doc/Boris/InvalidCredentials.html +0 -131
  38. data/doc/Boris/InvalidOption.html +0 -123
  39. data/doc/Boris/InvalidTargetName.html +0 -123
  40. data/doc/Boris/Lumberjack.html +0 -466
  41. data/doc/Boris/MissingCredentials.html +0 -123
  42. data/doc/Boris/NoActiveConnection.html +0 -123
  43. data/doc/Boris/NoProfileDetected.html +0 -123
  44. data/doc/Boris/Options.html +0 -783
  45. data/doc/Boris/Profiles.html +0 -117
  46. data/doc/Boris/Profiles/Linux.html +0 -1151
  47. data/doc/Boris/Profiles/RedHat.html +0 -875
  48. data/doc/Boris/Profiles/Solaris.html +0 -1230
  49. data/doc/Boris/Profiles/Structure.html +0 -2050
  50. data/doc/Boris/Profiles/UNIX.html +0 -893
  51. data/doc/Boris/Profiles/Windows.html +0 -1846
  52. data/doc/Boris/Profiles/Windows/Windows2003.html +0 -304
  53. data/doc/Boris/Profiles/Windows/Windows2008.html +0 -379
  54. data/doc/Boris/Profiles/Windows/Windows2012.html +0 -304
  55. data/doc/Boris/SNMPConnector.html +0 -512
  56. data/doc/Boris/SSHConnector.html +0 -633
  57. data/doc/Boris/Target.html +0 -2002
  58. data/doc/Boris/WMIConnector.html +0 -1134
  59. data/doc/BorisLogger.html +0 -217
  60. data/doc/Hash.html +0 -195
  61. data/doc/String.html +0 -1246
  62. data/doc/_index.html +0 -420
  63. data/doc/class_list.html +0 -53
  64. data/doc/css/common.css +0 -1
  65. data/doc/css/full_list.css +0 -57
  66. data/doc/css/style.css +0 -328
  67. data/doc/file.README.html +0 -183
  68. data/doc/file_list.html +0 -55
  69. data/doc/frames.html +0 -28
  70. data/doc/index.html +0 -183
  71. data/doc/js/app.js +0 -214
  72. data/doc/js/full_list.js +0 -173
  73. data/doc/js/jquery.js +0 -4
  74. data/doc/method_list.html +0 -1468
  75. data/doc/top-level-namespace.html +0 -126
  76. data/lib/boris/profiles/linux/redhat.rb +0 -77
  77. data/lib/boris/profiles/windows/windows2003.rb +0 -15
  78. data/lib/boris/profiles/windows/windows2008.rb +0 -23
  79. data/lib/boris/profiles/windows/windows2012.rb +0 -15
  80. data/test/connector_tests/test_snmp.rb +0 -35
  81. data/test/connector_tests/test_ssh.rb +0 -51
  82. data/test/connector_tests/test_wmi.rb +0 -129
  83. data/test/helper_tests/test_array.rb +0 -25
  84. data/test/helper_tests/test_hash.rb +0 -10
  85. data/test/helper_tests/test_string.rb +0 -136
  86. data/test/profile_tests/test_core_skeleton +0 -107
  87. data/test/profile_tests/test_linux_core.rb +0 -331
  88. data/test/profile_tests/test_redhat.rb +0 -134
  89. data/test/profile_tests/test_solaris.rb +0 -523
  90. data/test/profile_tests/test_unix_core.rb +0 -117
  91. data/test/profile_tests/test_windows.rb +0 -536
  92. data/test/setup_tests.rb +0 -14
  93. data/test/test_all.rb +0 -8
  94. data/test/test_options.rb +0 -44
  95. data/test/test_structure.rb +0 -136
  96. data/test/test_target.rb +0 -146
@@ -0,0 +1,11 @@
1
+ # 1.0.1
2
+ * Renamed Profiles to Profilers
3
+ * Moved networking helper methods to newly created Network module
4
+ * Separated Structure and Profilers
5
+ * Profilers are now separate classes for easier subclassing
6
+ * Simplified logging
7
+
8
+ # 1.0.0.beta1
9
+ * Initial public release
10
+
11
+ # 1.0.0* was yanked
data/README.md CHANGED
@@ -1,17 +1,18 @@
1
1
  # Boris
2
- ## A networked-device scanning solution
2
+ ## Networked-device scanning library written in Ruby
3
3
 
4
4
  * Code: http://github.com/alkalinecoffee/boris
5
- * Documentation: http://rdoc.info/github/alkalinecoffee/boris/master/frames
5
+ * Developer's blog: http://www.sharkwavemedia.com
6
+ * Documentation: http://rdoc.info/github/alkalinecoffee/boris/frames
6
7
  * Issues: https://github.com/alkalinecoffee/boris/issues
7
8
 
8
9
  ## Introduction
9
10
  Boris is a library that facilitates the communication between you and various networked devices over SNMP, SSH and WMI, pulling a large amount of configuration items including installed software, network settings, serial numbers, user accounts, disk utilization, and more.
10
11
 
11
- Out of the box, Boris has server support for Windows, Red Hat, and Solaris (with other platforms available with future plugins), with a focus on returning precisely formatted data, no matter which platforms your organization may have deployed. Through the use of profiles, Boris can easily be extended by the developer to include other platforms. Highly suitable for small and large environments alike looking to pull configuration data from various platforms.
12
+ Out of the box, Boris has server support for Red Hat, Solaris,and Windows (with other platforms available with future plugins), with a focus on returning precisely formatted data, no matter which platforms your organization may have deployed. Through the use of profilers, Boris can easily be extended by the developer to include other platforms. Highly suitable for small and large environments alike looking to pull configuration data from various platforms.
12
13
 
13
14
  ## Features
14
- * Out of the box, pulls information from RedHat Linux, Solaris 10, and Windows servers
15
+ * Currently, pulls information from Red Hat Linux, Solaris, and Windows servers (support for OS X, F5 BIG-IP, and Cisco IOS devices in the works)
15
16
  * Utilizes SNMP, SSH, and WMI communication technologies
16
17
  * Expandable to include other networked devices, such as switches, load balancers, and other operating systems
17
18
 
@@ -24,43 +25,109 @@ Let's pull some information from a RedHat Enterprise Linux server on our network
24
25
  ```ruby
25
26
  require 'boris'
26
27
 
27
- target = Boris::Target.new('redhatserver01.mydomain.com')
28
+ # Boris has different levels of logging. We can optionally set our logging level, which will apply
29
+ # to all Targets created during this session. If not set, the log level defaults to :fatal.
30
+ Boris.log_level = :debug
31
+
32
+ hostname = 'redhatserver01.mydomain.com'
28
33
 
29
34
  # let's use a helper to suggest how we should connect to it (which is useful if we're not sure what
30
35
  # kind of device this is)
31
- puts target.suggested_connection_method
36
+ puts Boris::Network.suggested_connection_method(hostname)
32
37
 
33
38
  # you can also add the logic to make the decision yourself by checking if certain TCP ports are responsive
34
- puts target.tcp_port_responding?(22)
39
+ puts Boris::Network.tcp_port_responding?(hostname, 22)
40
+
41
+ # create our target
42
+ target = Boris::Target.new(hostname)
35
43
 
36
44
  # add credentials to try against this target
37
- target.options.add_credential(:user=>'joe', :password=>'mypassword', :connection_types=>[:ssh])
45
+ target.options.add_credential(:user=>'myusername', :password=>'mypassword', :connection_types=>[:ssh])
46
+
47
+ # if this is a host using SSH, we can also pass in Net::SSH options (such as a private key for authentication).
48
+ # SSH options passed to Boris will automatically be pushed to Net:SSH.
49
+ target.options[:ssh_options] = {:keys=>['/path/to/my/private/key']}
38
50
 
39
51
  # attempt to connect to this target using the credentials we supplied above
40
52
  target.connect
41
53
 
42
54
  if target.connected?
43
- # detect which profile to load up (is this target running windows? solaris? or what?). if we can't
44
- # detect a suitable profile, this will throw an error
45
- target.detect_profile
55
+ # we can try to detect which profiler to load up (is this target running windows? solaris? or
56
+ # what?). if we can't detect a suitable profiler, this will throw an error.
57
+ target.detect_profiler
58
+
59
+ puts target.profiler.class
60
+
61
+ # we can call individual methods to grab specific information we may be interested in
62
+ target.get(:hardware)
63
+
64
+ # or maybe get some network interface info
65
+ puts target.get(:network_interfaces)
66
+
67
+ # retrieved items can be referenced two ways:
68
+ puts target[:network_interfaces].inspect
69
+ puts target.profiler.network_interfaces.inspect
70
+
71
+ # we can also call #retrieve_all to grab everything we can from this target (file systems, hardware,
72
+ # installed applications, etc.)
73
+ target.retrieve_all
74
+
75
+ # if there is more information we want to collect but is not collected by default, we can specify
76
+ # our own commands to run against the target via two methods: #get_values returns an Array (each
77
+ # line is an element of the array), or #get_value, which returns a String (the first line returned
78
+ # from the command)
79
+ puts target.connector.values_at('cat /etc/redhat-release')
80
+ puts target.connector.value_at('uname -a')
81
+
82
+ # NOTE: if this were a Windows server, you would send WMI queries instead of shell commands, ie:
83
+ #
84
+ # target.connector.values_at('SELECT * FROM Win32_ComputerSystem')
85
+ #
86
+
87
+ # finally, we can package up all of the data into json format for portability (the true argument
88
+ # tells the #to_json method to output the json with tabbed formatting)
89
+ puts target.to_json(:pretty_print)
90
+
91
+ target.disconnect
92
+ end
93
+ ```
46
94
 
47
- puts target.target_profile
95
+ ## Extending Boris
96
+ You can also run your own commands to grab information off of systems. For example, on a Linux device, to run your own script that is already on the target and retrieve its output:
48
97
 
49
- # we can call individual methods to grab specific information we may be interested in (or call
50
- # #retrieve_all to grab everything we can)
51
- target.get_hardware
98
+ ```ruby
99
+ # use the target's connector to grab multiple values. #values_at will return an array with each line
100
+ # returned as an item in the returned array.
101
+ multiple_lines_of_data = target.connector.values_at('/path/to/some/script')
52
102
 
53
- puts target.hardware.inspect
103
+ # to grab only the first line from a script or file, you can use #value_at:
104
+ single_line_of_data = target.connector.value_at('/path/to/some/script')
105
+ ```
54
106
 
55
- # finally, we can package up all of the data into json format for portability
56
- puts target.to_json
57
- end
107
+ Running commands in this fashion utilizes the #exec function from Net::SSH.
58
108
 
59
- target.disconnect
109
+ For a Windows host, which uses WMI vice SSH, you can send WMI queries or registry keys to the connector to get information:
110
+
111
+ ```ruby
112
+ # this will pull rows from a class in the standard root\CIMV2 namespace, returning an array of hashes
113
+ multiple_rows_of_data = target.connector.values_at('SELECT * FROM Win32_NetworkAdapter')
114
+
115
+ # this will pull rows from a class in the lower-level root\WMI namespace (note the second argument we're passing to #values_at):
116
+ multiple_rows_of_data = target.connector.values_at('SELECT * FROM MSNdis_EnumerateAdapter', :root_wmi)
117
+
118
+ # you can also poll for registry keys under HKEY_LOCAL_MACHINE by providing a base key path, which returns an array of keys:
119
+ registry_keys = target.connector.registry_subkeys_at('SOFTWARE\Microsoft\Windows')
120
+
121
+ # and then grab values found at some key via #registry_values_at, which returns value/data elements in a Hash:
122
+ registry_values = target.connector.registry_values_at('SOFTWARE\Microsoft\Windows\CurrentVersion')
60
123
  ```
61
124
 
125
+ **Coming soon--a write-up for SNMP devices**
126
+
127
+ Boris also comes with the ability to add your own complete modules for using the framework by writing your own data collection algorithms. This will also be written up in the near future.
128
+
62
129
  ## Data
63
- Through a number of queries and algorithms, Boris effeciently polls devices on the network for information including, but not limited to, network configuration, hardware capabilities, installed software and services, applied hotfixes/patches, and more.
130
+ Through a number of queries and algorithms, Boris efficiently polls devices on the network for information including, but not limited to, network configuration, hardware capabilities, installed software and services, applied hotfixes/patches, and more.
64
131
 
65
132
  **Available methods for use on most platforms include:**
66
133
 
@@ -75,20 +142,35 @@ Through a number of queries and algorithms, Boris effeciently polls devices on t
75
142
  * **network interfaces** - ethernet and fibre channel interfaces, including IPs, MAC addresses, connection status
76
143
  * **operating system** - name, version, kernel, date installed
77
144
 
78
- See {Boris::Profiles::Structure} for more details on the data structure.
145
+ See {http://www.rubydoc.info/github/alkalinecoffee/boris/Boris/Profilers/Structure Boris::Profilers::Structure} for more details on the data structure.
79
146
 
80
147
  Because the commands that might work correctly on one type of platform most likely won't work on another, Boris handles this by the use of...
81
148
 
82
- ## Profiles
83
- Profiles contain the instructions that allow us to run commands against our target and then parse and make sense of the data. Boris comes with the capability to communicate with targets over SNMP, SSH, or WMI. Each profile is written to use one of these methods of communication (internally called 'connectors'), which serve as a vehicle for running commands against a server. Boris comes with a few profiles built-in for some popular platforms, but can be easily extended to include other devices.
149
+ ## Profilers
150
+ Profilers contain the instructions that allow us to run commands against our target and then parse and make sense of the data. Boris comes with the capability to communicate with targets over SNMP, SSH, or WMI. Each profiler is written to use one of these methods of communication (internally called 'connectors'), which serve as a vehicle for running commands against a server. Boris comes with a few profilers built-in for some popular platforms, but can be easily extended to include other devices.
151
+
152
+ **Available profilers:**
153
+
154
+ * **Linux Core**
155
+ * Red Hat Linux
156
+ * **UNIX Core**
157
+ * Oracle Solaris
158
+ * **Windows Core**
159
+ * Windows 2003 Server
160
+ * Windows 2008 Server
161
+ * Windows 2012 Server
162
+
163
+ ## User Account Requirements
164
+ While Boris does its best to gather data from devices without any special privileges, sometimes it just can't be helped. One example of this is the RedHat profiler, which requires `sudo` access for the `dmidecode` command, as there isn't a well known, reliable way to grab this info without `dmidecode`. If Boris attempts to run a command that requires special access and is denied, it will throw a message to the logger and move on.
165
+
166
+ **Here is a list of known scan account requirements for each platform:**
84
167
 
85
- ## Requirements
86
- * Ruby 1.9.3 (only tested on MRI)
87
- * Net/SSH gem
88
- * NetAddr gem
89
- * SNMP gem
90
- * Mocha (for tests only)
91
- * Shoulda (for tests only)
168
+ * **Linux (any flavor)**
169
+ * User must have `sudo` for `dmidecode`
170
+ * **Solaris**
171
+ * User must have `sudo` for `fcinfo`
172
+ * **Windows**
173
+ * User must be a member of local Administrator group (looking into what other groups provide required access)
92
174
 
93
- ## LICENSE
175
+ ## License
94
176
  This software is provided under the MIT license. See the LICENSE.md file.
@@ -0,0 +1,19 @@
1
+ require 'rake'
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
4
+
5
+ require 'boris/version'
6
+
7
+ task :build do
8
+ system 'gem build boris.gemspec'
9
+ end
10
+
11
+ task :install => :build do
12
+ system "gem install boris-#{Boris::VERSION}.gem"
13
+ end
14
+
15
+ task :release => :build do
16
+ system "git tag -a v#{Boris::VERSION} -m 'Pushed #{Boris::VERSION}'"
17
+ system 'git push --tags'
18
+ system "gem push boris-#{Boris::VERSION}.gem"
19
+ end
@@ -14,17 +14,4 @@ require 'thread'
14
14
  require 'win32ole' if PLATFORM == :win32
15
15
 
16
16
  require 'boris/lumberjack'
17
-
18
- require 'boris/errors'
19
- require 'boris/options'
20
17
  require 'boris/target'
21
-
22
- require 'boris/helpers/array'
23
- require 'boris/helpers/constants'
24
- require 'boris/helpers/hash'
25
- require 'boris/helpers/scrubber'
26
- require 'boris/helpers/string'
27
-
28
- module Boris
29
-
30
- end
@@ -1,4 +1,10 @@
1
1
  module Boris
2
+ # The Connector class is the parent of the main Connector types that Boris
3
+ # utilizes (WMI, SNMP, and SSH). It's primary purpose is to create the general
4
+ # structure of a connector and offer some debugging messages for different
5
+ # actions. Typically, Connector objects would not be created by user code.
6
+ # Instead, your own connectors would be a subclass of Connector with calls
7
+ # to super as appropriate.
2
8
  class Connector
3
9
  include Lumberjack
4
10
 
@@ -7,31 +13,43 @@ module Boris
7
13
  attr_reader :options
8
14
  attr_reader :reconnectable
9
15
 
10
- def initialize(host, cred, options, logger=nil)
11
- debug 'creating connection object'
12
-
16
+ def initialize(host, cred={})
17
+ @logger = Boris.logger
18
+
13
19
  @host = host
14
20
  @user = cred[:user]
15
21
  @password = cred[:password]
16
22
  @connected = false
17
23
  @reconnectable = true
18
-
19
- @logger = logger
24
+ debug 'creating connection object'
20
25
  end
21
26
 
27
+ # Convience method for retrieveing the connection status for this Connector.
28
+ #
29
+ # connector.connected? #=> true
30
+ #
31
+ # @return [Boolean] true if connected
22
32
  def connected?
23
33
  @connected
24
34
  end
25
35
 
36
+ # Disconnect from the host.
26
37
  def disconnect
27
- debug 'closing connection to host'
38
+ info 'closing connection to host'
28
39
  @connected = false
29
40
  end
30
41
 
42
+ # Establish our connection.
31
43
  def establish_connection
32
44
  debug 'attempting connection'
33
45
  end
34
46
 
47
+ # Only to be called from a child class, as this method only performs some simple
48
+ # checks for errors and provides debugging messages. Not intended to be directly
49
+ # called from user code.
50
+ #
51
+ # @param [String] request the command we wish to execute over this connection
52
+ # @param [Integer] limit the maximum number of results we wish to return
35
53
  def values_at(request, limit)
36
54
  if !limit.kind_of?(Integer)
37
55
  raise ArgumentError, "non-integer limit specified (#{limit.inspect})"
@@ -41,7 +59,7 @@ module Boris
41
59
 
42
60
  amount = limit == 1 ? 'single value' : 'multiple values'
43
61
 
44
- debug "issuing request for #{amount} (#{request.inspect})"
62
+ debug "issuing request for #{amount} (#{request})"
45
63
  end
46
64
  end
47
65
  end
@@ -2,20 +2,32 @@ require 'boris/connectors'
2
2
 
3
3
  module Boris
4
4
  class SNMPConnector < Connector
5
- def initialize(host, cred, options, logger=nil)
6
- super(host, cred, options, logger)
5
+
6
+ # Create an instance of SNMPConnector by passing in a mandatory hostname or IP address,
7
+ # credential to try, and optional Hash of {Boris::Options options}. Under the hood, this
8
+ # class uses the SNMP library.
9
+ #
10
+ # @param [String] host hostname or IP address
11
+ # @param [Hash] cred credential we wish to use
12
+ # @param [Hash] options an optional list of options. See {Boris::Options} for a list of all
13
+ # possible options. The relevant option set here would be :snmp_options.
14
+ def initialize(host, cred, options={})
15
+ super(host, cred)
7
16
  @snmp_options = options[:snmp_options].merge(:host=>@host, :version=>:SNMPv1, :community=>@user)
8
17
 
9
18
  #snmp connections are always reconnectable
10
19
  @reconnectable = true
11
20
  end
12
21
 
22
+ # Disconnect from the host.
13
23
  def disconnect
14
24
  super
15
25
  @transport = nil
16
26
  debug 'connections closed'
17
27
  end
18
28
 
29
+ # Establish our connection.
30
+ # @return [SNMPConnector] instance of SNMPConnector
19
31
  def establish_connection
20
32
  super
21
33
 
@@ -30,13 +42,21 @@ module Boris
30
42
  warn "connection failed (#{error.message})"
31
43
  end
32
44
 
33
- return self
45
+ self
34
46
  end
35
47
 
48
+ # Return a single value from our request.
49
+ # @param [String] request the command we wish to execute over this connection
50
+ # @return [String] the first row/line returned by the host
36
51
  def value_at(request)
37
52
  values_at(request, 1)[0]
38
53
  end
39
54
 
55
+ # Return multiple values from our request, up to the limit specified (or no
56
+ # limit if no limit parameter is specified.
57
+ # @param [String] request the command we wish to execute over this connection
58
+ # @param [Integer] limit the optional maximum number of results we wish to return
59
+ # @return [Array] an array of rows returned by the query
40
60
  def values_at(request, limit=nil)
41
61
  super(request, limit)
42
62
 
@@ -46,7 +66,7 @@ module Boris
46
66
  row.each {|item| return_data << {:name=>item.name.to_s, :value=>item.value}}
47
67
  end
48
68
 
49
- info "#{return_data.size} row(s) returned"
69
+ debug "#{return_data.size} row(s) returned"
50
70
 
51
71
  limit = return_data.size if limit.nil?
52
72
 
@@ -2,22 +2,36 @@ require 'boris/connectors'
2
2
 
3
3
  module Boris
4
4
  class SSHConnector < Connector
5
- def initialize(host, cred, options, logger=nil)
5
+
6
+ # Create an instance of SSHConnector by passing in a mandatory hostname or IP address,
7
+ # credential to try, and optional Hash of {Boris::Options options}. Under the hood, this
8
+ # class uses the Net/SSH library.
9
+ #
10
+ # @param [String] host hostname or IP address
11
+ # @param [Hash] cred credential we wish to use
12
+ # @param [Hash] options an optional list of options. See {Boris::Options} for a list of all
13
+ # possible options. The relevant option set here would be :ssh_options.
14
+ def initialize(host, cred, options={})
6
15
  @ssh_options = options[:ssh_options]
7
16
  @ssh_options[:password] = @password if @password
8
17
 
9
- invalid_ssh_options = @ssh_options.keys - Net::SSH::VALID_OPTIONS
10
- raise ArgumentError, "invalid ssh option(s): #{invalid_ssh_options.join(', ')}" if invalid_ssh_options.any?
18
+ if @ssh_options
19
+ invalid_ssh_options = @ssh_options.keys - Net::SSH::VALID_OPTIONS
20
+ raise ArgumentError, "invalid ssh option(s): #{invalid_ssh_options.join(', ')}" if invalid_ssh_options.any?
21
+ end
11
22
 
12
- super(host, cred, options, logger)
23
+ super(host, cred)
13
24
  end
14
25
 
26
+ # Disconnect from the host.
15
27
  def disconnect
16
28
  super
17
29
  @transport = nil
18
30
  debug 'connections closed'
19
31
  end
20
32
 
33
+ # Establish our connection.
34
+ # @return [SSHConnector] instance of SSHConnector
21
35
  def establish_connection
22
36
  super
23
37
 
@@ -42,13 +56,25 @@ module Boris
42
56
  info 'connection does not seem to be available (so we will not retry)'
43
57
  end unless @transport
44
58
 
45
- return self
59
+ self
46
60
  end
47
61
 
62
+ # Return a single value from our request.
63
+ # @param [String] request the command we wish to execute over this connection
64
+ # @param [Boolean] request_pty if true, we should request psuedo-terminal (PTY).
65
+ # This is necessary if we are calling a command that uses elevated privileges (sudo).
66
+ # @return [String] the first row/line returned by the host
48
67
  def value_at(request, request_pty=false)
49
68
  values_at(request, request_pty, 1)[0]
50
69
  end
51
70
 
71
+ # Return multiple values from our request, up to the limit specified (or no
72
+ # limit if no limit parameter is specified.
73
+ # @param [String] request the command we wish to execute over this connection
74
+ # @param [Boolean] request_pty if true, we should request psuedo-terminal (PTY).
75
+ # This is necessary if we are calling a command that uses elevated privileges (sudo).
76
+ # @param [Integer] limit the optional maximum number of results we wish to return
77
+ # @return [Array] an array of rows returned by the command
52
78
  def values_at(request, request_pty=false, limit=nil)
53
79
  super(request, limit)
54
80
 
@@ -100,7 +126,7 @@ module Boris
100
126
 
101
127
  return_data = return_data.join.split(/\n/)
102
128
 
103
- info "#{return_data.size} row(s) returned"
129
+ debug "#{return_data.size} row(s) returned"
104
130
 
105
131
  limit = return_data.size if limit.nil?
106
132