gs_phone 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +4 -0
- data/CHANGES.txt +8 -0
- data/COPYING.txt +279 -0
- data/Manifest.txt +10 -0
- data/README.txt +26 -0
- data/Rakefile +67 -0
- data/TODO.txt +25 -0
- data/bin/gs_phone +12 -0
- data/lib/gs_phone/version.rb +9 -0
- data/lib/gs_phone.rb +274 -0
- data/setup.rb +1585 -0
- data/test/gs_phone_test.rb +11 -0
- data/test/test_helper.rb +2 -0
- metadata +61 -0
data/lib/gs_phone.rb
ADDED
@@ -0,0 +1,274 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# This is used to manage the Grandstream phones.
|
3
|
+
# It is a wrapper over Charles Howes (gsutil@ch.pkts.ca)'s gsutil
|
4
|
+
# utility (http://www.pkts.ca/gsutil.shtml)
|
5
|
+
#
|
6
|
+
# Copyright (C) 2007 Eric Davis <edavis10@gmail.com>
|
7
|
+
#
|
8
|
+
# This program is free software; you can redistribute it and/or
|
9
|
+
# modify it under the terms of the GNU General Public License
|
10
|
+
# as published by the Free Software Foundation; either version 2
|
11
|
+
# of the License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program; if not, write to the Free Software
|
20
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
21
|
+
|
22
|
+
|
23
|
+
require 'yaml'
|
24
|
+
require 'optparse'
|
25
|
+
|
26
|
+
class GrandStream
|
27
|
+
|
28
|
+
# Default configurations
|
29
|
+
@user_file = "users.yml"
|
30
|
+
@admin_password = "admin"
|
31
|
+
@gsutil = "gsutil"
|
32
|
+
@config_files = "config"
|
33
|
+
|
34
|
+
|
35
|
+
# Setup the help messages with the optparse library
|
36
|
+
def initialize(args)
|
37
|
+
read_configuration
|
38
|
+
@ip = args[1]
|
39
|
+
@current_ip = args[2]
|
40
|
+
@admin = args[3]
|
41
|
+
opts = OptionParser.new do |opts|
|
42
|
+
opts.banner = "Usage: #$0 COMMANDS [options]\n\n" +
|
43
|
+
" 'IP' is the ip address you want the phone to use\n" +
|
44
|
+
" 'crtIP' is the ip address the phone currently has\n" +
|
45
|
+
" 'pass' is the current phone password\n\n"
|
46
|
+
|
47
|
+
opts.on("--new 'IP' ['crtIP'|'pass']", "Add new user and setup their phone ") do
|
48
|
+
self.add_user(@ip)
|
49
|
+
self.make(@ip)
|
50
|
+
self.update_config(@ip, @current_ip, @admin)
|
51
|
+
self.reboot_phone(@current_ip)
|
52
|
+
end
|
53
|
+
opts.on('-A', "--add-user", 'Adds a user to the phone database') { self.add_user(@ip) }
|
54
|
+
opts.on('-M', "--make 'IP", 'Generates a config file from the template') { self.make(@ip) }
|
55
|
+
opts.on('--make-all', 'Reboots all phones') { self.make_all }
|
56
|
+
opts.on('-U', "--update 'IP' ['crtIP'|'pass']", "Update the configuration file to the phone") { self.update_config(@ip, @current_ip, @admin) }
|
57
|
+
opts.on('--update-all', 'Updates the configs on all phones') { self.update_all }
|
58
|
+
opts.on('-R', "--reboot 'IP'", 'Reboots a phone') { self.reboot_phone(@ip) }
|
59
|
+
opts.on('--reboot-all', 'Reboots all phones') { self.reboot_all_phones }
|
60
|
+
opts.on('-F', '--find-ip', "Find the ip address in the configuration file") { self.find_ip }
|
61
|
+
|
62
|
+
end
|
63
|
+
opts.parse!(args)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Read the gs_phone configuration file to get the settings
|
67
|
+
def read_configuration
|
68
|
+
|
69
|
+
if File.exists?("#{ENV["HOME"]}/.gs_phone")
|
70
|
+
settings = Hash.new
|
71
|
+
settings = YAML::load(File.open("#{ENV["HOME"]}/.gs_phone"))
|
72
|
+
|
73
|
+
@user_file = settings["user_file"] if settings.include?("user_file")
|
74
|
+
@admin_password = settings["admin_password"]
|
75
|
+
@gsutil = settings["gsutil"]
|
76
|
+
@config_files = settings["config_files"]
|
77
|
+
else
|
78
|
+
puts "You have no default configuration file. We will create one for you"
|
79
|
+
settings = {
|
80
|
+
"admin_password" => "admin",
|
81
|
+
"user_file" => "users.yml",
|
82
|
+
"gsutil" => "gsutil",
|
83
|
+
"config_files" => "config"
|
84
|
+
}
|
85
|
+
|
86
|
+
file = File.new("#{ENV["HOME"]}/.gs_phone","w")
|
87
|
+
file.puts settings.to_yaml
|
88
|
+
file.close
|
89
|
+
|
90
|
+
puts "File #{ENV["HOME"]}/.gs_phone has been created. Please make sure the"
|
91
|
+
puts " settings are correct."
|
92
|
+
exit
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Add a user to the configuration file
|
98
|
+
def add_user(ip_addr=nil)
|
99
|
+
# Lets get some details for the new user
|
100
|
+
puts "GS> Username?"
|
101
|
+
username = STDIN.gets.chomp
|
102
|
+
puts "GS> Extension Number?"
|
103
|
+
password = STDIN.gets.chomp
|
104
|
+
# Skip the ip address if they already passed it in.
|
105
|
+
if ip_addr.nil?
|
106
|
+
puts "GS> Phone IP Address (i.e. 192.168.1.1)"
|
107
|
+
ip_addr = STDIN.gets.chomp
|
108
|
+
end
|
109
|
+
puts "GS> MAC Address?"
|
110
|
+
mac_addy = STDIN.gets.chomp
|
111
|
+
|
112
|
+
# Open the user file and enter the data
|
113
|
+
users = File.open(@user_file, 'a')
|
114
|
+
users.puts "---"
|
115
|
+
users.puts "name: " + username
|
116
|
+
users.puts "ext: " + password
|
117
|
+
users.puts "ip: " + ip_addr
|
118
|
+
users.puts "mac: " + mac_addy
|
119
|
+
users.close
|
120
|
+
|
121
|
+
# Set this so we can use it in other parts of the script if "--new" was called
|
122
|
+
@ip = ip_addr
|
123
|
+
end
|
124
|
+
|
125
|
+
# Generate a config file from the template
|
126
|
+
def make(ip_address=@ip)
|
127
|
+
# Skip the ip address if they already passed it in.
|
128
|
+
if ip_address.nil?
|
129
|
+
puts "GS> What ip address? "
|
130
|
+
ip_address = STDIN.gets.chomp
|
131
|
+
end
|
132
|
+
|
133
|
+
@user_list = Hash.new
|
134
|
+
@phone = Array.new
|
135
|
+
|
136
|
+
# Open the user file and find the user who has the ip address that matches
|
137
|
+
# the one we are looking for
|
138
|
+
users = File.open(@user_file)
|
139
|
+
data = YAML::load_documents(users) do |element|
|
140
|
+
if element['ip'] == ip_address and not element['skip'] == 'y'
|
141
|
+
name = element['name']
|
142
|
+
password = element['ext'].to_s
|
143
|
+
exten = element['ext'].to_s
|
144
|
+
ip = element['ip']
|
145
|
+
|
146
|
+
# Split the ip address into each octal, the Grandstream config files
|
147
|
+
# needs it this way
|
148
|
+
ip1, ip2, ip3, ip4 = ip.split('.')
|
149
|
+
|
150
|
+
templated = IO.readlines(@config_files + "template.cfg")
|
151
|
+
phone_config = ""
|
152
|
+
|
153
|
+
# Substitue in the user fields into their config
|
154
|
+
# a.k.a. Magic REGEX section
|
155
|
+
templated.each do |line|
|
156
|
+
phone_config << line.gsub(/<<ext>>/, exten).gsub(/<<name>>/, name).gsub(/<<password>>/, password).gsub(/<<ip1>>/, ip1).gsub(/<<ip2>>/, ip2).gsub(/<<ip3>>/, ip3).gsub(/<<ip4>>/, ip4)
|
157
|
+
end
|
158
|
+
# Write out the string to a file now
|
159
|
+
File.open("#{@config_files}#{ip}.cfg", "w+") do |file|
|
160
|
+
file.puts phone_config
|
161
|
+
end
|
162
|
+
puts "GS< Made config for extension #{exten.to_s}"
|
163
|
+
end # IF
|
164
|
+
end # DO
|
165
|
+
end
|
166
|
+
|
167
|
+
def make_all
|
168
|
+
puts "GS< Making all configs"
|
169
|
+
@user_list = Hash.new
|
170
|
+
|
171
|
+
users = File.open(@user_file)
|
172
|
+
# Build a hash of the ext to ip
|
173
|
+
data = YAML::load_documents(users) do |element|
|
174
|
+
@user_list[element['ext']] = element['ip']
|
175
|
+
end
|
176
|
+
@user_list.each do |ext,ip|
|
177
|
+
puts "GS< Making config for #{ext} (#{ip})"
|
178
|
+
make(ip)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
# Make a config file and push it to phone via web scraping
|
184
|
+
def update_config(ip_address=@ip, current_ip=nil, admin=nil)
|
185
|
+
# Skip the ip address if they already passed it in.
|
186
|
+
if ip_address.nil?
|
187
|
+
puts "GS> What ip address? "
|
188
|
+
ip_address = STDIN.gets.chomp
|
189
|
+
end
|
190
|
+
if admin.nil?
|
191
|
+
admin = @admin_password
|
192
|
+
end
|
193
|
+
if current_ip.nil?
|
194
|
+
current_ip = ip_address
|
195
|
+
end
|
196
|
+
# Setup the string to shell out to the gsutil script to scrape the webforms
|
197
|
+
cmd = "#{@gsutil} -p '#{admin}' -r '#{current_ip}' < #{@config_files}#{ip_address}.cfg"
|
198
|
+
`#{cmd}`.to_s # Evil eval().
|
199
|
+
puts "GS< Config sent to phone"
|
200
|
+
end
|
201
|
+
|
202
|
+
# Make a config file for each phone and push it to the phone
|
203
|
+
def update_all
|
204
|
+
puts "GS< Updating all phones"
|
205
|
+
@user_list = Hash.new
|
206
|
+
|
207
|
+
users = File.open(@user_file)
|
208
|
+
# Build a hash of the ext to ip
|
209
|
+
data = YAML::load_documents(users) do |element|
|
210
|
+
if not element['skip'] == 'y'
|
211
|
+
@user_list[element['ext']] = element['ip']
|
212
|
+
end
|
213
|
+
end
|
214
|
+
@user_list.each do |ext,ip|
|
215
|
+
puts "GS< Making config for #{ext} (#{ip})"
|
216
|
+
update_config(ip)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
# Reboot a phone
|
222
|
+
def reboot_phone(ip_address=@ip)
|
223
|
+
# Skip the ip address if they already passed it in.
|
224
|
+
if ip_address.nil?
|
225
|
+
puts "GS> What ip address? "
|
226
|
+
ip_address = STDIN.gets.chomp
|
227
|
+
end
|
228
|
+
# Need a delay, if we just uploaded the new config then the phone will give a 500
|
229
|
+
# error if we try to reboot it too soon
|
230
|
+
sleep(3)
|
231
|
+
# Setup the string to shell out to the gsutil script to scrape the webforms
|
232
|
+
cmd = "#{@gsutil} -p '#{@admin_password}' -b '#{ip_address}'"
|
233
|
+
`#{cmd}` # Evil eval() two
|
234
|
+
puts "GS< Phone rebooted"
|
235
|
+
end
|
236
|
+
|
237
|
+
# Reboot all phones
|
238
|
+
def reboot_all_phones
|
239
|
+
puts "GS< Rebooting all phones"
|
240
|
+
@user_list = Hash.new
|
241
|
+
|
242
|
+
users = File.open(@user_file)
|
243
|
+
# Build a hash of the ext to ip
|
244
|
+
data = YAML::load_documents(users) do |element|
|
245
|
+
if not element['skip'] == 'y'
|
246
|
+
@user_list[element['ext']] = element['ip']
|
247
|
+
end
|
248
|
+
end
|
249
|
+
# Need a delay, if we just uploaded the new config then the phone will give a 500
|
250
|
+
# error if we try to reboot it too soon
|
251
|
+
sleep(3)
|
252
|
+
# Go-go BOFH method, this will reboot every phone in the user list.
|
253
|
+
@user_list.each do |ext,ip|
|
254
|
+
puts "GS< Rebooting phone #{ext} (#{ip})"
|
255
|
+
cmd = "#{@gsutil} -p '#{@admin_password}' -b '#{ip}'"
|
256
|
+
`#{cmd}`
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Finds the ip address of the phone if you know the extension.
|
261
|
+
def find_ip
|
262
|
+
print "What extension? "
|
263
|
+
exten_in = STDIN.gets.chomp.to_i
|
264
|
+
|
265
|
+
# Go thorugh config file loking for the extension
|
266
|
+
data = YAML::load_documents(File.open(@user_file)) do |element|
|
267
|
+
if element['ext'] == exten_in
|
268
|
+
@ip = element['ip']
|
269
|
+
puts "GS< #{element['ip']}"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end # Class
|
274
|
+
|