synaccess_connect 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +14 -8
- data/lib/synaccess_connect.rb +3 -32
- data/lib/synaccess_connect/net_booter/http.rb +8 -0
- data/lib/synaccess_connect/net_booter/http/http_connection.rb +111 -106
- data/lib/synaccess_connect/net_booter/http/rev_a.rb +25 -17
- data/lib/synaccess_connect/net_booter/http/rev_b.rb +24 -14
- data/lib/synaccess_connect/version.rb +3 -0
- metadata +15 -16
- data/lib/synaccess_connect/net_booter/telnet/rev_a.rb +0 -23
- data/lib/synaccess_connect/net_booter/telnet/rev_b.rb +0 -17
- data/lib/synaccess_connect/net_booter/telnet/telnet_connection.rb +0 -119
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZmIyY2NiZjNjYjU0OGJkN2ZiYzQwOTMzODQwNWFjODczN2I4Zjc0Yw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ODYwYzRjM2E2ODdhNjRlOWM2OGU4MWE1MTFkYjBhMmYwMWVhMDVkMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NTlmZWJhOWM3ZDJmMmY0NDRiZjM3YTgwNWQ4NmZmMmZjYTlkNzcwODM0NjY4
|
10
|
+
OWM0MDY2ZjIxNjM0MzYyZGQ1MDExNGVhZjNmMDk5MGJhNzZlNDEwNDZlMGQz
|
11
|
+
MWE3YTI3YmY2Y2Q1MTRlMzU4OTA5YzczMzNhYjMzNDhlOWQ1MGU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTBjZjdiODU0NDU0MWY1OGEwYzUyYmY3M2JlYWZhNTQ4N2M2YmRkMzc5ZTZk
|
14
|
+
ZDJiNTM4YWI4NjIyMTliNDMwN2Q2NGE1NTE3ZGJmMjA1MTcyNTMzMmEwZTcw
|
15
|
+
NGFjYzRmMzllOTg3NzY3NDQyYTMzN2FjMDQ4YjMxY2ZjN2Q4MGE=
|
data/README.md
CHANGED
@@ -12,19 +12,25 @@ Communication wrappers for Synaccess netBooter power relays.
|
|
12
12
|
Http
|
13
13
|
RevA
|
14
14
|
RevB
|
15
|
-
Telnet
|
16
|
-
RevA
|
17
|
-
RevB
|
18
15
|
```
|
19
16
|
|
20
|
-
|
17
|
+
The Telnet interface was removed in version 0.3.0 because it was unreliable. You
|
18
|
+
should switch to using the Http interface.
|
21
19
|
|
22
|
-
|
20
|
+
## Usage
|
23
21
|
|
24
|
-
|
22
|
+
* Add `gem "synaccess_connect", "~> 0.3.0" to your Gemfile.
|
25
23
|
|
26
|
-
|
27
|
-
|
24
|
+
## Example
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
connection = NetBooter::Http::RevA.new('XXX.XXX.XXX.XXX', username: "admin", password: "admin")
|
28
|
+
connection.status(1)
|
29
|
+
=> true
|
30
|
+
connection.toggle(false, 1)
|
31
|
+
connection.status(1)
|
32
|
+
=> false
|
33
|
+
```
|
28
34
|
|
29
35
|
## Interface
|
30
36
|
|
data/lib/synaccess_connect.rb
CHANGED
@@ -1,34 +1,5 @@
|
|
1
|
-
module NetBooter
|
2
|
-
module Telnet
|
3
|
-
end
|
4
|
-
module Http
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
1
|
require 'synaccess_connect/net_booter/error'
|
9
|
-
require 'synaccess_connect/net_booter/
|
10
|
-
require 'synaccess_connect/net_booter/telnet/rev_a'
|
11
|
-
require 'synaccess_connect/net_booter/telnet/rev_b'
|
12
|
-
|
13
|
-
require 'synaccess_connect/net_booter/http/http_connection'
|
14
|
-
require 'synaccess_connect/net_booter/http/rev_a'
|
15
|
-
require 'synaccess_connect/net_booter/http/rev_b'
|
16
|
-
|
2
|
+
require 'synaccess_connect/net_booter/http'
|
17
3
|
|
18
|
-
|
19
|
-
|
20
|
-
# module SynaccessConnect
|
21
|
-
# class Railtie < Rails::Railtie
|
22
|
-
# # initializer "carrierwave.setup_paths" do
|
23
|
-
# # CarrierWave.root = Rails.root.join(Rails.public_path).to_s
|
24
|
-
# # CarrierWave.base_path = ENV['RAILS_RELATIVE_URL_ROOT']
|
25
|
-
# # end
|
26
|
-
|
27
|
-
# # initializer "carrierwave.active_record" do
|
28
|
-
# # ActiveSupport.on_load :active_record do
|
29
|
-
# # require 'carrierwave/orm/activerecord'
|
30
|
-
# # end
|
31
|
-
# # end
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
# end
|
4
|
+
module NetBooter
|
5
|
+
end
|
@@ -1,128 +1,133 @@
|
|
1
|
-
require
|
1
|
+
require 'net/http'
|
2
2
|
require 'nokogiri'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
@options = {
|
8
|
-
:port => 80
|
9
|
-
}.merge(options)
|
10
|
-
end
|
4
|
+
module NetBooter
|
5
|
+
|
6
|
+
class HttpConnection
|
11
7
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
#
|
18
|
-
# Arguments:
|
19
|
-
# +outlet+ Outlet number you want to check (1-based)
|
20
|
-
#
|
21
|
-
# Returns:
|
22
|
-
# boolean - on/off status of the outlet
|
23
|
-
def status(outlet = 1)
|
24
|
-
statuses.fetch outlet do
|
25
|
-
raise NetBooter::Error.new('Error communicating with relay')
|
8
|
+
def initialize(host, options = {})
|
9
|
+
@host = host
|
10
|
+
@options = {
|
11
|
+
:port => 80
|
12
|
+
}.merge(options)
|
26
13
|
end
|
27
|
-
end
|
28
14
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
15
|
+
# Get the status of an outlet
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
# >> netbooter.status(2)
|
19
|
+
# => false
|
20
|
+
#
|
21
|
+
# Arguments:
|
22
|
+
# +outlet+ Outlet number you want to check (1-based)
|
23
|
+
#
|
24
|
+
# Returns:
|
25
|
+
# boolean - on/off status of the outlet
|
26
|
+
def status(outlet = 1)
|
27
|
+
statuses.fetch outlet do
|
28
|
+
raise NetBooter::Error.new('Error communicating with relay')
|
29
|
+
end
|
30
|
+
end
|
42
31
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
32
|
+
# Turn on the specified outlet
|
33
|
+
# Example:
|
34
|
+
# >> netbooter.toggle_on(2)
|
35
|
+
# => true
|
36
|
+
#
|
37
|
+
# Arguments:
|
38
|
+
# +outlet+ Outlet you want to turn on (1-based)
|
39
|
+
#
|
40
|
+
# Returns:
|
41
|
+
# boolean - The new status of the outlet (should be true)
|
42
|
+
def toggle_on(outlet = 1)
|
43
|
+
toggle(outlet, true)
|
44
|
+
end
|
56
45
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
current_status = status(outlet)
|
71
|
-
toggle_relay(outlet) if current_status != status
|
72
|
-
status
|
73
|
-
end
|
46
|
+
# Turn off the specified outlet
|
47
|
+
# Example:
|
48
|
+
# >> netbooter.toggle_off(2)
|
49
|
+
# => true
|
50
|
+
#
|
51
|
+
# Arguments:
|
52
|
+
# +outlet+ Outlet you want to turn off (1-based)
|
53
|
+
#
|
54
|
+
# Returns:
|
55
|
+
# boolean - The new status of the outlet (should be false)
|
56
|
+
def toggle_off(outlet = 1)
|
57
|
+
toggle(outlet, false)
|
58
|
+
end
|
74
59
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
60
|
+
# Toggle the status of an outlet
|
61
|
+
#
|
62
|
+
# Example:
|
63
|
+
# >> netbooter.toggle(1, false)
|
64
|
+
# => false
|
65
|
+
#
|
66
|
+
# Arguments:
|
67
|
+
# +outlet+ The outlet you want to toggle
|
68
|
+
# +status+ Boolean. true to turn on, false to turn off
|
69
|
+
#
|
70
|
+
# Returns:
|
71
|
+
# boolean - The new status of the outlet
|
72
|
+
def toggle(outlet, status)
|
73
|
+
current_status = status(outlet)
|
74
|
+
toggle_relay(outlet) if current_status != status
|
75
|
+
status
|
76
|
+
end
|
89
77
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
78
|
+
# Get the status of all outlets on the device. Needs to be defined
|
79
|
+
# in a subclass.
|
80
|
+
#
|
81
|
+
# Example:
|
82
|
+
# >> netbooter.statuses
|
83
|
+
# => { 1 => true, 2 => false }
|
84
|
+
#
|
85
|
+
# Arguments: none
|
86
|
+
#
|
87
|
+
# Returns:
|
88
|
+
# A hash containing the outlet numbers and their respective status
|
89
|
+
def statuses
|
90
|
+
raise NotImplementedError.new
|
91
|
+
end
|
95
92
|
|
96
|
-
|
93
|
+
# The method that contains the network command the relay. Needs to be defined
|
94
|
+
# in a subclass.
|
95
|
+
def toggle_relay(outlet)
|
96
|
+
raise NotImplementedError.new('Must implement toggle_relay in subclass')
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
97
100
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
# Make an http request and return the result.
|
102
|
+
def get_request(path)
|
103
|
+
resp = nil
|
104
|
+
begin
|
105
|
+
Timeout::timeout(5) do
|
106
|
+
resp = do_http_request(path)
|
107
|
+
end
|
108
|
+
rescue => e
|
109
|
+
raise NetBooter::Error.new("Error connecting to relay: #{e.message}")
|
104
110
|
end
|
105
|
-
|
106
|
-
raise NetBooter::Error.new("Error connecting to relay: #{e.message}")
|
111
|
+
resp
|
107
112
|
end
|
108
|
-
resp
|
109
|
-
end
|
110
113
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
114
|
+
def do_http_request(path)
|
115
|
+
resp = nil
|
116
|
+
Net::HTTP.start(@host) do |http|
|
117
|
+
req = Net::HTTP::Get.new(path)
|
115
118
|
|
116
|
-
|
119
|
+
req.basic_auth @options[:username], @options[:password] if @options[:username] && @options[:password]
|
117
120
|
|
118
|
-
|
121
|
+
resp = http.request(req)
|
119
122
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
+
# Error checking. Allow 200s and 302s
|
124
|
+
unless ['200', '302'].include? resp.code
|
125
|
+
raise NetBooter::Error.new "Relay responded with #{resp.code}. Perhaps you have the wrong relay type specified."
|
126
|
+
end
|
123
127
|
end
|
128
|
+
resp
|
124
129
|
end
|
125
|
-
|
130
|
+
|
126
131
|
end
|
127
132
|
|
128
133
|
end
|
@@ -1,24 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
module NetBooter
|
2
|
+
|
3
|
+
module Http
|
4
|
+
|
5
|
+
class RevA < HttpConnection
|
6
|
+
# So here's the deal... When you hit the switch page (pwrSw1.cgi) nothing happens.
|
7
|
+
# It's only when hitting the status page AFTER visiting a swith page that
|
8
|
+
# the relay is toggled.
|
9
|
+
def toggle_relay(outlet)
|
10
|
+
get_request("/pwrSw#{outlet}.cgi")
|
11
|
+
get_request("/synOpStatus.shtml")
|
12
|
+
end
|
9
13
|
|
10
|
-
|
11
|
-
|
14
|
+
def statuses
|
15
|
+
resp = get_request('/synOpStatus.shtml')
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
doc = Nokogiri::HTML(resp.body)
|
18
|
+
nodes = doc.xpath('//img')
|
19
|
+
status = {}
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
nodes.each do |node|
|
22
|
+
if node.values[0].match(/^led(off|on).gif$/)
|
23
|
+
status[node.parent.parent.xpath('th').first.content.to_i] = $1 == 'on' ? true : false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
status
|
20
27
|
end
|
21
28
|
end
|
22
|
-
|
29
|
+
|
23
30
|
end
|
31
|
+
|
24
32
|
end
|
@@ -1,20 +1,30 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module NetBooter
|
2
|
+
|
3
|
+
module Http
|
4
|
+
|
5
|
+
class RevB < HttpConnection
|
6
|
+
|
7
|
+
def toggle_relay(outlet)
|
8
|
+
get_request("/cmd.cgi?rly=#{outlet - 1}")
|
9
|
+
end
|
5
10
|
|
6
|
-
|
7
|
-
|
11
|
+
def statuses
|
12
|
+
resp = get_request('/status.xml')
|
8
13
|
|
9
|
-
|
10
|
-
|
14
|
+
doc = Nokogiri::XML(resp.body)
|
15
|
+
nodes = doc.xpath('/response/*')
|
11
16
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
status = {}
|
18
|
+
nodes.each do |node|
|
19
|
+
if node.name.match(/^rly(\d+)$/)
|
20
|
+
status[$1.to_i + 1] = node.content == '1' ? true : false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
status
|
16
24
|
end
|
25
|
+
|
17
26
|
end
|
18
|
-
|
27
|
+
|
19
28
|
end
|
20
|
-
|
29
|
+
|
30
|
+
end
|
metadata
CHANGED
@@ -1,57 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: synaccess_connect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Table XI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ! '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1.6'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ! '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '3.6'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '3.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: vcr
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.8'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.8'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: webmock
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -68,7 +68,7 @@ dependencies:
|
|
68
68
|
version: '1.16'
|
69
69
|
description: Ruby interface to connecting to Synaccess netBooter power relays
|
70
70
|
email:
|
71
|
-
-
|
71
|
+
- devs@tablexi.com
|
72
72
|
executables: []
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
@@ -76,12 +76,11 @@ files:
|
|
76
76
|
- README.md
|
77
77
|
- lib/synaccess_connect.rb
|
78
78
|
- lib/synaccess_connect/net_booter/error.rb
|
79
|
+
- lib/synaccess_connect/net_booter/http.rb
|
79
80
|
- lib/synaccess_connect/net_booter/http/http_connection.rb
|
80
81
|
- lib/synaccess_connect/net_booter/http/rev_a.rb
|
81
82
|
- lib/synaccess_connect/net_booter/http/rev_b.rb
|
82
|
-
- lib/synaccess_connect/
|
83
|
-
- lib/synaccess_connect/net_booter/telnet/rev_b.rb
|
84
|
-
- lib/synaccess_connect/net_booter/telnet/telnet_connection.rb
|
83
|
+
- lib/synaccess_connect/version.rb
|
85
84
|
homepage: https://github.com/tablexi/synaccess
|
86
85
|
licenses: []
|
87
86
|
metadata: {}
|
@@ -101,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
100
|
version: '0'
|
102
101
|
requirements: []
|
103
102
|
rubyforge_project:
|
104
|
-
rubygems_version: 2.
|
103
|
+
rubygems_version: 2.4.8
|
105
104
|
signing_key:
|
106
105
|
specification_version: 4
|
107
106
|
summary: ''
|
@@ -1,23 +0,0 @@
|
|
1
|
-
class NetBooter::Telnet::RevA < NetBooter::TelnetConnection
|
2
|
-
|
3
|
-
def override_options
|
4
|
-
{
|
5
|
-
:prompt => /^\r>$/n,
|
6
|
-
:status_string => 'On'
|
7
|
-
}
|
8
|
-
end
|
9
|
-
|
10
|
-
def local_statuses
|
11
|
-
parse_status @connection.cmd("pshow")
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
def authenticate
|
16
|
-
sleep 0.1
|
17
|
-
@connection.puts(@options[:username])
|
18
|
-
sleep 0.1
|
19
|
-
@connection.puts(@options[:password])
|
20
|
-
@connection.cmd('')
|
21
|
-
sleep 0.1
|
22
|
-
end
|
23
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
class NetBooter::Telnet::RevB < NetBooter::TelnetConnection
|
2
|
-
def local_statuses
|
3
|
-
@connection.cmd("")
|
4
|
-
sleep 0.25
|
5
|
-
parse_status @connection.cmd("pshow")
|
6
|
-
end
|
7
|
-
|
8
|
-
private
|
9
|
-
|
10
|
-
def authenticate
|
11
|
-
@connection.cmd('login')
|
12
|
-
sleep 0.25
|
13
|
-
@connection.puts(@options[:username])
|
14
|
-
sleep 0.25
|
15
|
-
@connection.puts(@options[:password])
|
16
|
-
end
|
17
|
-
end
|
@@ -1,119 +0,0 @@
|
|
1
|
-
require 'net/telnet'
|
2
|
-
|
3
|
-
class NetBooter::TelnetConnection
|
4
|
-
def initialize(host, options = {})
|
5
|
-
@host = host
|
6
|
-
@options = { :port => 23,
|
7
|
-
:binmode => false,
|
8
|
-
:prompt => /^[>]/n,
|
9
|
-
:timeout => 1,
|
10
|
-
:status_string => 'ON'
|
11
|
-
}.merge(override_options).merge(options)
|
12
|
-
end
|
13
|
-
|
14
|
-
def override_options
|
15
|
-
{}
|
16
|
-
end
|
17
|
-
|
18
|
-
def status(outlet = 1)
|
19
|
-
statuses.fetch outlet do
|
20
|
-
raise NetBooter::Error.new('Error communicating with relay')
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def statuses
|
25
|
-
with_connection :default => {} do
|
26
|
-
local_statuses
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def toggle_on(outlet = 1)
|
31
|
-
toggle(true, outlet)
|
32
|
-
end
|
33
|
-
|
34
|
-
def toggle_off(outlet = 1)
|
35
|
-
toggle(false, outlet)
|
36
|
-
end
|
37
|
-
|
38
|
-
def toggle(outlet, status)
|
39
|
-
status_string = status ? '1' : '0'
|
40
|
-
with_connection do
|
41
|
-
@connection.cmd("pset #{outlet} #{status_string}")
|
42
|
-
end
|
43
|
-
status
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def authenticate
|
49
|
-
raise NotImplementedException.new('Must implement in subclass')
|
50
|
-
end
|
51
|
-
|
52
|
-
# Parse the text that we get back from pshow
|
53
|
-
# returns hash of { channel => boolean_status }
|
54
|
-
def parse_status(response)
|
55
|
-
statuses = {}
|
56
|
-
return statuses unless response
|
57
|
-
|
58
|
-
response.split("\n").each do |line|
|
59
|
-
parts = line.split('|').map &:strip
|
60
|
-
next unless parts[0] =~ /^\d+/
|
61
|
-
statuses[parts[0].to_i] = parts[2] == @options[:status_string]
|
62
|
-
end
|
63
|
-
statuses
|
64
|
-
end
|
65
|
-
|
66
|
-
def connect
|
67
|
-
retry_block 5 do
|
68
|
-
@connection = Net::Telnet::new(
|
69
|
-
'Host' => @host,
|
70
|
-
'Port' => @options[:port],
|
71
|
-
'Binmode' => @options[:binmode],
|
72
|
-
'Prompt' => @options[:prompt],
|
73
|
-
'Timeout' => @options[:timeout]
|
74
|
-
)
|
75
|
-
authenticate if @options[:username] && @options[:password]
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def disconnect
|
80
|
-
begin
|
81
|
-
@connection.close if @connection
|
82
|
-
rescue
|
83
|
-
# do nothing
|
84
|
-
end
|
85
|
-
# needs a little bit of delay after disconnecting
|
86
|
-
# if so the next connection doesn't get refused while
|
87
|
-
# this one is closing. Number arrived at by experimentation
|
88
|
-
sleep 0.02
|
89
|
-
end
|
90
|
-
|
91
|
-
def with_connection options = {}
|
92
|
-
begin
|
93
|
-
connect
|
94
|
-
raise NetBooter::Error.new('Unable to connect') if @connection.nil?
|
95
|
-
output = yield
|
96
|
-
rescue => e
|
97
|
-
puts "ERROR! #{e.message}"
|
98
|
-
# puts e.backtrace.join("\n")
|
99
|
-
output = options[:default] if options[:default]
|
100
|
-
ensure
|
101
|
-
disconnect
|
102
|
-
end
|
103
|
-
|
104
|
-
output
|
105
|
-
end
|
106
|
-
|
107
|
-
def retry_block max_attempts, options = {}
|
108
|
-
max_attempts.times do |i|
|
109
|
-
begin
|
110
|
-
yield
|
111
|
-
break # if we made it through the yield without an error we can break
|
112
|
-
rescue => e
|
113
|
-
puts e.message
|
114
|
-
raise e if i + 1 >= max_attempts
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|