gs_phone 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+