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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6179815ad86f1edb1a7571347aecf67360b39176
4
+ data.tar.gz: a9fbac4944dcd4a58676f6cf866c1f687b1fa935
5
+ SHA512:
6
+ metadata.gz: 4cb37474da862c7cfe4900f4148469f3368d72e64d6eea01201e4200025bf9c688c04d6744a9efc6320ea617f467e8968fa5b87d8bf549e7e2681ad156879327
7
+ data.tar.gz: b5b47bc9e70fe9608ec09fb0aa5a0857cb3d0741ecdf019eb14fe8e375f5b59b0baacdb4f105a9d713b56cd065ad5c558a047633bc3a6208b9768c8658040fbc
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # ./update_cookbook_versions
4
+ #
5
+
6
+ require 'rubygems'
7
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
8
+ require 'gaddygaddy-client'
9
+
10
+ GaddyGaddy_Client.new.run
data/bin/interval ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'rubygems'
5
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
6
+ require 'interval'
7
+
8
+ Interval.new.run
File without changes
data/conf/gaddy.yml ADDED
@@ -0,0 +1,2 @@
1
+ file_dir: /conf
2
+ speech_enabled: true
data/conf/log4r.yml ADDED
@@ -0,0 +1,47 @@
1
+ log4r_config:
2
+ # define all loggers ...
3
+ loggers:
4
+ - name : gaddygaddy-client
5
+ level : DEBUG
6
+ trace : 'false'
7
+ outputters:
8
+ - stderr
9
+ - stdout
10
+ - name : default
11
+ level : DEBUG
12
+ trace : 'false'
13
+ outputters:
14
+ - stderr
15
+ - stdout
16
+ - name : interval
17
+ level : DEBUG
18
+ trace : 'false'
19
+ outputters:
20
+ - stderr
21
+ - stdout
22
+ outputters:
23
+ - type : StderrOutputter
24
+ name : stderr
25
+ level : WARN
26
+ formatter:
27
+ date_pattern: '%y%m%d %H:%M:%S'
28
+ pattern : "[%5l] %d :: %m"
29
+ type : PatternFormatter
30
+
31
+ - type : StdoutOutputter
32
+ name : stdout
33
+ level : DEBUG
34
+ formatter:
35
+ date_pattern: '%y%m%d %H:%M:%S'
36
+ pattern : "[%5l] %d :: %m"
37
+ type : PatternFormatter
38
+
39
+ - type : StderrOutputter
40
+ name : stderr_test
41
+ level : ERROR
42
+ formatter:
43
+ date_pattern: '%y%m%d %H:%M:%S'
44
+ # Added 'M' and 't' here - they are slow, but we're not calling unless we need to
45
+ pattern : "[%5l] %d :: %M :: %t"
46
+ type : PatternFormatter
47
+
data/conf/test.yml ADDED
@@ -0,0 +1 @@
1
+ file_dir: ../../tmp/
@@ -0,0 +1,60 @@
1
+ #
2
+ # Name:
3
+ # device_data.rb
4
+ #
5
+ # Created by: GaddyGaddy
6
+ #
7
+ # Description:
8
+ #
9
+ # Will handle data about the client like node info from Ohai that will tell everything like ip-address, macaddress,
10
+ # hw config etc. The data will be sent to the GaddyGaddy service
11
+ #
12
+ # Copyright (c) 2013 GaddyGaddy
13
+ #
14
+ # All rights reserved.
15
+ #
16
+
17
+ require_relative '../logging/logging'
18
+ require 'ohai'
19
+
20
+ class DeviceInfo
21
+ include Logging
22
+ extend Logging
23
+
24
+ def initialize(host, gg_config)
25
+ @host = host
26
+ @gg_config = gg_config
27
+ end
28
+
29
+ # Give the host name set previous
30
+ def host
31
+ @host
32
+ end
33
+
34
+ def gg_config
35
+ @gg_config
36
+ end
37
+
38
+ # Get data about the client by using the Ohai component developed by Opscode
39
+ def get_ohai_data
40
+ Ohai::Config[:plugin_path] << '/etc/chef/ohai_plugins'
41
+ ohai_system = Ohai::System.new
42
+ ohai_system.all_plugins
43
+ ohai_system.data
44
+ end
45
+
46
+ # Get the device data, if the data does not exist get it from Ohai
47
+ def data
48
+ @data||=get_ohai_data
49
+ end
50
+
51
+ # Will post the device data to the client service
52
+ def post
53
+ url = Request.get_base_url(host) + "/device/set_device_data/1/#{gg_config.config[:user_id_salt]}/#{gg_config.config[:device_id]}/#{gg_config.config[:token]}"
54
+ logger.debug "Will post this ohai data:\n #{data}"
55
+ response = Request.client_service_post url, :ohai_data => data
56
+ logger.debug "The response for the request is #{response} #{response.class}"
57
+ raise JCouldNotPostClientDataException.new({:message=> "Could not post data to the gaddygaddy service, error code is #{response.body}"}) unless response[:status].to_i == 0
58
+ end
59
+
60
+ end
@@ -0,0 +1,98 @@
1
+ #
2
+ # Name:
3
+ # chef_files.rb
4
+ #
5
+ # Created by: GaddyGaddy
6
+ #
7
+ # Description:
8
+ #
9
+ #
10
+ #
11
+
12
+
13
+ DEFAULT_FILE_HOST_PORT = 80
14
+
15
+ require_relative '../utils/run'
16
+
17
+ class ChefFiles
18
+
19
+ include Logging
20
+
21
+ def initialize(config, ap_host, chef_dir)
22
+ @config = config
23
+ @ap_host = ap_host
24
+ @chef_dir = chef_dir
25
+ end
26
+
27
+ # Get the version of cookbook installed at the system
28
+
29
+ def installed_cookbook_version
30
+ installed_versions = Dir.glob(File.join(@chef_dir, 'cookbooks_version_[0-9]*'))
31
+ installed_versions.size > 0 ? installed_versions.map{|file| File.basename(file.split('_')[2])}.max : 0
32
+ end
33
+
34
+ def create_version_file(version)
35
+ File.open(File.join(@chef_dir,'cookbooks_version_' + version.to_s), "w") do |f|
36
+ f.puts "Version: #{version}"
37
+ f.puts "Created at #{Time.now}"
38
+ f.close
39
+ end
40
+ end
41
+
42
+ def get_cookbook_version
43
+ response = Request.client_service_get @ap_host, "/chef/cookbooks_version/1/#{@config.user_id_salt}/#{@config.device_id}/#{@config.token}"
44
+ raise "Could not get cookbook version" unless response['cookbooks_version']
45
+ logger.debug "Got cookbook version: #{response}"
46
+ response['cookbooks_version']
47
+ end
48
+
49
+ # Will return cookbook_uri depending on cookbook version
50
+ # -1 is not supported in production
51
+ def cookbook_path(prod_version, version)
52
+ if prod_version
53
+ '/' + URI.encode("pkg/gg_chef_#{version}.tar.gz")
54
+ else
55
+ '/chef/latest_cookbook'
56
+ end
57
+ end
58
+
59
+ #
60
+ # Will check version of installed cookbooks and update if it's old
61
+ #
62
+ def get_cookbooks(file_host, cookbooks_version)
63
+ version = cookbooks_version ? cookbooks_version : get_cookbook_version.to_s
64
+ installed_version = installed_cookbook_version.to_s
65
+ prod_version = version.split('_')[0].to_s != '0'
66
+ return if installed_version.size > 0 && (installed_version.to_s == version.to_s) && prod_version
67
+ tmp_file = "/tmp/cookbooks-#{version}.tar.gz"
68
+ port = DEFAULT_FILE_HOST_PORT
69
+ file_host = prod_version ? file_host : @ap_host
70
+ # The file host should be without http or port
71
+ file_host = file_host.split("://")[1] if file_host.index("://")
72
+ file_host,port = file_host.split(":") if file_host.index(":")
73
+ Net::HTTP.start(file_host, port) do |http|
74
+ begin
75
+ http.read_timeout = 500
76
+ file = open(tmp_file, 'wb')
77
+ logger.debug "Will request the cookbooks files from http://#{file_host}:#{port}#{cookbook_path(prod_version, version)}"
78
+ result = http.request_get(cookbook_path(prod_version, version)) do |response|
79
+ response.read_body do |segment|
80
+ file.write(segment)
81
+ end
82
+ end
83
+ logger.debug "The tar cookbook request response was #{result.inspect}"
84
+ ensure
85
+ file.close
86
+ end
87
+ end
88
+ logger.debug "Will untar the file to #{@chef_dir} and then remove file #{tmp_file}"
89
+ FileUtils.mkdir_p @chef_dir
90
+ # Check that the tar file is valid first
91
+ cmd = "tar --test-label -zvf #{tmp_file} && rm -rf #{@chef_dir}/* && tar -C #{@chef_dir} -zxvf #{tmp_file}"
92
+ run_cmd cmd
93
+ create_version_file version
94
+ cmd_remove = "rm #{tmp_file}"
95
+ run_cmd cmd_remove
96
+ end
97
+
98
+ end
File without changes
@@ -0,0 +1,26 @@
1
+ #
2
+ # Name:
3
+ # espeak.rb
4
+ #
5
+ # Created by: GaddyGaddy
6
+ #
7
+ # Description:
8
+ #
9
+ # Will manage espeak
10
+ #
11
+ # Copyright (c) 2013 GaddyGaddy
12
+ #
13
+ # All rights reserved.
14
+ #
15
+
16
+ require 'stringex'
17
+
18
+ class ESpeak
19
+
20
+ def self.speak to_speak
21
+ file_name = to_speak.to_ascii.replace_whitespace('-').gsub('/','-')
22
+ wav_file = "/tmp/#{file_name}.wav"
23
+ `/usr/bin/espeak -w #{wav_file} "#{to_speak}"` unless File.exist?(wav_file)
24
+ `/usr/bin/aplay #{wav_file}`
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ #
2
+ # Name:
3
+ # log_data.rb
4
+ #
5
+ # Created by: GaddyGaddy
6
+ #
7
+ # Description:
8
+ # Will get log_data from a log file
9
+ #
10
+ #
11
+ # Copyright (c) 2013 GaddyGaddy
12
+ #
13
+ # All rights reserved.
14
+ #
15
+
16
+ class LogData
17
+
18
+ #
19
+ # Get a specific number of lines from a log file
20
+ #
21
+ def self.get_log_data(log_file_name, lines)
22
+ unless log_file_name.index('/')
23
+ log_file_name = log_file_name + '.log' unless log_file_name[-4..-1] == '.log'
24
+ log_file_name = "/opt/log/#{log_file_name[0..-5]}/#{log_file_name}"
25
+ end
26
+ raise "File #{log_file_name} does not exist" unless File.exist?(log_file_name)
27
+ cmd = "tail -n #{lines} #{log_file_name}"
28
+ exit_code, stdout = systemu cmd
29
+ if exit_code.success?
30
+ stdout
31
+ else
32
+ 'Could not read log_data from ' + log_file_name
33
+ end
34
+ end
35
+
36
+ #
37
+ # Get the time when the log file was last modified
38
+ #
39
+ def self.get_log_file_time(log_file_name)
40
+ File.mtime(log_file_name).to_s
41
+ end
42
+ end
@@ -0,0 +1,32 @@
1
+ #
2
+ # Name:
3
+ # espeak.rb
4
+ #
5
+ # Created by: GaddyGaddy
6
+ #
7
+ # Description:
8
+ #
9
+ # Will notify via the speakers
10
+ #
11
+ # Copyright (c) 2013 GaddyGaddy
12
+ #
13
+ # All rights reserved.
14
+ #
15
+
16
+ require_relative '../espeak'
17
+
18
+ module Notification
19
+ class ESpeakNotification
20
+
21
+ def self.espeak?
22
+ `whereis espeak`.index('bin')
23
+ end
24
+
25
+ def self.notify(event, message_text)
26
+ if espeak?
27
+ ESpeak.speak message_text
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,43 @@
1
+ #
2
+ # Name:
3
+ # file.rb
4
+ #
5
+ # Created by: GaddyGaddy
6
+ #
7
+ # Description:
8
+ # Will write the notification to a file
9
+ #
10
+ #
11
+ # Copyright (c) 2013 GaddyGaddy
12
+ #
13
+ # All rights reserved.
14
+ #
15
+
16
+ module Notification
17
+
18
+ class FileNotification
19
+
20
+ def self.file_dir= file_dir
21
+ @file_dir = file_dir
22
+ end
23
+
24
+ def self.file_dir
25
+ @file_dir
26
+ end
27
+
28
+ def self.notify(event, message_text)
29
+ f=File.open(File.join(file_dir,'gaddy_notification.log'), 'a')
30
+ f.write "#{event['event_time'].strftime('%Y-%m-%d %H:%M')} #{event['type']} #{message_text}\n"
31
+ f.fsync
32
+ f.close
33
+ end
34
+
35
+ # This will check if the text is already in the log file
36
+ def self.text_in_log_file message
37
+ log_file=File.join(file_dir,'gaddy_notification.log')
38
+ `/bin/grep '#{message}' #{log_file} `.strip.length > 0
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Name:
3
+ # file.rb
4
+ #
5
+ # Created by: mansson
6
+ #
7
+ # Description:
8
+ # Will write the notification to a file
9
+ #
10
+ #
11
+ # Copyright (c) 2013 GaddyGaddy
12
+ #
13
+ # All rights reserved.
14
+ #
15
+
16
+ module Notification
17
+
18
+ class FileNotification
19
+
20
+ def self.file_dir= file_dir
21
+ @file_dir = file_dir
22
+ end
23
+
24
+ def self.file_dir
25
+ @file_dir
26
+ end
27
+
28
+ def self.notify(event, message_text)
29
+ f=File.open(File.join(file_dir,'gaddy_notification.log'), 'w')
30
+ f.write "#{event['event_time'].strftime('%Y-%m-%d %H:%M')} #{event['type']} #{message_text}\n"
31
+ f.close
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,40 @@
1
+ #
2
+ # Name:
3
+ # sensu.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
+ module Notification
17
+
18
+ SENSU_HOST = 'localhost'
19
+ SENSU_PORT = 3030
20
+
21
+ class Sensu
22
+ # To change this template use File | Settings | File Templates.
23
+ def self.notify(event, message_text)
24
+ report = {
25
+ :name => "gaddy_notification",
26
+ :output => event.to_json,
27
+ :status => 2,
28
+ :handler => 'send_event'
29
+ }
30
+
31
+ begin
32
+ s = TCPSocket.open(SENSU_HOST, SENSU_PORT)
33
+ s.print JSON.generate(report)
34
+ s.close
35
+ rescue Exception => e
36
+ puts e.message
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,25 @@
1
+ #
2
+ # Name:
3
+ # wall.rb
4
+ #
5
+ # Created by: GaddyGaddy
6
+ #
7
+ # Description:
8
+ #
9
+ #
10
+
11
+ module Notification
12
+ class Wall
13
+
14
+ def self.wall?
15
+ `whereis wall`.index('bin')
16
+ end
17
+
18
+ def self.notify(event, message_text)
19
+ if wall?
20
+ systemu("echo 'Gaddy says: #{message_text}'|wall")
21
+ end
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,73 @@
1
+ #
2
+ # Name:
3
+ # notification.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
+ require_relative '../logging/logging'
17
+ require_relative 'notification/file_notification'
18
+ require_relative 'notification/espeak'
19
+ require_relative 'notification/sensu'
20
+ require_relative 'notification/wall'
21
+ require 'i18n'
22
+
23
+ module Notification
24
+ class Send
25
+ include Logging
26
+
27
+ def initialize(options = {})
28
+ I18n.load_path += Dir[File.join(File.dirname(__FILE__), '..','..','locales', '*.yml').to_s]
29
+ @speech_enabled = options[:speech_enabled]
30
+ end
31
+
32
+ # Language is english for now, we need to add a language parameter to the user info or config for gaddygaddy
33
+ def language
34
+ 'en'
35
+ end
36
+
37
+ def event= event
38
+ @event = JSON.parse(event)
39
+ end
40
+
41
+ def event
42
+ @event
43
+ end
44
+
45
+ def message_as_text
46
+ logger.debug "Will create message from event #{event['message_key']}"
47
+ translated_text = I18n.t event['message_key'], {locale: language}
48
+ count_values = translated_text.split("%").count - 1
49
+ if event['message_values']||count_values > 0
50
+ if count_values == event['message_values'].length
51
+ translated_text % event['message_values']
52
+ else
53
+ raise "Mismatch between the text for #{event['message_key']} - #{translated_text} have #{count_values} %s and the size of event values array is #{event['message_values'].length}"
54
+ end
55
+ else
56
+ translated_text
57
+ end
58
+ end
59
+
60
+ # Will do notifications to different sources like log file, web site and even speak
61
+
62
+ def notify(device_id)
63
+ event['event_time'] = Time.now unless event['event_time']
64
+ event['device_id'] = device_id
65
+ # Need to test before we put stuff in log file
66
+ should_speak = ! Notification::FileNotification.text_in_log_file(message_as_text)
67
+ Notification::Wall.notify(event, message_as_text)
68
+ Notification::FileNotification.notify(event, message_as_text)
69
+ Notification::Sensu.notify(event, message_as_text)
70
+ Notification::ESpeakNotification.notify(event, message_as_text) if should_speak && @speech_enabled
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,4 @@
1
+
2
+ --This line, and those below, will be ignored--
3
+
4
+ M notification/file_notification.rb