riscos 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/riscos.rb +177 -78
- metadata +5 -5
data/lib/riscos.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'expect'
|
2
2
|
require 'pty'
|
3
|
+
|
3
4
|
module Cisco
|
4
5
|
|
5
6
|
class Base
|
6
7
|
attr_accessor :timeout, :prompt, :output, :info
|
7
8
|
|
8
9
|
def initialize(options)
|
9
|
-
|
10
10
|
@host = options[:host] || "nil"
|
11
11
|
@user = options[:user] || "nil"
|
12
12
|
@pw = options[:pw] || "nil" #login pass
|
@@ -15,57 +15,52 @@ module Cisco
|
|
15
15
|
@w = "/dev/null" #writer socket
|
16
16
|
@p = nil #pid to kill later
|
17
17
|
@prompt = /\r\n\r.*[#>]\s?\z/n
|
18
|
-
@timeout =
|
18
|
+
@timeout = 10
|
19
19
|
@output = Array.new
|
20
|
-
@info = Array.new
|
20
|
+
@info = Array.new #store configuration info gleaned from config
|
21
|
+
@error = Array.new
|
21
22
|
end
|
22
|
-
|
23
|
+
# Quickly logs into the device.
|
24
|
+
#
|
25
|
+
# * runs a login, enable, and conft to get you where you need to be
|
23
26
|
def loginquick()
|
24
27
|
self.login
|
25
28
|
self.enable
|
26
29
|
self.conft
|
27
30
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def enable()
|
32
|
-
begin
|
31
|
+
# Turns on enable or superuser mode on the device.
|
32
|
+
#
|
33
|
+
# * gives you the ability to use the superuser's console
|
34
|
+
def enable()
|
33
35
|
@w.print("enable\n")
|
34
|
-
|
35
|
-
read(@r,@timeout, @prompt)
|
36
|
-
rescue Exception => ee
|
37
|
-
@info.push("ERROR: Exception for host in enable:#{ee.to_s}\n")
|
38
|
-
end
|
36
|
+
run(@enpw)
|
39
37
|
end
|
40
|
-
|
38
|
+
# Turns on 'configuration mode' on the device
|
39
|
+
#
|
40
|
+
# * gives you the set system parameters on the device
|
41
41
|
def conft()
|
42
|
-
|
43
|
-
|
44
|
-
read(@r,@timeout, @prompt)
|
45
|
-
@w.print("pager 0 \n")
|
46
|
-
read(@r,@timeout, @prompt)
|
47
|
-
rescue Exception => ee
|
48
|
-
@info.push("ERROR: Exception for host in conft :#{ee.to_s}\n")
|
49
|
-
end
|
50
|
-
|
42
|
+
run("conf t")
|
43
|
+
run("pager 0")
|
51
44
|
end
|
52
|
-
|
53
|
-
|
45
|
+
# Runs a technical diagnostic on the device. This outputs a lot of information.
|
46
|
+
#
|
47
|
+
# * this is basically one command that gives you almost everything you'd ever want to know
|
54
48
|
def showtech()
|
55
|
-
|
56
|
-
@w.print("show tech\n")
|
57
|
-
#it would be real nice to take this then populate the information about the device
|
58
|
-
read(@r,@timeout, @prompt)
|
59
|
-
rescue Exception => ee
|
60
|
-
@info.push("ERROR: Exception for host in show tech:#{ee.to_s}\n")
|
61
|
-
end
|
49
|
+
run("show tech")
|
62
50
|
end
|
63
|
-
|
64
|
-
|
51
|
+
# Lets us read the command line output of the device. If we error, we return the error in the @error array and the command that failed. We
|
52
|
+
# will also close the reading and writing sockets if we get a timeout. If we don't we end up with stray ruby processes.
|
53
|
+
#
|
54
|
+
# * these can change for each call
|
55
|
+
# * @r is the reader socket
|
56
|
+
# * @timeout is how log we want to wait for this particular read
|
57
|
+
# * @prompt is the prompt we'll wait for on this read
|
58
|
+
def read(r=@r,timeout=@timeout,prompt=@prompt)
|
59
|
+
|
65
60
|
begin
|
66
|
-
r.expect(
|
61
|
+
r.expect(prompt,timeout) do |rec|
|
67
62
|
if rec == nil then
|
68
|
-
@
|
63
|
+
@error.push("ERROR: Timeout talking to device")
|
69
64
|
close()
|
70
65
|
else
|
71
66
|
@output.push(rec)
|
@@ -73,96 +68,200 @@ module Cisco
|
|
73
68
|
end
|
74
69
|
end
|
75
70
|
rescue Exception => ee
|
76
|
-
@
|
71
|
+
@error.push "ERROR:Exception trying to read stream: #{ee.to_s}"
|
77
72
|
return @output
|
78
73
|
end
|
79
|
-
|
80
74
|
end
|
75
|
+
# Logout of the device
|
76
|
+
#
|
77
|
+
#
|
81
78
|
|
82
79
|
def logout()
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
@w.print("write mem\n")
|
87
|
-
read(@r,@timeout, @prompt)
|
88
|
-
@w.print("exit\n")
|
89
|
-
rescue Exception => ee
|
90
|
-
@info.push("ERROR: Exception for host in logout:#{ee.to_s}\n\nAlready closed connection?")
|
91
|
-
end
|
80
|
+
run("pager 30")
|
81
|
+
run("write mem")
|
82
|
+
@w.print("exit")
|
92
83
|
end
|
93
84
|
|
94
|
-
|
95
|
-
|
85
|
+
# Individual commands to run on the device. These would be good for scripts and batch processes.
|
86
|
+
#
|
87
|
+
# * cmd is the command you're sending to the device
|
88
|
+
# * @prompt is the particular prompt we're going to look for. We do a "read" after each run and return the output from the device
|
89
|
+
def run(cmd,prompt=@prompt)
|
96
90
|
begin
|
97
91
|
@w.print("#{cmd}\n")
|
98
|
-
buffer
|
92
|
+
buffer = read(@r,@timeout,prompt)
|
99
93
|
rescue Exception => ee
|
100
|
-
@
|
94
|
+
@error.push("ERROR: Exception for host while executing #{cmd}: #{ee.to_s}")
|
101
95
|
end
|
102
96
|
return buffer
|
103
97
|
end
|
104
98
|
|
99
|
+
# Close the connection. We're through.
|
100
|
+
#
|
101
|
+
# * close the sockets then kill the pid to make sure.
|
102
|
+
|
105
103
|
def close
|
106
|
-
|
107
104
|
begin
|
108
105
|
@w.close
|
109
106
|
@r.close
|
110
107
|
#just to be sure, nuke it
|
111
108
|
Process.kill(:SIGKILL, @p)
|
112
|
-
|
113
109
|
@output.push("connection closed")
|
114
110
|
rescue Exception => ee
|
115
|
-
@
|
111
|
+
@error.push("ERROR: Problem closing connection: #{ee.to_s}")
|
116
112
|
end
|
117
113
|
end
|
118
|
-
|
119
|
-
|
120
114
|
end
|
121
115
|
|
122
116
|
class Asa < Base
|
117
|
+
|
118
|
+
# Login specific to ASAs and FWSMs (since they behave just like ASAs)
|
119
|
+
#
|
120
|
+
#
|
123
121
|
def login()
|
124
122
|
cmd="ssh -o StrictHostKeyChecking=no #{@user}@#{@host}\n"
|
125
123
|
begin
|
126
124
|
PTY.spawn(cmd) do |r,w,p|
|
127
125
|
@r,@w,@p=r,w,p
|
128
126
|
read(@r,@timeout, "word:")
|
129
|
-
|
130
|
-
read(@r,@timeout, @prompt)
|
127
|
+
run(@pw)
|
131
128
|
end
|
132
129
|
|
133
130
|
rescue Exception => ee
|
134
|
-
@
|
131
|
+
@error.push("ERROR: Exception for host in login:#{ee.to_s}\n\nBad ip address?")
|
135
132
|
end
|
136
133
|
end
|
137
|
-
|
138
|
-
|
139
|
-
|
140
134
|
end
|
141
135
|
|
136
|
+
# Login specific to Pixes (since they behave differently than ASAs.)
|
137
|
+
#
|
138
|
+
#
|
142
139
|
|
143
140
|
class Pix < Base
|
144
141
|
|
145
142
|
def login()
|
146
143
|
cmd="ssh -o StrictHostKeyChecking=no #{@user}@#{@host}\n"
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
144
|
+
PTY.spawn(cmd) do |r,w,p|
|
145
|
+
@r,@w,@p=r,w,p
|
146
|
+
read(@r,@timeout, "word:")
|
147
|
+
run(@pw)
|
148
|
+
read()
|
149
|
+
#Pix adds an extra <CR> on login, so we remove it for you
|
150
|
+
@output.pop
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
## these are still being developed.
|
157
|
+
class Css < Base
|
158
|
+
attr_accessor :owner, :service, :sslproxy, :sslfiles
|
159
|
+
|
160
|
+
def initialize(options)
|
161
|
+
super(options)
|
162
|
+
@owner = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) }
|
163
|
+
@service = Array.new
|
164
|
+
@sslproxy = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) }
|
165
|
+
@sslfiles = Array.new
|
166
|
+
end
|
167
|
+
|
168
|
+
def login
|
169
|
+
cmd="ssh -o StrictHostKeyChecking=no #{@host}"
|
170
|
+
PTY.spawn(cmd) do |r,w,p|
|
171
|
+
@r,@w,@p=r,w,p
|
172
|
+
read(@r,@timeout, "name:")
|
173
|
+
run(@user, "word:")
|
174
|
+
run(@pw)
|
175
|
+
run("terminal length 65535")
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def logout()
|
180
|
+
run("terminal length 30")
|
181
|
+
run("write mem")
|
182
|
+
@w.print("exit")
|
183
|
+
end
|
184
|
+
|
185
|
+
# Runs a 'show service summary' on the related CSS.
|
186
|
+
#
|
187
|
+
# * the output is parsed into Service Name
|
188
|
+
# * next field is State
|
189
|
+
# * next field is Conn
|
190
|
+
# * next field is Weight
|
191
|
+
# * next field is Avg Load
|
192
|
+
# * last field is State Transitions
|
193
|
+
|
194
|
+
def showservices
|
195
|
+
s = run("show service summary")
|
196
|
+
#s = read()
|
197
|
+
s=s.first.split("\r\r\r\n")
|
198
|
+
s[5..-2].each do |l|
|
199
|
+
@service.push(l.split)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def owners
|
204
|
+
o = run("show run owner")
|
205
|
+
o = o.first.split("\r\r\r\n")
|
206
|
+
# we need to chomp the first and last lines
|
207
|
+
o.delete_at(0)
|
208
|
+
o.delete_at(-1)
|
209
|
+
#change to when/case
|
210
|
+
o[2..-1].each do |l|
|
211
|
+
next if l.empty?
|
212
|
+
l = l.split
|
213
|
+
line = case l
|
214
|
+
when /^owner/
|
215
|
+
@ow=l.last
|
216
|
+
@owner[@ow]
|
217
|
+
when /content/
|
218
|
+
@serv=[]
|
219
|
+
@co=l.last
|
220
|
+
@owner[@ow][@co]
|
221
|
+
when /^active/
|
222
|
+
@owner[@ow][@co][l.first]=true
|
223
|
+
when /add service/
|
224
|
+
@serv.push(l.last)
|
225
|
+
@owner[@ow][@co]["add service"]=@serv
|
226
|
+
else
|
227
|
+
@owner[@ow][@co][l[0..-2].to_s]=l.last
|
228
|
+
end
|
157
229
|
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def sslproxies
|
233
|
+
s= run("show run ssl-proxy-list")
|
234
|
+
s=s.first.split("\r\r\r\n")
|
235
|
+
s[3..-2].each do |l|
|
236
|
+
l=l.split
|
237
|
+
#puts l
|
238
|
+
line = case l.first
|
239
|
+
when /ssl-proxy-list/
|
240
|
+
@proxy=l.last
|
241
|
+
@sslproxy[l.last]
|
242
|
+
when /^active/
|
243
|
+
@sslproxy[@proxy]["active"]=true
|
244
|
+
when /ssl-server/
|
245
|
+
@details=[]
|
246
|
+
@server=l[1]
|
247
|
+
@sslproxy[@proxy][@server]
|
248
|
+
when /.*?\\s.*?/
|
249
|
+
puts "here"
|
250
|
+
@details.push((l.last[2..-1].collect {|x| x + " " }).to_s)
|
251
|
+
# @details.delete("")
|
252
|
+
@sslproxy[@proxy][@server]=@details
|
158
253
|
|
159
|
-
|
160
|
-
@
|
161
|
-
end
|
254
|
+
else
|
255
|
+
@sslproxy[@proxy]["active"]=false
|
256
|
+
end
|
162
257
|
end
|
163
|
-
|
164
|
-
|
258
|
+
end
|
259
|
+
|
260
|
+
def sslfile
|
261
|
+
@sslfiles = run("show ssl files")
|
165
262
|
|
166
263
|
end
|
264
|
+
|
265
|
+
end
|
167
266
|
|
168
267
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riscos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Voccio
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-02-16 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: Provides a common easy to use interface to talk to Cisco Pix and Cisco
|
16
|
+
description: Provides a common easy to use interface to talk to Cisco Pix, ASA, FWSM and Cisco CSSes.
|
17
17
|
email: paul@substation9.com
|
18
18
|
executables: []
|
19
19
|
|
@@ -26,7 +26,7 @@ files:
|
|
26
26
|
- Changelog
|
27
27
|
- LICENSE
|
28
28
|
- lib/riscos.rb
|
29
|
-
has_rdoc:
|
29
|
+
has_rdoc: true
|
30
30
|
homepage: http://riscos.rubyforge.org/
|
31
31
|
post_install_message:
|
32
32
|
rdoc_options: []
|
@@ -51,6 +51,6 @@ rubyforge_project: riscos
|
|
51
51
|
rubygems_version: 1.3.1
|
52
52
|
signing_key:
|
53
53
|
specification_version: 2
|
54
|
-
summary: Provides a common easy to use interface to talk to Cisco Pix and Cisco
|
54
|
+
summary: Provides a common easy to use interface to talk to Cisco Pix, ASA, FWSM and Cisco CSSes.
|
55
55
|
test_files: []
|
56
56
|
|