serialkiller 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,3 @@
1
+ module SerialKiller
2
+ VERSION = '0.0.1'
3
+ 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: []