gs_phone 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+