serialkiller 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/serial +16 -0
- data/lib/serial.rb +43 -0
- data/lib/serial/cli.rb +20 -0
- data/lib/serial/devices.rb +1 -0
- data/lib/serial/devices/sentry.rb +62 -0
- data/lib/serial/version.rb +3 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 42b24d89567ed6c0261c138b259a99ce87b6bbc8
|
4
|
+
data.tar.gz: 21b1089a70ea52cbb18d7ba4a34bbc0fe2f379c2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4139376e90d1cced209c8f05137fb1db5d1efec246791f58128e2d68b9b13c6cbf958b48f59d3125e4ac36e7cec14868781583cae140db308769e2ed54b97344
|
7
|
+
data.tar.gz: f78a14175c90fd86e3633aba279ee08289974cbe997031701ce7133156ad8dd90a2eefd569bf0e6eeddd059ebebb9b46b351029197eacf251b1bb4a26d702887
|
data/bin/serial
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
3
|
+
require 'serial/cli'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
begin
|
7
|
+
ENV['THOR_DEBUG'] = '1'
|
8
|
+
etime = Benchmark.realtime { SerialKiller::CLI.start(ARGV) }
|
9
|
+
$stderr.puts "Completed in #{etime}s"
|
10
|
+
rescue Thor::UndefinedCommandError, Thor::UnknownArgumentError, Thor::AmbiguousCommandError, Thor::InvocationError => e
|
11
|
+
$stderr.puts(e.message)
|
12
|
+
exit(64)
|
13
|
+
rescue Thor::Error => e
|
14
|
+
$stderr.puts(e.message)
|
15
|
+
exit(1)
|
16
|
+
end
|
data/lib/serial.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
require 'ruby_expect'
|
4
|
+
require 'active_support/all'
|
5
|
+
|
6
|
+
require 'serial/devices'
|
7
|
+
|
8
|
+
module SerialKiller
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def connect(device: nil, host: nil, port: nil, offset: nil, timeout: nil, retries: nil, verbose: nil, keyfile: nil, username: '', password: '')
|
12
|
+
options = { offset: offset, keyfile: keyfile, verbose: verbose, timeout: timeout, retries: retries }
|
13
|
+
options[:username] = username unless username.empty?
|
14
|
+
options[:password] = password unless password.empty?
|
15
|
+
|
16
|
+
case device
|
17
|
+
when 'sentry'
|
18
|
+
sentry_connect(host, port, **options)
|
19
|
+
else
|
20
|
+
raise "#{device} is not supported"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def connect_device(host, port, offset: nil, keyfile: nil, verbose: nil, timeout: nil, retries: nil)
|
27
|
+
logger = Logger.new(STDOUT)
|
28
|
+
logger.level = Logger::DEBUG
|
29
|
+
exp = RubyExpect::Expect.spawn("/usr/bin/ssh root@#{host} -i #{keyfile} -p #{offset + port}", logger: verbose ? logger : nil)
|
30
|
+
exp.timeout = timeout
|
31
|
+
|
32
|
+
attempts = 0
|
33
|
+
exp.procedure do
|
34
|
+
exp.send ''
|
35
|
+
while attempts < retries
|
36
|
+
sleep(1)
|
37
|
+
yield exp
|
38
|
+
sleep(5)
|
39
|
+
attempts += 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/serial/cli.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'serial'
|
3
|
+
|
4
|
+
class SerialKiller::CLI < Thor
|
5
|
+
desc 'connect', 'Connect to a device'
|
6
|
+
method_option :device, type: :string, required: true, banner: 'DEVICE', desc: 'Type of device to connect to', enum: ['sentry'], aliases: '-d'
|
7
|
+
method_option :host, type: :string, required: true, banner: 'HOST', desc: 'Serial console server host to connect to', aliases: '-h'
|
8
|
+
method_option :port, type: :numeric, required: true, banner: 'PORT', desc: 'Serial console server port to connect to', aliases: '-p'
|
9
|
+
method_option :username, type: :string, default: '', banner: 'USERNAME', desc: 'Username for login', aliases: '-U'
|
10
|
+
method_option :password, type: :string, default: '', banner: 'PASSWORD', desc: 'Password for login', aliases: '-P'
|
11
|
+
method_option :offset, type: :numeric, default: 3000, banner: 'OFFSET', desc: 'Port offset on serial console server', aliases: '-o'
|
12
|
+
method_option :keyfile, type: :string, default: '/etc/conserver/.ssh/id_rsa', banner: 'KEYFILE', desc: 'Path to ssh keyfile', aliases: '-k'
|
13
|
+
method_option :timeout, type: :numeric, default: 30, banner: 'TIMEOUT', desc: 'Time to wait before giving up', aliases: '-t'
|
14
|
+
method_option :retries, type: :numeric, default: 5, banner: 'RETRIES', desc: 'Number of times to attempt to connect', aliases: '-r'
|
15
|
+
method_option :verbose, type: :boolean, default: false, desc: 'Run with verbose debug output', aliases: '-v'
|
16
|
+
def connect
|
17
|
+
opts = options.deep_symbolize_keys
|
18
|
+
SerialKiller.connect(**opts)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'serial/devices/sentry'
|
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
def sentry_extract(exp, username, password)
|
4
|
+
exp.send username
|
5
|
+
exp.expect /Password:/ do
|
6
|
+
send password
|
7
|
+
end
|
8
|
+
exp.expect /Switched CDU:/ do
|
9
|
+
send 'show system'
|
10
|
+
sleep(5)
|
11
|
+
end
|
12
|
+
|
13
|
+
exp.expect /NIC S\/N:\s+(.*)$/ do
|
14
|
+
puts "NIC Serial: #{exp.last_match.captures.first.strip}"
|
15
|
+
end
|
16
|
+
|
17
|
+
exp.expect /Switched CDU:/ do
|
18
|
+
send 'show network'
|
19
|
+
sleep(5)
|
20
|
+
end
|
21
|
+
|
22
|
+
exp.expect /IPv4 Address:\s+(.*)\s+Subnet Mask:.*$/ do
|
23
|
+
puts "DHCP IP: #{exp.last_match.captures.first.strip}"
|
24
|
+
end
|
25
|
+
|
26
|
+
exp.expect /More \(Y\/es N\/o\):/ do
|
27
|
+
send 'Y'
|
28
|
+
sleep(5)
|
29
|
+
end
|
30
|
+
|
31
|
+
exp.expect /IPv4 Address:\s+(.*)\s+Subnet Mask:.*$/ do
|
32
|
+
puts "Static IP: #{exp.last_match.captures.first.strip}"
|
33
|
+
end
|
34
|
+
|
35
|
+
exp.expect /More \(Y\/es N\/o\):/ do
|
36
|
+
send 'Y'
|
37
|
+
end
|
38
|
+
|
39
|
+
exp.expect /Switched CDU:/ do
|
40
|
+
send 'logout'
|
41
|
+
sleep(5)
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def sentry_connect(host, port, username: 'admn', password: 'admn', **kwargs)
|
47
|
+
connect_device(host, port, **kwargs) do |exp|
|
48
|
+
exp.procedure.any do
|
49
|
+
exp.expect /^\s+$/ do
|
50
|
+
exp.send ''
|
51
|
+
end
|
52
|
+
|
53
|
+
exp.expect /Sentry Switched CDU/ do
|
54
|
+
exp.send ''
|
55
|
+
end
|
56
|
+
|
57
|
+
exp.expect /Username:/ do
|
58
|
+
sentry_extract(exp, username, password)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: serialkiller
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dale Hamel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-11-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.6
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.2.6
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.19.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.19.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ruby_expect
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.7.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.7.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 10.4.2
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 10.4.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.10.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.10.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 3.2.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 3.2.0
|
97
|
+
description: Write expectations for network devices to interact with their serial
|
98
|
+
consoles
|
99
|
+
email: dale.hamel@srvthe.net
|
100
|
+
executables:
|
101
|
+
- serial
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- bin/serial
|
106
|
+
- lib/serial.rb
|
107
|
+
- lib/serial/cli.rb
|
108
|
+
- lib/serial/devices.rb
|
109
|
+
- lib/serial/devices/sentry.rb
|
110
|
+
- lib/serial/version.rb
|
111
|
+
homepage: http://rubygems.org/gems/serialkiller
|
112
|
+
licenses:
|
113
|
+
- MIT
|
114
|
+
metadata: {}
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 2.4.8
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: Automates serial console interactions using expectations
|
135
|
+
test_files: []
|