lita-ssh-run 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -4
- data/lib/lita/handlers/ssh_run.rb +162 -45
- data/lita-ssh-run.gemspec +3 -2
- metadata +36 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6668cf973bb770f5e4780e4158e3fb040bcaff6b
|
4
|
+
data.tar.gz: ceea91c7635db468810021111e925bafb7068886
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f696b54d60afebd72c8b4e0df86efaf4c7f11cae81a86c7968d82f84ce192c67c041e6998a79aaf4914c6b1a0bf0278d6fbce54b1bfc40bb4de019f979f898ec
|
7
|
+
data.tar.gz: b4d3c3df2b10daf7415b272539e09cc627579ce63812b8486e09ffeb2bc7a07ab0e66a61d9c1ff0db86b429166b1007f1d46f0ab27861d48ef96ee8494895ae2
|
data/README.md
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
# lita-ssh-run
|
2
2
|
|
3
|
-
This will allow you to run commands via ssh
|
3
|
+
This will allow you to run commands via ssh and powershell via winrm
|
4
|
+
|
4
5
|
Example:
|
5
6
|
`Lita, run uptime on 192.168.1.10`
|
7
|
+
`Lita, run Get-Service on 192.168.1.20`
|
6
8
|
|
7
|
-
Usernames and
|
8
|
-
|
9
|
+
Usernames, passwords, and OS type are stored in redis memory by chat userid and host passed.
|
10
|
+
|
11
|
+
If not found, it will prompt via private message on how to enter user, password, and OS:
|
9
12
|
Currently passwords are passed via plaintext in private message. I have requested to Slack to add an obfuscation format block for things like this.
|
10
13
|
|
14
|
+
**Tested on slack and hipchat**
|
11
15
|
## Installation
|
12
16
|
|
13
17
|
Add lita-ssh-run to your Lita instance's Gemfile:
|
@@ -16,7 +20,6 @@ Add lita-ssh-run to your Lita instance's Gemfile:
|
|
16
20
|
gem "lita-ssh-run"
|
17
21
|
```
|
18
22
|
|
19
|
-
|
20
23
|
## Configuration
|
21
24
|
|
22
25
|
None
|
@@ -29,6 +32,12 @@ None
|
|
29
32
|
|
30
33
|
`Lita, set password for 192.168.1.0 to PASSWORD`
|
31
34
|
|
35
|
+
`Lita, set OS for 192.168.1.0 to linux`
|
36
|
+
|
37
|
+
`Lita, set OS for 192.168.1.0 to windows`
|
38
|
+
|
39
|
+
`List, set port for 192.168.1.0 to 2222`
|
40
|
+
|
32
41
|
|
33
42
|
## License
|
34
43
|
|
@@ -1,73 +1,190 @@
|
|
1
1
|
module Lita
|
2
2
|
module Handlers
|
3
3
|
class SshRun < Handler
|
4
|
-
|
4
|
+
require 'net/ssh'
|
5
|
+
require 'winrm'
|
5
6
|
|
6
|
-
|
7
|
+
route(/^run\s+(.+)\s+on\s+(.+)/i,
|
8
|
+
:run_command,
|
9
|
+
command: true,
|
10
|
+
help: { "run <command> on <machine>" => "runs an ssh or powershell command on remote machine" })
|
7
11
|
|
8
|
-
|
12
|
+
route(/^set\s+(username|password)\s+for\s+(.+)\s+to\s+(.+)/i,
|
13
|
+
:set_user_pass,
|
14
|
+
command: true,
|
15
|
+
help: { "set <username or password> for <machineName>" =>
|
16
|
+
"sets a username or password for a machine you want to run commands on" })
|
9
17
|
|
10
|
-
|
18
|
+
route(/^set\s+(port)\s+for\s+(.+)\s+to\s+(.+)/i,
|
19
|
+
:set_server_port,
|
20
|
+
command: true,
|
21
|
+
help: { "set port for <machinename>" =>
|
22
|
+
"changes default port for machine connection (defaults are 22 for SSH and 5985 for winrm" })
|
11
23
|
|
12
|
-
|
24
|
+
route(/^set\s+(os)\s+for\s+(.+)\s+to\s+(.+)/i,
|
25
|
+
:set_server_os,
|
26
|
+
command: true,
|
27
|
+
help: { "set os for <machineName>" =>
|
28
|
+
"choices are 'windows' and 'linux'. This tells us to use ssh or winrm for the specified machine" })
|
13
29
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
30
|
+
route(/^clear\s+all\s+stored\s+(creds|credentials)/i,
|
31
|
+
:flush_redis,
|
32
|
+
command: true,
|
33
|
+
restrict_to: :admins,
|
34
|
+
help: { "clear all stored cred" =>
|
35
|
+
"blows away our redis data for lita-run-ssh" })
|
36
|
+
|
37
|
+
def run_command(response)
|
38
|
+
server = response.matches[0][1]
|
39
|
+
id_server_os = response.user.id + "_" + server + "_os"
|
40
|
+
os = redis.get(id_server_os)
|
41
|
+
get_os(response, server) unless['WINDOWS', 'LINUX'].include? os.to_s.upcase
|
42
|
+
if (os.to_s.upcase.eql? 'WINDOWS')
|
43
|
+
run_winrm(response)
|
44
|
+
elsif (os.to_s.upcase.eql? 'LINUX')
|
45
|
+
run_ssh(response)
|
46
|
+
else
|
47
|
+
response.reply("I was unable to find an OS for you on #{server}, please check you direct messages from me.")
|
48
|
+
end
|
49
|
+
end
|
22
50
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
51
|
+
def run_ssh(response)
|
52
|
+
cmd = response.matches[0][0]
|
53
|
+
server = response.matches[0][1]
|
54
|
+
id_server_port = response.user.id + "_" + server + "_port"
|
55
|
+
port = redis.get(id_server_port)
|
56
|
+
if (port.nil?)
|
57
|
+
port = 22
|
58
|
+
end
|
59
|
+
id_server_user = response.user.id + "_" + server + "_username"
|
60
|
+
id_server_pass = response.user.id + "_" + server + "_password"
|
61
|
+
usernm = redis.get(id_server_user)
|
62
|
+
passwd = redis.get(id_server_pass)
|
63
|
+
get_user_pass(response, server, "Username") unless usernm
|
64
|
+
get_user_pass(response, server, "Password") unless passwd
|
65
|
+
if usernm && passwd && port
|
66
|
+
Net::SSH.start(server, usernm, :port => port, :password => passwd, :timeout => 10) do |ssh |
|
67
|
+
output = ssh.exec!(cmd)
|
68
|
+
if !output
|
69
|
+
response.reply("Command was run, but it appears there was no output to stdout or stderr.")
|
70
|
+
else
|
71
|
+
response.reply("```" + output.encode('utf-8', :invalid => :replace, :undef => :replace, :replace => '_') + "```")
|
27
72
|
end
|
28
|
-
elsif usernm
|
29
|
-
response.reply_with_mention("I was unable to find a password for you on #{server}, please check you direct messages from me.")
|
30
|
-
elsif passwd
|
31
|
-
response.reply_with_mention("I was unable to find a username for you on #{server}, please check you direct messages from me.")
|
32
|
-
else
|
33
|
-
response.reply_with_mention("I was unable to find a username or password for you on #{server}, please check you direct messages from me.")
|
34
73
|
end
|
74
|
+
elsif usernm
|
75
|
+
response.reply_with_mention("I was unable to find a password for you on #{server}, please check you direct messages from me.")
|
76
|
+
elsif passwd
|
77
|
+
response.reply_with_mention("I was unable to find a username for you on #{server}, please check you direct messages from me.")
|
78
|
+
else
|
79
|
+
response.reply_with_mention("I was unable to find a username or password for you on #{server}, please check you direct messages from me.")
|
80
|
+
end
|
81
|
+
end
|
35
82
|
|
83
|
+
def run_winrm(response)
|
84
|
+
cmd = response.matches[0][0]
|
85
|
+
server = response.matches[0][1]
|
86
|
+
id_server_port = response.user.id + "_" + server + "_port"
|
87
|
+
port = redis.get(id_server_port)
|
88
|
+
if (port.nil?)
|
89
|
+
port = 5985
|
36
90
|
end
|
91
|
+
id_server_user = response.user.id + "_" + server + "_username"
|
92
|
+
id_server_pass = response.user.id + "_" + server + "_password"
|
93
|
+
usernm = redis.get(id_server_user)
|
94
|
+
passwd = redis.get(id_server_pass)
|
95
|
+
get_user_pass(response, server, "Username") unless usernm
|
96
|
+
get_user_pass(response, server, "Password") unless passwd
|
97
|
+
if usernm && passwd && port
|
98
|
+
endpoint = "http://#{server}:#{port}/wsman"
|
99
|
+
winrm = WinRM::WinRMWebService.new(endpoint, :negotiate, :user => usernm, :pass => passwd)
|
100
|
+
winrm.create_executor do |executor|
|
101
|
+
executor.run_powershell_script(cmd) do |stdout, stderr|
|
102
|
+
if stdout.to_s == '' && stderr.to_s == ''
|
103
|
+
response.reply("Command was run, but it appears there was no output to stdout or stderr.")
|
104
|
+
else
|
105
|
+
out = StringIO.new
|
106
|
+
out.puts stdout
|
107
|
+
response.reply(out.string)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
elsif usernm
|
112
|
+
response.reply_with_mention("I was unable to find a password for you on #{server}, please check you direct messages from me.")
|
113
|
+
elsif passwd
|
114
|
+
response.reply_with_mention("I was unable to find a username for you on #{server}, please check you direct messages from me.")
|
115
|
+
else
|
116
|
+
response.reply_with_mention("I was unable to find a username or password for you on #{server}, please check you direct messages from me.")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def get_user_pass(response, server, * user_pass)
|
121
|
+
user_pass.each do |blah|
|
122
|
+
response.reply_privately("No #{blah.capitalize} found for you on #{server}\nPlease privately reply with:\n`Lita, set #{blah.capitalize} for #{server} to #{blah.upcase}`")
|
123
|
+
end
|
124
|
+
end
|
37
125
|
|
38
|
-
|
39
|
-
|
40
|
-
|
126
|
+
def get_os(response, server)
|
127
|
+
response.reply_privately("No os found for you on #{server}\nPlease privately reply with:\n`Lita, set os for #{server} to windows` or \n`Lita, set os for #{server} to linux`")
|
128
|
+
end
|
129
|
+
|
130
|
+
def set_user_pass(response)
|
131
|
+
request = response.matches[0][0]
|
132
|
+
server = response.matches[0][1]
|
133
|
+
value = response.matches[0][2]
|
134
|
+
id_server_user_pass = response.user.id + "_" + server + "_" + request.downcase
|
135
|
+
if request && server && value
|
136
|
+
redis.set(id_server_user_pass, value)
|
137
|
+
response.reply_privately("#{request.capitalize} set")
|
138
|
+
id_server_user = response.user.id + "_" + server + "_username"
|
139
|
+
id_server_pass = response.user.id + "_" + server + "_password"
|
140
|
+
if redis.get(id_server_user) && redis.get(id_server_pass)
|
141
|
+
response.reply("Username and Password now set, please rerun your request")
|
41
142
|
end
|
143
|
+
else
|
144
|
+
response.reply_privately("There seems to have been a problem setting that for you")
|
42
145
|
end
|
146
|
+
end
|
43
147
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
value = response.matches[0][2]
|
48
|
-
id_server_user_pass = response.user.id + "_" + server + "_" + request.downcase
|
148
|
+
def flush_redis(response)
|
149
|
+
redis.flushdb
|
150
|
+
end
|
49
151
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
152
|
+
def set_server_port(response)
|
153
|
+
request = response.matches[0][0]
|
154
|
+
server = response.matches[0][1]
|
155
|
+
value = response.matches[0][2]
|
156
|
+
id_server_port = response.user.id + "_" + server + "_port"
|
157
|
+
if request && server && value
|
158
|
+
redis.set(id_server_port, value)
|
159
|
+
if redis.get(id_server_port)
|
160
|
+
response.reply("Server Port now set to #{value}")
|
161
|
+
end
|
162
|
+
else
|
163
|
+
response.reply_privately("There seems to have been a problem setting that for you")
|
164
|
+
end
|
165
|
+
end
|
57
166
|
|
167
|
+
def set_server_os(response)
|
168
|
+
request = response.matches[0][0]
|
169
|
+
server = response.matches[0][1]
|
170
|
+
value = response.matches[0][2]
|
171
|
+
id_server_os = response.user.id + "_" + server + "_os"
|
172
|
+
if ['WINDOWS', 'LINUX'].include? value.to_s.upcase
|
173
|
+
if request && server && value
|
174
|
+
redis.set(id_server_os, value)
|
175
|
+
id_server_os = response.user.id + "_" + server + "_os"
|
176
|
+
if redis.get(id_server_os)
|
177
|
+
response.reply("Server os now set to #{value}.")
|
58
178
|
end
|
59
179
|
else
|
60
180
|
response.reply_privately("There seems to have been a problem setting that for you")
|
61
181
|
end
|
182
|
+
else
|
183
|
+
response.reply_privately("valid options for os are: windows, linux")
|
62
184
|
end
|
63
|
-
|
64
|
-
def flush_redis(response)
|
65
|
-
redis.flushdb
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
185
|
end
|
70
186
|
|
71
187
|
Lita.register_handler(SshRun)
|
188
|
+
end
|
72
189
|
end
|
73
|
-
end
|
190
|
+
end
|
data/lita-ssh-run.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "lita-ssh-run"
|
3
|
-
spec.version = "0.0.
|
3
|
+
spec.version = "0.0.3"
|
4
4
|
spec.authors = ["Dan Cash"]
|
5
5
|
spec.email = ["dancash04@gmail.com"]
|
6
|
-
spec.description = %q{Runs commands against remote server via ssh}
|
6
|
+
spec.description = %q{Runs commands against remote server via ssh or winrm}
|
7
7
|
spec.summary = %q{See description}
|
8
8
|
spec.homepage = "https://github.com/cashman04/lita-ssh-run"
|
9
9
|
spec.license = "MIT"
|
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
|
17
17
|
spec.add_runtime_dependency "lita", ">= 4.1"
|
18
18
|
spec.add_runtime_dependency 'net-ssh'
|
19
|
+
spec.add_runtime_dependency 'winrm'
|
19
20
|
|
20
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
21
22
|
spec.add_development_dependency "rake"
|
metadata
CHANGED
@@ -1,128 +1,142 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lita-ssh-run
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Cash
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lita
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.1'
|
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
26
|
version: '4.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: net-ssh
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: winrm
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- -
|
59
|
+
- - ~>
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '1.3'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- -
|
66
|
+
- - ~>
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '1.3'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - '>='
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - '>='
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rack-test
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - '>='
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - '>='
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rspec
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- -
|
101
|
+
- - '>='
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: 3.0.0
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- -
|
108
|
+
- - '>='
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: 3.0.0
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: simplecov
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- -
|
115
|
+
- - '>='
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '0'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
|
-
- -
|
122
|
+
- - '>='
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: coveralls
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
|
-
- -
|
129
|
+
- - '>='
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
|
-
- -
|
136
|
+
- - '>='
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
|
-
description: Runs commands against remote server via ssh
|
139
|
+
description: Runs commands against remote server via ssh or winrm
|
126
140
|
email:
|
127
141
|
- dancash04@gmail.com
|
128
142
|
executables: []
|
@@ -150,17 +164,17 @@ require_paths:
|
|
150
164
|
- lib
|
151
165
|
required_ruby_version: !ruby/object:Gem::Requirement
|
152
166
|
requirements:
|
153
|
-
- -
|
167
|
+
- - '>='
|
154
168
|
- !ruby/object:Gem::Version
|
155
169
|
version: '0'
|
156
170
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
171
|
requirements:
|
158
|
-
- -
|
172
|
+
- - '>='
|
159
173
|
- !ruby/object:Gem::Version
|
160
174
|
version: '0'
|
161
175
|
requirements: []
|
162
176
|
rubyforge_project:
|
163
|
-
rubygems_version: 2.
|
177
|
+
rubygems_version: 2.0.14
|
164
178
|
signing_key:
|
165
179
|
specification_version: 4
|
166
180
|
summary: See description
|