checkup 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +22 -0
- data/bin/checkup +9 -0
- data/checkup.gemspec +24 -0
- data/lib/checkup.rb +53 -0
- data/lib/checkup/binder.rb +14 -0
- data/lib/checkup/cli/utility.rb +62 -0
- data/lib/checkup/config.rb +41 -0
- data/lib/checkup/configuration/base.rb +6 -0
- data/lib/checkup/configuration/helpers.rb +52 -0
- data/lib/checkup/configuration/notifier/base.rb +13 -0
- data/lib/checkup/configuration/notifier/mail.rb +112 -0
- data/lib/checkup/configuration/service/base.rb +10 -0
- data/lib/checkup/configuration/service/http.rb +14 -0
- data/lib/checkup/dependency.rb +38 -0
- data/lib/checkup/errors.rb +80 -0
- data/lib/checkup/logger.rb +157 -0
- data/lib/checkup/model.rb +119 -0
- data/lib/checkup/notifier/base.rb +26 -0
- data/lib/checkup/notifier/mail.rb +170 -0
- data/lib/checkup/service/base.rb +23 -0
- data/lib/checkup/service/http.rb +47 -0
- data/lib/checkup/template.rb +33 -0
- data/lib/checkup/version.rb +43 -0
- data/templates/notifier/mail/error.erb +3 -0
- metadata +103 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
checkup (0.0.1)
|
5
|
+
httparty
|
6
|
+
thor (~> 0.14.6)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
httparty (0.9.0)
|
12
|
+
multi_json (~> 1.0)
|
13
|
+
multi_xml
|
14
|
+
multi_json (1.3.6)
|
15
|
+
multi_xml (0.5.1)
|
16
|
+
thor (0.14.6)
|
17
|
+
|
18
|
+
PLATFORMS
|
19
|
+
ruby
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
checkup!
|
data/bin/checkup
ADDED
data/checkup.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
require File.expand_path('lib/checkup/version')
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'checkup'
|
7
|
+
gem.version = Checkup::Version.current
|
8
|
+
gem.platform = Gem::Platform::RUBY
|
9
|
+
gem.authors = 'Heiko Moeller'
|
10
|
+
gem.email = 'femaref@googlemail.com'
|
11
|
+
gem.homepage = 'http://rubygems.org/gems/checkup'
|
12
|
+
gem.summary = ''
|
13
|
+
|
14
|
+
|
15
|
+
gem.files = %x[git ls-files].split("\n")
|
16
|
+
gem.test_files = %x[git ls-files -- {spec}/*].split("\n")
|
17
|
+
gem.require_path = 'lib'
|
18
|
+
|
19
|
+
gem.executables = ['checkup']
|
20
|
+
|
21
|
+
gem.add_dependency 'thor', ['~> 0.14.6']
|
22
|
+
gem.add_dependency 'httparty'
|
23
|
+
|
24
|
+
end
|
data/lib/checkup.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'thor'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'Checkup requires the Thor library'
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
|
10
|
+
module Checkup
|
11
|
+
LIBRARY_PATH = File.join(File.dirname(__FILE__), 'checkup')
|
12
|
+
TEMPLATE_PATH = File.join(File.dirname(__FILE__), '..', 'templates')
|
13
|
+
CLI_PATH = File.join(LIBRARY_PATH, 'cli')
|
14
|
+
CONFIGURATION_PATH = File.join(LIBRARY_PATH, 'configuration')
|
15
|
+
|
16
|
+
autoload :Binder, File.join(LIBRARY_PATH, 'binder')
|
17
|
+
autoload :Config, File.join(LIBRARY_PATH, 'config')
|
18
|
+
autoload :Dependency, File.join(LIBRARY_PATH, 'dependency')
|
19
|
+
autoload :Errors, File.join(LIBRARY_PATH, 'errors')
|
20
|
+
autoload :Logger, File.join(LIBRARY_PATH, 'logger')
|
21
|
+
autoload :Model, File.join(LIBRARY_PATH, 'model')
|
22
|
+
autoload :Template, File.join(LIBRARY_PATH, 'template')
|
23
|
+
autoload :Version, File.join(LIBRARY_PATH, 'version')
|
24
|
+
|
25
|
+
module CLI
|
26
|
+
autoload :Utility, File.join(CLI_PATH, 'utility')
|
27
|
+
end
|
28
|
+
|
29
|
+
module Configuration
|
30
|
+
autoload :Base, File.join(CONFIGURATION_PATH, 'base')
|
31
|
+
autoload :Helpers, File.join(CONFIGURATION_PATH, 'helpers')
|
32
|
+
|
33
|
+
module Notifier
|
34
|
+
autoload :Base, File.join(CONFIGURATION_PATH, 'notifier', 'base')
|
35
|
+
autoload :Mail, File.join(CONFIGURATION_PATH, 'notifier', 'mail')
|
36
|
+
end
|
37
|
+
|
38
|
+
module Service
|
39
|
+
autoload :Base, File.join(CONFIGURATION_PATH, 'service', 'base')
|
40
|
+
autoload :Http, File.join(CONFIGURATION_PATH, 'service', 'http')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module Notifier
|
45
|
+
autoload :Base, File.join(LIBRARY_PATH, 'notifier', 'base')
|
46
|
+
autoload :Mail, File.join(LIBRARY_PATH, 'notifier', 'mail')
|
47
|
+
end
|
48
|
+
|
49
|
+
module Service
|
50
|
+
autoload :Base, File.join(LIBRARY_PATH, 'service', 'base')
|
51
|
+
autoload :Http, File.join(LIBRARY_PATH, 'service', 'http')
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Checkup
|
2
|
+
module CLI
|
3
|
+
class Utility < Thor
|
4
|
+
include Thor::Actions
|
5
|
+
|
6
|
+
method_option :trigger, :type => :string, :required => true, :aliases => ['-t', '--triggers']
|
7
|
+
method_option :root_path, :type => :string, :default => '', :aliases => '-r'
|
8
|
+
desc 'perform', 'executes a named model'
|
9
|
+
def perform
|
10
|
+
root_path = options[:root_path]
|
11
|
+
|
12
|
+
if root_path == ""
|
13
|
+
root_path = Checkup::Config::DEFAULT_ROOT_PATH
|
14
|
+
end
|
15
|
+
|
16
|
+
load root_path
|
17
|
+
|
18
|
+
triggers = options[:trigger].split(",")
|
19
|
+
triggers.map!(&:strip).map! {|t|
|
20
|
+
t.include?('*') ? Model.find_matching(t) : t
|
21
|
+
}.flatten!
|
22
|
+
|
23
|
+
triggers.each do |trigger|
|
24
|
+
model = Model.find(trigger)
|
25
|
+
model.perform!
|
26
|
+
Logger.clear!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
method_option :root_path, :type => :string, :default => '', :aliases => '-r'
|
31
|
+
desc 'list', 'lists all models'
|
32
|
+
def list
|
33
|
+
root_path = options[:root_path]
|
34
|
+
|
35
|
+
if root_path == ""
|
36
|
+
root_path = Checkup::Config::DEFAULT_ROOT_PATH
|
37
|
+
end
|
38
|
+
|
39
|
+
load root_path
|
40
|
+
|
41
|
+
Model.all.each do |model|
|
42
|
+
puts model.trigger
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def load (path)
|
49
|
+
path = File.expand_path path
|
50
|
+
|
51
|
+
if !Dir.exists? path
|
52
|
+
FileUtils.mkdir_p path
|
53
|
+
end
|
54
|
+
|
55
|
+
Dir[File.join(path, "*.rb")].each do |file|
|
56
|
+
Checkup::Config.class_eval File.read(File.expand_path(File.basename(file), path))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Checkup
|
2
|
+
module Config
|
3
|
+
DEFAULT_ROOT_PATH = '~/.checkup'
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def add_dsl_constants!
|
7
|
+
create_modules(
|
8
|
+
self,
|
9
|
+
[
|
10
|
+
# Services
|
11
|
+
['Http'],
|
12
|
+
# Notifiers
|
13
|
+
['Mail']
|
14
|
+
]
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_modules(scope, names)
|
19
|
+
names.flatten.each do |name|
|
20
|
+
if name.is_a?(Hash)
|
21
|
+
name.each do |key, val|
|
22
|
+
create_modules(get_or_create_empty_module(scope, key), [val])
|
23
|
+
end
|
24
|
+
else
|
25
|
+
get_or_create_empty_module(scope, name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_or_create_empty_module(scope, const)
|
31
|
+
if scope.const_defined?(const)
|
32
|
+
scope.const_get(const)
|
33
|
+
else
|
34
|
+
scope.const_set(const, Module.new)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
add_dsl_constants!
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Checkup
|
4
|
+
module Configuration
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
##
|
8
|
+
# Finds all the object's getter methods and checks the global
|
9
|
+
# configuration for these methods, if they respond then they will
|
10
|
+
# assign the object's attribute(s) to that particular global configuration's attribute
|
11
|
+
def load_defaults!
|
12
|
+
module_names = self.class.name.split('::')[1..-1]
|
13
|
+
configuration = Checkup::Configuration
|
14
|
+
module_names.each do |module_name|
|
15
|
+
configuration = configuration.const_get(module_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
getter_methods.each do |attribute|
|
19
|
+
if configuration.respond_to?(attribute)
|
20
|
+
self.send("#{attribute}=", configuration.send(attribute))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Clears all the defaults that may have been set by the user
|
27
|
+
def clear_defaults!
|
28
|
+
setter_methods.each do |method|
|
29
|
+
self.send(method, nil)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
##
|
36
|
+
# Returns an Array of the setter methods (as String)
|
37
|
+
def setter_methods
|
38
|
+
methods.map do |method|
|
39
|
+
method = method.to_s
|
40
|
+
method if method =~ /^\w(\w|\d|\_)+\=$/ and method != 'taguri='
|
41
|
+
end.compact
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Returns an Array of getter methods (as String)
|
46
|
+
def getter_methods
|
47
|
+
setter_methods.map {|method| method.sub('=','') }
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Checkup
|
4
|
+
module Configuration
|
5
|
+
module Notifier
|
6
|
+
class Mail < Base
|
7
|
+
class << self
|
8
|
+
|
9
|
+
##
|
10
|
+
# Mail delivery method to be used by the Mail gem.
|
11
|
+
# Supported methods:
|
12
|
+
#
|
13
|
+
# `:smtp` [::Mail::SMTP] (default)
|
14
|
+
# : Settings used only by this method:
|
15
|
+
# : `address`, `port`, `domain`, `user_name`, `password`
|
16
|
+
# : `authentication`, `enable_starttls_auto`, `openssl_verify_mode`
|
17
|
+
#
|
18
|
+
# `:sendmail` [::Mail::Sendmail]
|
19
|
+
# : Settings used only by this method:
|
20
|
+
# : `sendmail`, `sendmail_args`
|
21
|
+
#
|
22
|
+
# `:exim` [::Mail::Exim]
|
23
|
+
# : Settings used only by this method:
|
24
|
+
# : `exim`, `exim_args`
|
25
|
+
#
|
26
|
+
# `:file` [::Mail::FileDelivery]
|
27
|
+
# : Settings used only by this method:
|
28
|
+
# : `mail_folder`
|
29
|
+
#
|
30
|
+
attr_accessor :delivery_method
|
31
|
+
|
32
|
+
##
|
33
|
+
# Sender and Receiver email addresses
|
34
|
+
# Examples:
|
35
|
+
# sender - my.email.address@gmail.com
|
36
|
+
# receiver - your.email.address@gmail.com
|
37
|
+
attr_accessor :from, :to
|
38
|
+
|
39
|
+
##
|
40
|
+
# The address to use
|
41
|
+
# Example: smtp.gmail.com
|
42
|
+
attr_accessor :address
|
43
|
+
|
44
|
+
##
|
45
|
+
# The port to connect to
|
46
|
+
# Example: 587
|
47
|
+
attr_accessor :port
|
48
|
+
|
49
|
+
##
|
50
|
+
# Your domain (if applicable)
|
51
|
+
# Example: mydomain.com
|
52
|
+
attr_accessor :domain
|
53
|
+
|
54
|
+
##
|
55
|
+
# Username and Password (sender email's credentials)
|
56
|
+
# Examples:
|
57
|
+
# user_name - meskyanichi
|
58
|
+
# password - my_secret_password
|
59
|
+
attr_accessor :user_name, :password
|
60
|
+
|
61
|
+
##
|
62
|
+
# Authentication type
|
63
|
+
# Example: plain
|
64
|
+
attr_accessor :authentication
|
65
|
+
|
66
|
+
##
|
67
|
+
# Automatically set TLS
|
68
|
+
# Example: true
|
69
|
+
attr_accessor :enable_starttls_auto
|
70
|
+
|
71
|
+
##
|
72
|
+
# OpenSSL Verify Mode
|
73
|
+
# Example: none - Only use this option for a self-signed and/or wildcard certificate
|
74
|
+
attr_accessor :openssl_verify_mode
|
75
|
+
|
76
|
+
##
|
77
|
+
# When using the `:sendmail` `delivery_method` option,
|
78
|
+
# this may be used to specify the absolute path to `sendmail` (if needed)
|
79
|
+
# Example: '/usr/sbin/sendmail'
|
80
|
+
attr_accessor :sendmail
|
81
|
+
|
82
|
+
##
|
83
|
+
# Optional arguments to pass to `sendmail`
|
84
|
+
# Note that this will override the defaults set by the Mail gem (currently: '-i -t')
|
85
|
+
# So, if set here, be sure to set all the arguments you require.
|
86
|
+
# Example: '-i -t -X/tmp/traffic.log'
|
87
|
+
attr_accessor :sendmail_args
|
88
|
+
|
89
|
+
##
|
90
|
+
# When using the `:exim` `delivery_method` option,
|
91
|
+
# this may be used to specify the absolute path to `exim` (if needed)
|
92
|
+
# Example: '/usr/sbin/exim'
|
93
|
+
attr_accessor :exim
|
94
|
+
|
95
|
+
##
|
96
|
+
# Optional arguments to pass to `exim`
|
97
|
+
# Note that this will override the defaults set by the Mail gem (currently: '-i -t')
|
98
|
+
# So, if set here, be sure to set all the arguments you require.
|
99
|
+
# Example: '-i -t -X/tmp/traffic.log'
|
100
|
+
attr_accessor :exim_args
|
101
|
+
|
102
|
+
##
|
103
|
+
# Folder where mail will be kept when using the `:file` `delivery_method` option.
|
104
|
+
# Default location is '$HOME/backup-mails'
|
105
|
+
# Example: '/tmp/test-mails'
|
106
|
+
attr_accessor :mail_folder
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Checkup
|
4
|
+
# Small dependency loader, so we don't have to require all possible gems in the Gemfile
|
5
|
+
class Dependency
|
6
|
+
def self.all
|
7
|
+
@all ||= {
|
8
|
+
'mail' => {
|
9
|
+
:require => 'mail',
|
10
|
+
:version => '>= 2.4.0',
|
11
|
+
:for => 'Sending Emails (Mail Notifier)'
|
12
|
+
},
|
13
|
+
'httparty' => {
|
14
|
+
:require => 'httparty',
|
15
|
+
:version => '>= 0',
|
16
|
+
:for => 'Http up check'
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.load (name)
|
22
|
+
begin
|
23
|
+
gem(name, all[name][:version])
|
24
|
+
require(all[name][:require])
|
25
|
+
rescue LoadError
|
26
|
+
Logger.error Errors::Dependency::LoadError.new(<<-EOS)
|
27
|
+
Dependency missing
|
28
|
+
Dependency required for:
|
29
|
+
#{all[name][:for]}
|
30
|
+
To install the gem, issue the following command:
|
31
|
+
> gem install #{name} -v '#{all[name][:version]}'
|
32
|
+
Please try again after installing the missing dependency.
|
33
|
+
EOS
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Checkup
|
2
|
+
# when included, automatically creates new Exceptions depending on the Const passed in
|
3
|
+
module ErrorsHelper
|
4
|
+
def const_missing(const)
|
5
|
+
if const.to_s.end_with?('Error')
|
6
|
+
module_eval("class #{const} < Checkup::Errors::Error; end")
|
7
|
+
else
|
8
|
+
module_eval("module #{const}; extend Checkup::ErrorsHelper; end")
|
9
|
+
end
|
10
|
+
const_get(const)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Errors
|
15
|
+
extend ErrorsHelper
|
16
|
+
|
17
|
+
class Error < StandardError
|
18
|
+
|
19
|
+
def self.wrap(orig_err, msg = nil)
|
20
|
+
new(msg, orig_err)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(msg = nil, orig_err = nil)
|
24
|
+
super(msg)
|
25
|
+
set_backtrace(orig_err.backtrace) if @orig_err = orig_err
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
return @to_s if @to_s
|
30
|
+
orig_to_s = super()
|
31
|
+
|
32
|
+
if orig_to_s == self.class.to_s
|
33
|
+
msg = orig_err_msg ?
|
34
|
+
"#{orig_err_class}: #{orig_err_msg}" : orig_err_class
|
35
|
+
else
|
36
|
+
msg = format_msg(orig_to_s)
|
37
|
+
msg << "\n Reason: #{orig_err_class}" + (orig_err_msg ?
|
38
|
+
"\n #{orig_err_msg}" : ' (no message given)') if @orig_err
|
39
|
+
end
|
40
|
+
|
41
|
+
@to_s = msg ? msg_prefix + msg : class_name
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def msg_prefix
|
47
|
+
@msg_prefix ||= class_name + ': '
|
48
|
+
end
|
49
|
+
|
50
|
+
def orig_msg
|
51
|
+
@orig_msg ||= to_s.sub(msg_prefix, '')
|
52
|
+
end
|
53
|
+
|
54
|
+
def class_name
|
55
|
+
@class_name ||= self.class.to_s.sub('Checkup::Errors::', '')
|
56
|
+
end
|
57
|
+
|
58
|
+
def orig_err_class
|
59
|
+
return unless @orig_err
|
60
|
+
|
61
|
+
@orig_err_class ||= @orig_err.is_a?(Errors::Error) ?
|
62
|
+
@orig_err.send(:class_name) : @orig_err.class.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
def orig_err_msg
|
66
|
+
return unless @orig_err
|
67
|
+
return @orig_err_msg unless @orig_err_msg.nil?
|
68
|
+
|
69
|
+
msg = @orig_err.is_a?(Errors::Error) ?
|
70
|
+
@orig_err.send(:orig_msg) : @orig_err.to_s
|
71
|
+
@orig_err_msg = (msg == orig_err_class) ?
|
72
|
+
false : format_msg(msg)
|
73
|
+
end
|
74
|
+
|
75
|
+
def format_msg(msg)
|
76
|
+
msg.gsub(/^ */, ' ').strip
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Checkup
|
4
|
+
module Logger
|
5
|
+
class << self
|
6
|
+
|
7
|
+
attr_accessor :quiet
|
8
|
+
|
9
|
+
##
|
10
|
+
# Outputs a messages to the console and writes it to the backup.log
|
11
|
+
def message(string)
|
12
|
+
to_console loggify(string, :message, :green)
|
13
|
+
to_file loggify(string, :message)
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Outputs an error to the console and writes it to the backup.log
|
18
|
+
# Called when an Exception has caused the backup process to abort.
|
19
|
+
def error(string)
|
20
|
+
@has_errors = true
|
21
|
+
to_console loggify(string, :error, :red), true
|
22
|
+
to_file loggify(string, :error)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Outputs a notice to the console and writes it to the backup.log
|
27
|
+
# Sets #has_warnings? true so :on_warning notifications will be sent
|
28
|
+
def warn(string)
|
29
|
+
@has_warnings = true
|
30
|
+
to_console loggify(string, :warning, :yellow), true
|
31
|
+
to_file loggify(string, :warning)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Outputs the data as if it were a regular 'puts' command,
|
35
|
+
# but also logs it to the backup.log
|
36
|
+
def normal(string)
|
37
|
+
to_console loggify(string)
|
38
|
+
to_file loggify(string)
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Silently logs data to the log file
|
43
|
+
def silent(string)
|
44
|
+
to_file loggify(string, :silent)
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Returns an Array of all messages written to the log file for this session
|
49
|
+
def messages
|
50
|
+
@messages ||= []
|
51
|
+
end
|
52
|
+
|
53
|
+
def has_errors?
|
54
|
+
@has_errors ||= false
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Returns true if any warnings have been issued
|
59
|
+
def has_warnings?
|
60
|
+
@has_warnings ||= false
|
61
|
+
end
|
62
|
+
|
63
|
+
def clear!
|
64
|
+
messages.clear
|
65
|
+
@has_warnings = false
|
66
|
+
end
|
67
|
+
|
68
|
+
def truncate!(max_bytes = 500_000)
|
69
|
+
log_file = File.join(Config.log_path, 'checkup.log')
|
70
|
+
return unless File.exist?(log_file)
|
71
|
+
|
72
|
+
if File.stat(log_file).size > max_bytes
|
73
|
+
FileUtils.mv(log_file, log_file + '~')
|
74
|
+
File.open(log_file + '~', 'r') do |io_in|
|
75
|
+
File.open(log_file, 'w') do |io_out|
|
76
|
+
io_in.seek(-max_bytes, IO::SEEK_END) && io_in.gets
|
77
|
+
while line = io_in.gets
|
78
|
+
io_out.puts line
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
FileUtils.rm_f(log_file + '~')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
##
|
89
|
+
# Returns the time in [YYYY/MM/DD HH:MM:SS] format
|
90
|
+
def time
|
91
|
+
Time.now.strftime("%Y/%m/%d %H:%M:%S")
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Receives a String, or an Object that responds to #to_s (e.g. an
|
96
|
+
# Exception), from one of the messaging methods and converts it into an
|
97
|
+
# Array of Strings, split on newline separators. Each line is then
|
98
|
+
# formatted into a log format based on the given options, and the Array
|
99
|
+
# returned to be passed to to_console() and/or to_file().
|
100
|
+
def loggify(string, type = false, color = false)
|
101
|
+
lines = string.to_s.split("\n")
|
102
|
+
if type
|
103
|
+
type = send(color, type) if color
|
104
|
+
time_now = time
|
105
|
+
lines.map {|line| "[#{time_now}][#{type}] #{line}" }
|
106
|
+
else
|
107
|
+
lines
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# Receives an Array of Strings to be written to the console.
|
113
|
+
def to_console(lines, stderr = false)
|
114
|
+
return if quiet
|
115
|
+
lines.each {|line| stderr ? Kernel.warn(line) : puts(line) }
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Receives an Array of Strings to be written to the log file.
|
120
|
+
def to_file(lines)
|
121
|
+
# File.open(File.join(Config.log_path, 'checkup.log'), 'a') do |file|
|
122
|
+
# lines.each {|line| file.puts line }
|
123
|
+
# end
|
124
|
+
# messages.push(*lines)
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# Invokes the #colorize method with the provided string
|
129
|
+
# and the color code "32" (for green)
|
130
|
+
def green(string)
|
131
|
+
colorize(string, 32)
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# Invokes the #colorize method with the provided string
|
136
|
+
# and the color code "33" (for yellow)
|
137
|
+
def yellow(string)
|
138
|
+
colorize(string, 33)
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# Invokes the #colorize method the with provided string
|
143
|
+
# and the color code "31" (for red)
|
144
|
+
def red(string)
|
145
|
+
colorize(string, 31)
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Wraps the provided string in colorizing tags to provide
|
150
|
+
# easier to view output to the client
|
151
|
+
def colorize(string, code)
|
152
|
+
"\e[#{code}m#{string}\e[0m"
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Checkup
|
2
|
+
class Model
|
3
|
+
class << self
|
4
|
+
def all
|
5
|
+
@all ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
def find(trigger)
|
9
|
+
trigger = trigger.to_s
|
10
|
+
all.each do |model|
|
11
|
+
return model if model.trigger == trigger
|
12
|
+
end
|
13
|
+
raise Errors::Model::MissingTriggerError,
|
14
|
+
"Could not find trigger '#{trigger}'."
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_matching(trigger)
|
18
|
+
regex = /^#{ trigger.to_s.gsub('*', '(.*)') }$/
|
19
|
+
all.select {|model| regex =~ model.trigger }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :trigger
|
24
|
+
attr_reader :description
|
25
|
+
|
26
|
+
|
27
|
+
def initialize(trigger, description, &block)
|
28
|
+
@trigger = trigger.to_s
|
29
|
+
@description = description.to_s
|
30
|
+
@started_at = Time.now
|
31
|
+
|
32
|
+
@services = []
|
33
|
+
@notifiers = []
|
34
|
+
|
35
|
+
instance_eval(&block) if block_given?
|
36
|
+
Model.all << self
|
37
|
+
end
|
38
|
+
|
39
|
+
def service(name, &block)
|
40
|
+
@services << get_class_from_scope(Service, name).new(self, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def notify_with(name, &block)
|
44
|
+
@notifiers << get_class_from_scope(Notifier, name).new(self, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def perform!
|
48
|
+
log!(:started)
|
49
|
+
|
50
|
+
|
51
|
+
@services.each do |service|
|
52
|
+
service_result = true
|
53
|
+
begin
|
54
|
+
Logger.message "Starting service #{service.identifier}"
|
55
|
+
service_result &&= service.perform!
|
56
|
+
rescue StandardError => e
|
57
|
+
service_result = false
|
58
|
+
self.notify! :error, service, "#{service.identifier}: #{e.message}"
|
59
|
+
Logger.error e.message
|
60
|
+
end
|
61
|
+
|
62
|
+
message = "Finished service #{service.identifier}"
|
63
|
+
|
64
|
+
if !service_result
|
65
|
+
message += " (with errors)"
|
66
|
+
Logger.error message
|
67
|
+
else
|
68
|
+
Logger.message message
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
log!(:finished)
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_class_from_scope(scope, name)
|
77
|
+
klass = scope
|
78
|
+
name = name.to_s.sub(/^Checkup::Config::/, '')
|
79
|
+
name.split('::').each do |chunk|
|
80
|
+
klass = klass.const_get(chunk)
|
81
|
+
end
|
82
|
+
klass
|
83
|
+
end
|
84
|
+
|
85
|
+
def log!(action)
|
86
|
+
case action
|
87
|
+
when :started
|
88
|
+
Logger.message "Started model '(#{trigger})'!\n" +
|
89
|
+
"[ checkup #{ Version.current } : #{ RUBY_DESCRIPTION } ]"
|
90
|
+
|
91
|
+
when :finished
|
92
|
+
msg = "Finished '(#{ trigger })' " +
|
93
|
+
"Completed %s in #{ elapsed_time }"
|
94
|
+
if Logger.has_warnings?
|
95
|
+
Logger.warn msg % 'Successfully (with Warnings)'
|
96
|
+
elsif Logger.has_errors?
|
97
|
+
Logger.error msg % 'with errors'
|
98
|
+
else
|
99
|
+
Logger.message msg % 'Successfully'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def notify! (status, origin, message)
|
105
|
+
@notifiers.each do |notifier|
|
106
|
+
notifier.notify! status, origin, message
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def elapsed_time
|
111
|
+
duration = Time.now.to_i - @started_at.to_i
|
112
|
+
hours = duration / 3600
|
113
|
+
remainder = duration - (hours * 3600)
|
114
|
+
minutes = remainder / 60
|
115
|
+
seconds = remainder - (minutes * 60)
|
116
|
+
'%02d:%02d:%02d' % [hours, minutes, seconds]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Checkup
|
2
|
+
module Notifier
|
3
|
+
class Base
|
4
|
+
include Checkup::Configuration::Helpers
|
5
|
+
|
6
|
+
attr_accessor :on_success
|
7
|
+
alias :notify_on_success? :on_success
|
8
|
+
|
9
|
+
attr_accessor :on_warning
|
10
|
+
alias :notify_on_warning? :on_warning
|
11
|
+
|
12
|
+
attr_accessor :on_failure
|
13
|
+
alias :notify_on_failure? :on_failure
|
14
|
+
|
15
|
+
def initialize(model)
|
16
|
+
@model = model
|
17
|
+
load_defaults!
|
18
|
+
|
19
|
+
yield self
|
20
|
+
end
|
21
|
+
|
22
|
+
def perform!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
Checkup::Dependency.load('mail')
|
4
|
+
|
5
|
+
module Checkup
|
6
|
+
module Notifier
|
7
|
+
class Mail < Base
|
8
|
+
|
9
|
+
##
|
10
|
+
# Mail delivery method to be used by the Mail gem.
|
11
|
+
# Supported methods:
|
12
|
+
#
|
13
|
+
# `:smtp` [::Mail::SMTP] (default)
|
14
|
+
# : Settings used only by this method:
|
15
|
+
# : `address`, `port`, `domain`, `user_name`, `password`
|
16
|
+
# : `authentication`, `enable_starttls_auto`, `openssl_verify_mode`
|
17
|
+
#
|
18
|
+
# `:sendmail` [::Mail::Sendmail]
|
19
|
+
# : Settings used only by this method:
|
20
|
+
# : `sendmail`, `sendmail_args`
|
21
|
+
#
|
22
|
+
# `:exim` [::Mail::Exim]
|
23
|
+
# : Settings used only by this method:
|
24
|
+
# : `exim`, `exim_args`
|
25
|
+
#
|
26
|
+
# `:file` [::Mail::FileDelivery]
|
27
|
+
# : Settings used only by this method:
|
28
|
+
# : `mail_folder`
|
29
|
+
#
|
30
|
+
attr_accessor :delivery_method
|
31
|
+
|
32
|
+
##
|
33
|
+
# Sender and Receiver email addresses
|
34
|
+
# Examples:
|
35
|
+
# sender - my.email.address@gmail.com
|
36
|
+
# receiver - your.email.address@gmail.com
|
37
|
+
attr_accessor :from, :to
|
38
|
+
|
39
|
+
##
|
40
|
+
# The address to use
|
41
|
+
# Example: smtp.gmail.com
|
42
|
+
attr_accessor :address
|
43
|
+
|
44
|
+
##
|
45
|
+
# The port to connect to
|
46
|
+
# Example: 587
|
47
|
+
attr_accessor :port
|
48
|
+
|
49
|
+
##
|
50
|
+
# Your domain (if applicable)
|
51
|
+
# Example: mydomain.com
|
52
|
+
attr_accessor :domain
|
53
|
+
|
54
|
+
##
|
55
|
+
# Username and Password (sender email's credentials)
|
56
|
+
# Examples:
|
57
|
+
# user_name - meskyanichi
|
58
|
+
# password - my_secret_password
|
59
|
+
attr_accessor :user_name, :password
|
60
|
+
|
61
|
+
##
|
62
|
+
# Authentication type
|
63
|
+
# Example: plain
|
64
|
+
attr_accessor :authentication
|
65
|
+
|
66
|
+
##
|
67
|
+
# Automatically set TLS
|
68
|
+
# Example: true
|
69
|
+
attr_accessor :enable_starttls_auto
|
70
|
+
|
71
|
+
##
|
72
|
+
# OpenSSL Verify Mode
|
73
|
+
# Example: none - Only use this option for a self-signed and/or wildcard certificate
|
74
|
+
attr_accessor :openssl_verify_mode
|
75
|
+
|
76
|
+
##
|
77
|
+
# When using the `:sendmail` `delivery_method` option,
|
78
|
+
# this may be used to specify the absolute path to `sendmail` (if needed)
|
79
|
+
# Example: '/usr/sbin/sendmail'
|
80
|
+
attr_accessor :sendmail
|
81
|
+
|
82
|
+
##
|
83
|
+
# Optional arguments to pass to `sendmail`
|
84
|
+
# Note that this will override the defaults set by the Mail gem (currently: '-i -t')
|
85
|
+
# So, if set here, be sure to set all the arguments you require.
|
86
|
+
# Example: '-i -t -X/tmp/traffic.log'
|
87
|
+
attr_accessor :sendmail_args
|
88
|
+
|
89
|
+
##
|
90
|
+
# When using the `:exim` `delivery_method` option,
|
91
|
+
# this may be used to specify the absolute path to `exim` (if needed)
|
92
|
+
# Example: '/usr/sbin/exim'
|
93
|
+
attr_accessor :exim
|
94
|
+
|
95
|
+
##
|
96
|
+
# Optional arguments to pass to `exim`
|
97
|
+
# Note that this will override the defaults set by the Mail gem (currently: '-i -t')
|
98
|
+
# So, if set here, be sure to set all the arguments you require.
|
99
|
+
# Example: '-i -t -X/tmp/traffic.log'
|
100
|
+
attr_accessor :exim_args
|
101
|
+
|
102
|
+
##
|
103
|
+
# Folder where mail will be kept when using the `:file` `delivery_method` option.
|
104
|
+
# Default location is '$HOME/Backup/emails'
|
105
|
+
# Example: '/tmp/test-mails'
|
106
|
+
attr_accessor :mail_folder
|
107
|
+
|
108
|
+
def initialize(model, &block)
|
109
|
+
super(model)
|
110
|
+
|
111
|
+
instance_eval(&block) if block_given?
|
112
|
+
end
|
113
|
+
|
114
|
+
def notify!(status, origin, message)
|
115
|
+
email = new_email
|
116
|
+
email.subject = "[Checkup::#{status}] #{@model.trigger}"
|
117
|
+
template = Checkup::Template.new ({ :origin => origin, :message => message })
|
118
|
+
email.body = template.result('notifier/mail/%s.erb' % status.to_s)
|
119
|
+
|
120
|
+
email.deliver!
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
##
|
126
|
+
# Configures the Mail gem by setting the defaults.
|
127
|
+
# Creates and returns a new email, based on the @delivery_method used.
|
128
|
+
def new_email
|
129
|
+
method = %w{ smtp sendmail exim file test }.
|
130
|
+
index(@delivery_method.to_s) ? @delivery_method.to_s : 'smtp'
|
131
|
+
|
132
|
+
options =
|
133
|
+
case method
|
134
|
+
when 'smtp'
|
135
|
+
{ :address => @address,
|
136
|
+
:port => @port,
|
137
|
+
:domain => @domain,
|
138
|
+
:user_name => @user_name,
|
139
|
+
:password => @password,
|
140
|
+
:authentication => @authentication,
|
141
|
+
:enable_starttls_auto => @enable_starttls_auto,
|
142
|
+
:openssl_verify_mode => @openssl_verify_mode }
|
143
|
+
when 'sendmail'
|
144
|
+
opts = {}
|
145
|
+
opts.merge!(:location => File.expand_path(@sendmail)) if @sendmail
|
146
|
+
opts.merge!(:arguments => @sendmail_args) if @sendmail_args
|
147
|
+
opts
|
148
|
+
when 'exim'
|
149
|
+
opts = {}
|
150
|
+
opts.merge!(:location => File.expand_path(@exim)) if @exim
|
151
|
+
opts.merge!(:arguments => @exim_args) if @exim_args
|
152
|
+
opts
|
153
|
+
when 'file'
|
154
|
+
@mail_folder ||= File.join(Config.root_path, 'emails')
|
155
|
+
{ :location => File.expand_path(@mail_folder) }
|
156
|
+
when 'test' then {}
|
157
|
+
end
|
158
|
+
|
159
|
+
::Mail.defaults do
|
160
|
+
delivery_method method.to_sym, options
|
161
|
+
end
|
162
|
+
|
163
|
+
email = ::Mail.new
|
164
|
+
email.to = @to
|
165
|
+
email.from = @from
|
166
|
+
email
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Checkup
|
4
|
+
module Service
|
5
|
+
class Base
|
6
|
+
include Checkup::Configuration::Helpers
|
7
|
+
|
8
|
+
def initialize(model)
|
9
|
+
@model = model
|
10
|
+
load_defaults!
|
11
|
+
|
12
|
+
yield self
|
13
|
+
end
|
14
|
+
|
15
|
+
def perform!
|
16
|
+
end
|
17
|
+
|
18
|
+
def identifier
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
Checkup::Dependency.load('httparty')
|
4
|
+
|
5
|
+
module Checkup
|
6
|
+
module Service
|
7
|
+
class Http < Base
|
8
|
+
attr_accessor :url
|
9
|
+
attr_accessor :method
|
10
|
+
attr_accessor :expected_code
|
11
|
+
attr_accessor :expected_response
|
12
|
+
|
13
|
+
def perform!
|
14
|
+
super
|
15
|
+
|
16
|
+
response = ::HTTParty.send(self.method.to_sym, self.url)
|
17
|
+
|
18
|
+
Logger.message "Got #{response.code} from #{self.url}"
|
19
|
+
|
20
|
+
result = response.code == self.expected_code
|
21
|
+
|
22
|
+
if !result
|
23
|
+
raise Checkup::Errors::Service::Http::AssertError,
|
24
|
+
"Expected code #{self.expected_code}, got #{response.code}"
|
25
|
+
end
|
26
|
+
|
27
|
+
if self.expected_response.is_a? Regexp
|
28
|
+
result &&= !!self.expected_response.match(response.body)
|
29
|
+
if !result
|
30
|
+
raise Checkup::Errors::Service::Http::RegexpError,
|
31
|
+
"Expected match for #{self.expected_response.to_s}"
|
32
|
+
end
|
33
|
+
else
|
34
|
+
result &&= self.expected_response == response.body
|
35
|
+
raise Checkup::Errors::Service::Http::AssertError,
|
36
|
+
"Expected response #{self.expected_response}"
|
37
|
+
end
|
38
|
+
|
39
|
+
return result
|
40
|
+
end
|
41
|
+
|
42
|
+
def identifier
|
43
|
+
return "#{self.method} #{self.url}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Checkup
|
4
|
+
class Template
|
5
|
+
|
6
|
+
attr_accessor :binding
|
7
|
+
|
8
|
+
def initialize(object = nil)
|
9
|
+
if object.is_a?(Binding)
|
10
|
+
@binding = object
|
11
|
+
elsif object.is_a?(Hash)
|
12
|
+
@binding = Checkup::Binder.new(object).get_binding
|
13
|
+
else
|
14
|
+
@binding = nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def render(file)
|
19
|
+
puts result(file)
|
20
|
+
end
|
21
|
+
|
22
|
+
def result(file)
|
23
|
+
ERB.new(file_contents(file), nil, '<>').result(binding)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def file_contents(file)
|
29
|
+
File.read(File.join(Checkup::TEMPLATE_PATH, file))
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Checkup
|
4
|
+
class Version
|
5
|
+
|
6
|
+
##
|
7
|
+
# Change the MAJOR, MINOR and PATCH constants below
|
8
|
+
# to adjust the version of the Backup gem
|
9
|
+
#
|
10
|
+
# MAJOR:
|
11
|
+
# Defines the major version
|
12
|
+
# MINOR:
|
13
|
+
# Defines the minor version
|
14
|
+
# PATCH:
|
15
|
+
# Defines the patch version
|
16
|
+
MAJOR, MINOR, PATCH = 0, 0, 2
|
17
|
+
|
18
|
+
##
|
19
|
+
# Returns the major version ( big release based off of multiple minor releases )
|
20
|
+
def self.major
|
21
|
+
MAJOR
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Returns the minor version ( small release based off of multiple patches )
|
26
|
+
def self.minor
|
27
|
+
MINOR
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Returns the patch version ( updates, features and (crucial) bug fixes )
|
32
|
+
def self.patch
|
33
|
+
PATCH
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Returns the current version of the Backup gem ( qualified for the gemspec )
|
38
|
+
def self.current
|
39
|
+
"#{major}.#{minor}.#{patch}"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: checkup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Heiko Moeller
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.14.6
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.14.6
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: httparty
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description:
|
47
|
+
email: femaref@googlemail.com
|
48
|
+
executables:
|
49
|
+
- checkup
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- Gemfile.lock
|
56
|
+
- bin/checkup
|
57
|
+
- checkup.gemspec
|
58
|
+
- lib/checkup.rb
|
59
|
+
- lib/checkup/binder.rb
|
60
|
+
- lib/checkup/cli/utility.rb
|
61
|
+
- lib/checkup/config.rb
|
62
|
+
- lib/checkup/configuration/base.rb
|
63
|
+
- lib/checkup/configuration/helpers.rb
|
64
|
+
- lib/checkup/configuration/notifier/base.rb
|
65
|
+
- lib/checkup/configuration/notifier/mail.rb
|
66
|
+
- lib/checkup/configuration/service/base.rb
|
67
|
+
- lib/checkup/configuration/service/http.rb
|
68
|
+
- lib/checkup/dependency.rb
|
69
|
+
- lib/checkup/errors.rb
|
70
|
+
- lib/checkup/logger.rb
|
71
|
+
- lib/checkup/model.rb
|
72
|
+
- lib/checkup/notifier/base.rb
|
73
|
+
- lib/checkup/notifier/mail.rb
|
74
|
+
- lib/checkup/service/base.rb
|
75
|
+
- lib/checkup/service/http.rb
|
76
|
+
- lib/checkup/template.rb
|
77
|
+
- lib/checkup/version.rb
|
78
|
+
- templates/notifier/mail/error.erb
|
79
|
+
homepage: http://rubygems.org/gems/checkup
|
80
|
+
licenses: []
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 1.8.23
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: ''
|
103
|
+
test_files: []
|