gaddygaddy 0.1.78
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.
- checksums.yaml +7 -0
- data/bin/gaddygaddy-client +10 -0
- data/bin/interval +8 -0
- data/conf/development.yml +0 -0
- data/conf/gaddy.yml +2 -0
- data/conf/log4r.yml +47 -0
- data/conf/test.yml +1 -0
- data/lib/device_info/device_info.rb +60 -0
- data/lib/gaddygaddy-client/chef_files.rb +98 -0
- data/lib/gaddygaddy-client/device_config.rb +0 -0
- data/lib/gaddygaddy-client/espeak.rb +26 -0
- data/lib/gaddygaddy-client/log_data.rb +42 -0
- data/lib/gaddygaddy-client/notification/espeak.rb +32 -0
- data/lib/gaddygaddy-client/notification/file_notification.rb +43 -0
- data/lib/gaddygaddy-client/notification/file_notification.rb~ +36 -0
- data/lib/gaddygaddy-client/notification/sensu.rb +40 -0
- data/lib/gaddygaddy-client/notification/wall.rb +25 -0
- data/lib/gaddygaddy-client/notification.rb +73 -0
- data/lib/gaddygaddy-client/svn-commit.tmp~ +4 -0
- data/lib/gaddygaddy-client.rb +396 -0
- data/lib/gaddygaddy-client.rb~ +425 -0
- data/lib/gg_config/gg_config.rb +162 -0
- data/lib/interval.rb +280 -0
- data/lib/logging/logging.rb +62 -0
- data/lib/utils/hash_monkeypatch.rb +34 -0
- data/lib/utils/request.rb +52 -0
- data/lib/utils/retriable.rb +63 -0
- data/lib/utils/run.rb +20 -0
- data/locales/en.yml +24 -0
- data/locales/sv.yml +11 -0
- metadata +160 -0
@@ -0,0 +1,425 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# gaddygaddy-client.rb
|
4
|
+
#
|
5
|
+
# Created by: mansson
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
APPLICATION_NAME = "gaddygaddy-client"
|
17
|
+
|
18
|
+
require 'gg_config/gg_config'
|
19
|
+
require 'device_info/device_info'
|
20
|
+
require 'fileutils'
|
21
|
+
require 'utils/hash_monkeypatch'
|
22
|
+
require 'json'
|
23
|
+
require 'subcommand'
|
24
|
+
require 'gaddygaddy-client/chef_management'
|
25
|
+
require 'logging/logging'
|
26
|
+
require 'restclient'
|
27
|
+
require 'systemu'
|
28
|
+
require 'utils/request'
|
29
|
+
require 'utils/retriable'
|
30
|
+
require 'error_constants'
|
31
|
+
|
32
|
+
REVISION = "$Revision: 1 $"[10..-3].chomp
|
33
|
+
|
34
|
+
DEFAULT_CHEF_DIR = "/var/chef"
|
35
|
+
DEFAULT_CONF_DIR = "/conf"
|
36
|
+
DEFAULT_CONF_FILE = "gaddy_*.gcf"
|
37
|
+
CONFIG_FILE_NAME = "node.json"
|
38
|
+
|
39
|
+
class TokenJException < JException;end
|
40
|
+
class CreateDeviceJException < JException;end
|
41
|
+
|
42
|
+
class GaddyGaddy_Client
|
43
|
+
|
44
|
+
include Logging
|
45
|
+
include Subcommands
|
46
|
+
include Retriable
|
47
|
+
extend Retriable
|
48
|
+
|
49
|
+
def initialize
|
50
|
+
logger.outputters = Log4r::Outputter.stdout
|
51
|
+
end
|
52
|
+
|
53
|
+
def usage
|
54
|
+
puts "gaddygaddy-client [OPTIONS]"
|
55
|
+
puts "The client to run for the GaddyGaddy service"
|
56
|
+
puts "For more information about the commands run gaddygaddy-client --help"
|
57
|
+
puts "Revision :#{REVISION}"
|
58
|
+
puts
|
59
|
+
end
|
60
|
+
|
61
|
+
def read_options
|
62
|
+
# This hash will hold all of the options
|
63
|
+
# parsed from the command-line by
|
64
|
+
# OptionParser.
|
65
|
+
@options = {}
|
66
|
+
|
67
|
+
|
68
|
+
global_options do |opts|
|
69
|
+
opts.banner = "Usage: gaddygaddy-client [options] [subcommand [options]]"
|
70
|
+
opts.description = "GaddyGaddy client for the GaddyGaddy service"
|
71
|
+
opts.separator ""
|
72
|
+
opts.separator "Global options are:"
|
73
|
+
|
74
|
+
@options[:conf_dir] = DEFAULT_CONF_DIR
|
75
|
+
opts.on( '--config_dir CONF-DIR', "Directory containing the client configuration files, default is #{DEFAULT_CONF_DIR}" ) do |conf_dir|
|
76
|
+
@options[:conf_dir] = conf_dir
|
77
|
+
end
|
78
|
+
|
79
|
+
@options[:conf_file] = DEFAULT_CONF_FILE
|
80
|
+
opts.on( '--config_file CONF-FILE', "File name (without) path for the configuration file, default is #{DEFAULT_CONF_FILE}" ) do |conf_file|
|
81
|
+
@options[:conf_file] = conf_file
|
82
|
+
end
|
83
|
+
|
84
|
+
@options[:log_file] = nil
|
85
|
+
opts.on( '-L', '--logfile FILE', 'Write log to FILE, defaults to STDOUT' ) do|file|
|
86
|
+
@options[:log_file] = file
|
87
|
+
end
|
88
|
+
|
89
|
+
@options[:file_host] = "config.gaddygaddy.com:84"
|
90
|
+
opts.on( '--file_host FILE_HOST', 'The file host to get files like cookbooks from' ) do|file_host|
|
91
|
+
@options[:file_host] = file_host
|
92
|
+
end
|
93
|
+
|
94
|
+
@options[:host] = "ap.gaddygaddy.com:82"
|
95
|
+
opts.on( '-H', '--host HOST', 'The host to connect to' ) do|host|
|
96
|
+
@options[:host] = host
|
97
|
+
end
|
98
|
+
|
99
|
+
@options[:log_level] = 'info'
|
100
|
+
opts.on( '-l', '--log_level level', 'Set the log level (debug, info, warn, error, fatal)' ) do|level|
|
101
|
+
@options[:log_level] = level
|
102
|
+
end
|
103
|
+
|
104
|
+
@options[:test_mode] = false
|
105
|
+
opts.on( '--test_mode', 'Used for testing, will only retry once for example' ) do
|
106
|
+
@options[:test_mode] = true
|
107
|
+
end
|
108
|
+
|
109
|
+
@options[:token] = nil
|
110
|
+
opts.on( '-t', '--token TOKEN', 'The token to be used to access' ) do|token|
|
111
|
+
@options[:token] = token
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
add_help_option
|
119
|
+
|
120
|
+
command :get_cookbooks do |opts|
|
121
|
+
opts.banner = "Usage: get_cookbooks [options]"
|
122
|
+
opts.description = "Will download the cookbooks from the GaddyGaddy service"
|
123
|
+
@options[:chef_dir] = DEFAULT_CHEF_DIR
|
124
|
+
opts.on( '--chef_dir CHEF-DIR', "The chef dir to place the files into, default is #{DEFAULT_CHEF_DIR}" ) do |chef_dir|
|
125
|
+
@options[:chef_dir] = chef_dir
|
126
|
+
end
|
127
|
+
@options[:cookbooks_version] = nil
|
128
|
+
opts.on( '--cookbooks_version COOKBOOKS_VERSION', "Override the setting of which cookbook version to download" ) do |cookbooks_version|
|
129
|
+
@options[:cookbooks_version] = cookbooks_version
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
command :chef_config do |opts|
|
134
|
+
opts.banner = "Usage: chef_config [options]"
|
135
|
+
opts.description = "Will download the config and place it in a directory"
|
136
|
+
end
|
137
|
+
|
138
|
+
command :init_config do |opts|
|
139
|
+
opts.banner = "Usage: init_config [options]"
|
140
|
+
opts.description = "Will init the config, will check that config files doesn't exist"
|
141
|
+
end
|
142
|
+
|
143
|
+
command :verify_installation do |opts|
|
144
|
+
opts.banner = "Usage: verify_installation[options]"
|
145
|
+
opts.description = "Will verify the installation and check for gaddy file and network configuration"
|
146
|
+
end
|
147
|
+
cmd = nil
|
148
|
+
begin
|
149
|
+
cmd = opt_parse
|
150
|
+
mandatory = []
|
151
|
+
missing = mandatory.select{ |param| @options[param].nil? }
|
152
|
+
unless missing.empty?
|
153
|
+
puts "Missing options: #{missing.join(', ')}" #
|
154
|
+
puts opt_parse #
|
155
|
+
exit 1
|
156
|
+
end
|
157
|
+
unless cmd
|
158
|
+
puts "No command is specified\n\n"
|
159
|
+
usage
|
160
|
+
puts print_actions
|
161
|
+
exit 1
|
162
|
+
end
|
163
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument #
|
164
|
+
puts $!.to_s # Friendly output when parsing fails
|
165
|
+
puts opt_parse #
|
166
|
+
exit 1 #
|
167
|
+
end
|
168
|
+
cmd
|
169
|
+
end
|
170
|
+
|
171
|
+
def gg_config
|
172
|
+
@gg_config ||= GGConfig.new(:conf_dir => @options[:conf_dir], :conf_file => @options[:conf_file])
|
173
|
+
end
|
174
|
+
|
175
|
+
def get_property(property_name)
|
176
|
+
file_name = File.join(conf_dir, "gaddygaddy.property")
|
177
|
+
value = nil
|
178
|
+
if File.exists? file_name
|
179
|
+
prop_file = File.open(File.join(conf_dir, "gaddygaddy.property"), "r")
|
180
|
+
prop_file.read_lines.each do |line|
|
181
|
+
prop, prop_value = line.split("=")
|
182
|
+
if prop.strip == property_name
|
183
|
+
value = value.strip
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
value
|
188
|
+
end
|
189
|
+
|
190
|
+
# Get the config directory
|
191
|
+
def conf_dir
|
192
|
+
@options[:conf_dir]
|
193
|
+
end
|
194
|
+
|
195
|
+
# Should try to get the host from options or config
|
196
|
+
|
197
|
+
def get_host
|
198
|
+
@options[:host]
|
199
|
+
end
|
200
|
+
|
201
|
+
# Get the version of cookbook installed at the system
|
202
|
+
|
203
|
+
def get_installed_cookbook_version
|
204
|
+
get_property "gaddygaddy.cookbooks.installed_version"
|
205
|
+
end
|
206
|
+
|
207
|
+
def get_cookbook_version
|
208
|
+
url = Request.get_base_url(get_host) + "/chef/cookbooks_version/1/#{user_id_salt}/#{device_id}/#{get_token}"
|
209
|
+
response = Request.client_service_get url
|
210
|
+
raise "Could not get cookbook version" unless response['cookbooks_version']
|
211
|
+
logger.debug "Got cookbook version: #{response}"
|
212
|
+
response['cookbooks_version']
|
213
|
+
end
|
214
|
+
|
215
|
+
def device_id
|
216
|
+
gg_config.config[:device_id]
|
217
|
+
end
|
218
|
+
|
219
|
+
def get_chef_config_file
|
220
|
+
url = Request.get_base_url(get_host) + "/chef/node_json/1/#{user_id_salt}/#{device_id}/#{get_token}"
|
221
|
+
response = Request.client_service_get url
|
222
|
+
raise "Could not get config file for device #{device_id}" unless response["run_list"].length > 0
|
223
|
+
logger.debug "Got config file: #{response}"
|
224
|
+
response
|
225
|
+
end
|
226
|
+
|
227
|
+
def get_chef_config
|
228
|
+
begin
|
229
|
+
FileUtils.mkdir_p conf_dir
|
230
|
+
rescue Exception => e
|
231
|
+
raise e.inspect
|
232
|
+
end
|
233
|
+
conf_content = get_chef_config_file
|
234
|
+
chef_config = conf_content['variables']
|
235
|
+
chef_config['run_list'] = conf_content['run_list']
|
236
|
+
|
237
|
+
conf_file = File.open File.join(conf_dir, CONFIG_FILE_NAME), "w"
|
238
|
+
conf_file.write chef_config.to_json
|
239
|
+
conf_file.close
|
240
|
+
end
|
241
|
+
|
242
|
+
# Check that the config file exist and has valid content, this will also be validated toward the server
|
243
|
+
def config_valid
|
244
|
+
config_ok = false
|
245
|
+
config_file_name = Dir.glob(File.join(conf_dir, @options[:conf_file]))[0]
|
246
|
+
logger.debug "Will validate config for #{config_file_name}"
|
247
|
+
if File.exists?(config_file_name)
|
248
|
+
begin
|
249
|
+
conf_file = File.open(config_file_name)
|
250
|
+
config = JSON.parse(conf_file.read)
|
251
|
+
rescue Exception => e
|
252
|
+
raise "Could not read from file #{config_file_name}"
|
253
|
+
end
|
254
|
+
logger.debug "Have read from file #{config_file_name}"
|
255
|
+
config_ok = config["device_id"]
|
256
|
+
end
|
257
|
+
# TODO validate the client against the client service
|
258
|
+
config_ok
|
259
|
+
end
|
260
|
+
|
261
|
+
# Get a device id, to start with only implemented for Raspberry
|
262
|
+
def hardware_id
|
263
|
+
hardware_id = `cat /proc/cpuinfo|grep Serial`.strip[10..-1].to_s.strip
|
264
|
+
logger.debug "The device id is #{hardware_id}"
|
265
|
+
if hardware_id == ""
|
266
|
+
hardware_id = 'test_device'
|
267
|
+
end
|
268
|
+
raise JNoDeviceIDFound.new({:message => "Could not found a device id for this computer, a device id is needed, see further help"}) unless hardware_id
|
269
|
+
hardware_id
|
270
|
+
end
|
271
|
+
|
272
|
+
# Get teh user name from the config
|
273
|
+
def user_email
|
274
|
+
# This to avoid characters like + replaced with space
|
275
|
+
gg_config.get_user_email
|
276
|
+
end
|
277
|
+
|
278
|
+
def user_id_salt
|
279
|
+
gg_config.get_user_id_salt
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
# Create a new config by requesting it from the server
|
284
|
+
def create_new_config
|
285
|
+
url = Request.get_base_url(get_host) + "/chef/add_device_for_user/1/#{CGI.escape(CGI.escape(user_email))}"
|
286
|
+
response = Request.client_service_get url
|
287
|
+
url_config = URI.encode(Request.get_base_url(get_host) + "/device/config_file/1/#{response['device_id']}/#{response['user_id_salt']}/#{response['token']}")
|
288
|
+
response_config = Request.client_service_get url_config
|
289
|
+
logger.debug response_config.class
|
290
|
+
logger.debug response_config.inspect
|
291
|
+
response = response_config
|
292
|
+
raise JNoDeviceIDFound if response_config['status'].to_i != 0
|
293
|
+
gg_config.config = response['config']
|
294
|
+
gg_config.save
|
295
|
+
end
|
296
|
+
|
297
|
+
# init the configuration by trying to get the node config, if that doesn't exist then create a new config
|
298
|
+
def init_config
|
299
|
+
begin
|
300
|
+
get_chef_config_file
|
301
|
+
rescue JNoGaddyGaddyConfigFile
|
302
|
+
end
|
303
|
+
return if config_valid
|
304
|
+
create_new_config
|
305
|
+
@device_info.post
|
306
|
+
end
|
307
|
+
|
308
|
+
def get_token
|
309
|
+
# TODO get this from config file
|
310
|
+
token = gg_config.config[:token]
|
311
|
+
raise TokenJException.new({:status => ERR_NO_VALID_TOKEN, :message => "No token specified"}) unless token
|
312
|
+
token
|
313
|
+
end
|
314
|
+
|
315
|
+
def run_cmd(cmd)
|
316
|
+
status, stdout, stderr = systemu cmd
|
317
|
+
raise "Could not run command: #{cmd}, stdout is #{stdout}, error message is #{stderr}" if status != 0
|
318
|
+
end
|
319
|
+
|
320
|
+
def get_cookbook
|
321
|
+
version = @options[:cookbooks_version] ? @options[:cookbooks_version] : get_cookbook_version.to_s
|
322
|
+
installed_version = get_installed_cookbook_version.to_s
|
323
|
+
tmp_file = "/tmp/cookbooks-#{version}.tar.gz"
|
324
|
+
port = 80
|
325
|
+
file_host = @options[:file_host]
|
326
|
+
# The file host should be without http or port
|
327
|
+
file_host = file_host.split("://")[1] if file_host.index("://")
|
328
|
+
file_host,port = file_host.split(":") if file_host.index(":")
|
329
|
+
Net::HTTP.start(file_host, port) do |http|
|
330
|
+
begin
|
331
|
+
file = open(tmp_file, 'wb')
|
332
|
+
cookbook_path = '/' + URI.encode("pkg/gg_chef_#{version}.tar.gz")
|
333
|
+
logger.debug "Will request the cookbooks files from http://#{file_host}:#{port}#{cookbook_path}"
|
334
|
+
result = http.request_get(cookbook_path) do |response|
|
335
|
+
response.read_body do |segment|
|
336
|
+
file.write(segment)
|
337
|
+
end
|
338
|
+
end
|
339
|
+
logger.debug "The tar cookbook request response was #{result.inspect}"
|
340
|
+
ensure
|
341
|
+
file.close
|
342
|
+
end
|
343
|
+
end
|
344
|
+
logger.debug "Will untar the file to #{@options[:chef_dir]} and then remove file #{tmp_file}"
|
345
|
+
FileUtils.mkdir_p @options[:chef_dir]
|
346
|
+
cmd = "tar -C #{@options[:chef_dir]} -zxvf #{tmp_file}"
|
347
|
+
run_cmd cmd
|
348
|
+
cmd_remove = "rm #{tmp_file}"
|
349
|
+
run_cmd cmd_remove
|
350
|
+
end
|
351
|
+
|
352
|
+
def self.alert(type)
|
353
|
+
alert_timing = case type
|
354
|
+
when :no_config_file
|
355
|
+
{:on => 0.1, :off => 0.1,:alert_text => 'Could not found any gaddy config file in /conf/gaddy_XXXX.gcf'}
|
356
|
+
when :no_network
|
357
|
+
{:on => 1,:off => 1, :alert_text => 'Could not connect to internet, network configuration seams broken'}
|
358
|
+
end
|
359
|
+
begin
|
360
|
+
`echo none >/sys/class/leds/led0/trigger`
|
361
|
+
count = 0
|
362
|
+
send_info_count = 20 / (alert_timing[:on] + alert_timing[:off])
|
363
|
+
while true do
|
364
|
+
if (count % send_info_count) == 0
|
365
|
+
puts alert_timing[:alert_text]
|
366
|
+
`/usr/bin/espeak "#{alert_timing[:alert_text]}"`
|
367
|
+
end
|
368
|
+
`echo 1 >/sys/class/leds/led0/brightness`
|
369
|
+
sleep alert_timing[:on]
|
370
|
+
`echo 0 >/sys/class/leds/led0/brightness`
|
371
|
+
sleep alert_timing[:off]
|
372
|
+
count += 1
|
373
|
+
end
|
374
|
+
ensure
|
375
|
+
`echo mmc0 >/sys/class/leds/led0/trigger`
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def self.ip_to_verify
|
380
|
+
'8.8.8.8'
|
381
|
+
end
|
382
|
+
|
383
|
+
def self.network_ok?
|
384
|
+
ping_result = `ping -w 10 #{ip_to_verify} -c 1`
|
385
|
+
logger.debug "Result of ping is #{ping_result}"
|
386
|
+
! ping_result.index("100% packet loss")
|
387
|
+
end
|
388
|
+
|
389
|
+
# Verify that we have a conf file and verify network connection
|
390
|
+
def self.verify_installation
|
391
|
+
conf_file = Dir.glob(File.join('/','conf', "gaddy*.gcf"))
|
392
|
+
alert(:no_config_file) if conf_file.empty?
|
393
|
+
alert(:no_network) unless network_ok?
|
394
|
+
end
|
395
|
+
|
396
|
+
def run
|
397
|
+
cmd = read_options
|
398
|
+
begin
|
399
|
+
Retriable.set_test_mode if @options[:test_mode]
|
400
|
+
@device_info = DeviceInfo.new(get_host, gg_config)
|
401
|
+
set_log_level @options[:log_level]
|
402
|
+
set_log_file @options[:log_file] if @options[:log_file]
|
403
|
+
logger.info "Will start #{APPLICATION_NAME} with command #{cmd}"
|
404
|
+
case cmd
|
405
|
+
when "get_cookbooks"
|
406
|
+
get_cookbook
|
407
|
+
when "chef_config"
|
408
|
+
get_chef_config
|
409
|
+
when "init_config"
|
410
|
+
init_config
|
411
|
+
when "verify_installation"
|
412
|
+
self.class.verify_installation
|
413
|
+
else
|
414
|
+
usage
|
415
|
+
raise "No valid command entered, the command is #{cmd}"
|
416
|
+
end
|
417
|
+
|
418
|
+
rescue Exception => e
|
419
|
+
logger.error e.message
|
420
|
+
logger.error "Enable full stack trace with -l DEBUG" unless logger.debug?
|
421
|
+
logger.error "Backtrace:\n\t#{e.backtrace.join("\n\t")}" if logger.debug?
|
422
|
+
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# config.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
|
17
|
+
$LOAD_PATH << File.expand_path('../../../../gg_common/lib',__FILE__)
|
18
|
+
|
19
|
+
require 'error_constants'
|
20
|
+
require 'jexception'
|
21
|
+
require_relative '../logging/logging'
|
22
|
+
require 'topic_constants'
|
23
|
+
|
24
|
+
class GGConfig
|
25
|
+
include Logging
|
26
|
+
|
27
|
+
def initialize(options = {:conf_dir => "/conf", :conf_file => "gaddy_*.gcf"} )
|
28
|
+
@conf_file = options[:conf_file]
|
29
|
+
@conf_dir = File.expand_path(options[:conf_dir])
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def device_id
|
34
|
+
config[:device_id]
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_device_name
|
38
|
+
device_name = get_config_for(:device_name,"host","device")
|
39
|
+
unless valid_host_name?(device_name)
|
40
|
+
raise JException.new({:message => "The host name #{device_name} is not a valid host name",
|
41
|
+
:status => ERR_NO_VALID_HOSTNAME,
|
42
|
+
:extra_info => {:host_name => device_name}
|
43
|
+
})
|
44
|
+
end
|
45
|
+
device_name
|
46
|
+
end
|
47
|
+
|
48
|
+
def token
|
49
|
+
config[:token]
|
50
|
+
end
|
51
|
+
|
52
|
+
def user_email
|
53
|
+
get_config_for(:user_email,"user","user")
|
54
|
+
end
|
55
|
+
|
56
|
+
def user_id_salt
|
57
|
+
get_config_for(:user_id_salt,"user","user_id_salt")
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
# Get the config file name
|
63
|
+
def config_file_name
|
64
|
+
Dir.glob(File.join(@conf_dir, @conf_file))[0]
|
65
|
+
end
|
66
|
+
|
67
|
+
def read_config_file
|
68
|
+
begin
|
69
|
+
config_file = File.open(config_file_name)
|
70
|
+
file_content = config_file.read
|
71
|
+
config = JSON.parse(file_content)
|
72
|
+
logger.debug "Have read config file #{config_file_name} and found content #{config.to_s}"
|
73
|
+
rescue Exception => e
|
74
|
+
raise JNoGaddyGaddyConfigFile.new({:message => e.message})
|
75
|
+
end
|
76
|
+
config.symbolize_keys!
|
77
|
+
end
|
78
|
+
|
79
|
+
def config
|
80
|
+
@config_content ||= read_config_file
|
81
|
+
end
|
82
|
+
|
83
|
+
def config= (new_config)
|
84
|
+
@config_content = new_config.symbolize_keys!
|
85
|
+
end
|
86
|
+
|
87
|
+
def valid_host_name?(host_name)
|
88
|
+
host_name.size <= 63 and not (host_name.rindex('-', 0) or host_name.index('-', -1) or host_name.scan(/[^a-z\d-]/i).any?)
|
89
|
+
end
|
90
|
+
|
91
|
+
def save
|
92
|
+
unless valid_config?
|
93
|
+
raise JCouldNotSaveConfigFileException.new({:message => "Missing configuration information, could not save config file for #{config.inspect}"})
|
94
|
+
end
|
95
|
+
begin
|
96
|
+
config_file = File.open(config_file_name,"w")
|
97
|
+
config_file.write config.to_json.to_s
|
98
|
+
rescue Exception => e
|
99
|
+
raise JCouldNotSaveConfigFileException.new({:message => e.message})
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# Generic method to get the initial config for a config_type, could be device_name or user_name, will also try
|
105
|
+
# to find all kind of configs files with device_name or user_name
|
106
|
+
def get_config_for(config_type, conf_name, extra_conf_file)
|
107
|
+
config_value = nil
|
108
|
+
begin
|
109
|
+
if config
|
110
|
+
logger.debug "Config exist and is #{config} looking for config type #{config_type}"
|
111
|
+
config_value = config[config_type]
|
112
|
+
end
|
113
|
+
rescue Exception => e
|
114
|
+
logger.info "Could not find a gaddygaddy config file, message is #{e.message}"
|
115
|
+
end
|
116
|
+
unless config_value
|
117
|
+
files = Dir.glob(File.join(@conf_dir, 'config.*'))
|
118
|
+
files << File.join(@conf_dir, extra_conf_file) if File.exist? File.join(@conf_dir, extra_conf_file)
|
119
|
+
files.each do |conf_file_name|
|
120
|
+
logger.debug "The file #{conf_file_name} has file size #{File.size(conf_file_name)}"
|
121
|
+
if File.size(conf_file_name).to_i < 1000
|
122
|
+
conf_file = File.open(conf_file_name,"r")
|
123
|
+
lines = conf_file.readlines
|
124
|
+
# Check if there are not a lot of lines in the config
|
125
|
+
if lines.size < 4
|
126
|
+
lines.each do |line|
|
127
|
+
if line.index("=")
|
128
|
+
args = line.split("=")
|
129
|
+
# Validate that the syntax of the property is ok
|
130
|
+
if args.size == 2
|
131
|
+
config_value = args[1].strip if args[0].strip == conf_name || args[0].strip == "config_value"
|
132
|
+
else
|
133
|
+
logger.info "The file #{conf_file_name} has too many = in the line #{line}"
|
134
|
+
end
|
135
|
+
else
|
136
|
+
# Validate that there are no spaces in the config_value
|
137
|
+
config_value = line.strip
|
138
|
+
end
|
139
|
+
end
|
140
|
+
else
|
141
|
+
logger.info "The file #{conf_file_name} is not a config file as it's too many lines"
|
142
|
+
end
|
143
|
+
else
|
144
|
+
logger.info "Will not check file #{conf_file_name} as it is to big"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
# Check that we have found a config_value and that the config_value is a valid host name, if not raise a exception with topic info to be able to help the user further
|
149
|
+
unless config_value
|
150
|
+
raise JNoGaddyGaddyConfigFile.new({:message => "Could not found any file with config in the config dir #{@conf_dir}",
|
151
|
+
:topic => TPC_NO_CONFIG_FILE,
|
152
|
+
:extra_info => {:conf_dir => @conf_dir}
|
153
|
+
})
|
154
|
+
end
|
155
|
+
config_value
|
156
|
+
end
|
157
|
+
|
158
|
+
def valid_config?
|
159
|
+
config[:user_id_salt] && config[:token] && config[:device_name]
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|