perus 0.1.0
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/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +16 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/perus-pinger +23 -0
- data/exe/perus-server +23 -0
- data/lib/perus/options.rb +30 -0
- data/lib/perus/pinger/chrome_command.rb +54 -0
- data/lib/perus/pinger/command.rb +123 -0
- data/lib/perus/pinger/commands/chrome_execute.rb +26 -0
- data/lib/perus/pinger/commands/chrome_navigate.rb +25 -0
- data/lib/perus/pinger/commands/chrome_reload.rb +29 -0
- data/lib/perus/pinger/commands/kill_process.rb +13 -0
- data/lib/perus/pinger/commands/remove_path.rb +15 -0
- data/lib/perus/pinger/commands/replace.rb +18 -0
- data/lib/perus/pinger/commands/restart.rb +9 -0
- data/lib/perus/pinger/commands/script.rb +59 -0
- data/lib/perus/pinger/commands/upgrade.rb +16 -0
- data/lib/perus/pinger/commands/upload.rb +15 -0
- data/lib/perus/pinger/metrics/chrome.rb +33 -0
- data/lib/perus/pinger/metrics/cpu.rb +17 -0
- data/lib/perus/pinger/metrics/hd.rb +14 -0
- data/lib/perus/pinger/metrics/mem.rb +11 -0
- data/lib/perus/pinger/metrics/process.rb +27 -0
- data/lib/perus/pinger/metrics/screenshot.rb +36 -0
- data/lib/perus/pinger/metrics/temp.rb +18 -0
- data/lib/perus/pinger/metrics/uptime.rb +10 -0
- data/lib/perus/pinger/metrics/value.rb +18 -0
- data/lib/perus/pinger/pinger.rb +218 -0
- data/lib/perus/pinger.rb +38 -0
- data/lib/perus/server/admin.rb +83 -0
- data/lib/perus/server/app.rb +304 -0
- data/lib/perus/server/db.rb +29 -0
- data/lib/perus/server/form.rb +73 -0
- data/lib/perus/server/helpers.rb +36 -0
- data/lib/perus/server/migrations/001_create_systems.rb +20 -0
- data/lib/perus/server/migrations/002_create_configs.rb +12 -0
- data/lib/perus/server/migrations/003_create_values.rb +23 -0
- data/lib/perus/server/migrations/004_create_groups.rb +12 -0
- data/lib/perus/server/migrations/005_create_errors.rb +15 -0
- data/lib/perus/server/migrations/006_create_alerts.rb +14 -0
- data/lib/perus/server/migrations/007_create_actions.rb +18 -0
- data/lib/perus/server/migrations/008_create_metrics.rb +16 -0
- data/lib/perus/server/migrations/009_create_command_config.rb +13 -0
- data/lib/perus/server/migrations/010_create_scripts.rb +13 -0
- data/lib/perus/server/migrations/011_create_script_commands.rb +14 -0
- data/lib/perus/server/migrations/012_create_config_metrics.rb +14 -0
- data/lib/perus/server/models/action.rb +71 -0
- data/lib/perus/server/models/alert.rb +9 -0
- data/lib/perus/server/models/command_config.rb +58 -0
- data/lib/perus/server/models/config.rb +30 -0
- data/lib/perus/server/models/config_metric.rb +15 -0
- data/lib/perus/server/models/error.rb +5 -0
- data/lib/perus/server/models/group.rb +12 -0
- data/lib/perus/server/models/metric.rb +53 -0
- data/lib/perus/server/models/script.rb +39 -0
- data/lib/perus/server/models/script_command.rb +15 -0
- data/lib/perus/server/models/system.rb +160 -0
- data/lib/perus/server/models/value.rb +11 -0
- data/lib/perus/server/public/css/reset.css +102 -0
- data/lib/perus/server/public/css/style.css +461 -0
- data/lib/perus/server/public/fonts/opensans/OpenSans-Italic.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/OpenSans-Light.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/OpenSans-LightItalic.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/OpenSans-Regular.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/OpenSans-Semibold.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/OpenSans-SemiboldItalic.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-light-webfont.eot +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-light-webfont.svg +1824 -0
- data/lib/perus/server/public/fonts/opensans/opensans-light-webfont.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-light-webfont.woff +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-light-webfont.woff2 +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-regular-webfont.eot +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-regular-webfont.svg +1824 -0
- data/lib/perus/server/public/fonts/opensans/opensans-regular-webfont.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-regular-webfont.woff +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-regular-webfont.woff2 +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-semibold-webfont.eot +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-semibold-webfont.svg +1824 -0
- data/lib/perus/server/public/fonts/opensans/opensans-semibold-webfont.ttf +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-semibold-webfont.woff +0 -0
- data/lib/perus/server/public/fonts/opensans/opensans-semibold-webfont.woff2 +0 -0
- data/lib/perus/server/public/fonts/opensans/stylesheet.css +35 -0
- data/lib/perus/server/public/js/dygraph-combined.js +6 -0
- data/lib/perus/server/public/js/jquery.js +4 -0
- data/lib/perus/server/server.rb +32 -0
- data/lib/perus/server/views/admin/edit.erb +9 -0
- data/lib/perus/server/views/admin/index.erb +18 -0
- data/lib/perus/server/views/admin/new.erb +5 -0
- data/lib/perus/server/views/alerts/form.erb +3 -0
- data/lib/perus/server/views/command_config.erb +37 -0
- data/lib/perus/server/views/configs/edit.erb +36 -0
- data/lib/perus/server/views/configs/form.erb +1 -0
- data/lib/perus/server/views/errors.erb +6 -0
- data/lib/perus/server/views/groups/form.erb +1 -0
- data/lib/perus/server/views/index.erb +21 -0
- data/lib/perus/server/views/layout.erb +44 -0
- data/lib/perus/server/views/scripts/edit.erb +36 -0
- data/lib/perus/server/views/scripts/form.erb +2 -0
- data/lib/perus/server/views/system.erb +202 -0
- data/lib/perus/server/views/systems/form.erb +6 -0
- data/lib/perus/server/views/systems.erb +17 -0
- data/lib/perus/server.rb +24 -0
- data/lib/perus/version.rb +3 -0
- data/lib/perus.rb +10 -0
- data/perus.gemspec +36 -0
- metadata +354 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Perus::Pinger
|
|
2
|
+
class Mem < Command
|
|
3
|
+
description 'Measures overall RAM usage as a percentage on the client.'
|
|
4
|
+
metric!
|
|
5
|
+
|
|
6
|
+
def run
|
|
7
|
+
percent = `cat /proc/meminfo | awk '{if ($1=="MemTotal:") total = $2; if ($1 == "MemFree:") free = $2;} END {print (1 - (free / total))*100}'`
|
|
8
|
+
{mem_all: percent.to_f}
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Perus::Pinger
|
|
2
|
+
class Process < Command
|
|
3
|
+
description 'Measures percentage of RAM and CPU used by the process
|
|
4
|
+
specified by "process_path". The results are returned to
|
|
5
|
+
the server under 2 metrics called "cpu_{name}" and
|
|
6
|
+
"mem_{name}". Valid values for "process_path" are
|
|
7
|
+
contained in the pinger config file.'
|
|
8
|
+
option :process_path, restricted: true
|
|
9
|
+
option :name
|
|
10
|
+
metric!
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
path = options.process_path.gsub("/", "\\\\\\/")
|
|
14
|
+
cpu, mem = `ps aux | awk '/#{path}/ {cpu += $3; mem += $4} END {print cpu, mem;}'`.split
|
|
15
|
+
if `uname -s`.strip == 'Darwin'
|
|
16
|
+
core_count = `sysctl -n hw.ncpu`
|
|
17
|
+
else
|
|
18
|
+
core_count = `cat /proc/cpuinfo | grep processor | awk '{count += 1} END {print count}'`
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
{
|
|
22
|
+
"cpu_#{options.name}" => cpu.to_f / core_count.to_i,
|
|
23
|
+
"mem_#{options.name}" => mem.to_f
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Perus::Pinger
|
|
2
|
+
class Screenshot < Command
|
|
3
|
+
description 'Takes a screenshot of the primary screen on the client and
|
|
4
|
+
uploads it. The screenshot is saved to "path" before being
|
|
5
|
+
uploaded. Valid values for "path" are contained in the
|
|
6
|
+
pinger config file.'
|
|
7
|
+
option :path, default: '/tmp/screenshot.jpg', restricted: true
|
|
8
|
+
option :resize, default: '20%'
|
|
9
|
+
metric!
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
if `uname -s`.strip == 'Darwin'
|
|
13
|
+
if options.resize[-1] != '%'
|
|
14
|
+
raise 'Non percent resize option unsupported by OS X currently'
|
|
15
|
+
else
|
|
16
|
+
percent = options.resize.to_f / 100
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
`screencapture -m -t jpg -x #{options.path}`
|
|
20
|
+
width = `sips -g pixelWidth #{options.path}`.match(/pixelWidth: (\d+)/)[1]
|
|
21
|
+
height = `sips -g pixelHeight #{options.path}`.match(/pixelHeight: (\d+)/)[1]
|
|
22
|
+
`sips -z #{height.to_i * percent} #{width.to_i * percent} #{options.path}`
|
|
23
|
+
else
|
|
24
|
+
`export DISPLAY=:0; import -window root -resize #{options.resize} #{options.path}`
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@screenshot_file = File.new(options.path)
|
|
28
|
+
{screenshot: @screenshot_file}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def cleanup
|
|
32
|
+
@screenshot_file.close unless @screenshot_file.closed?
|
|
33
|
+
File.delete(options.path)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Perus::Pinger
|
|
2
|
+
class Temp < Command
|
|
3
|
+
description 'Measures the temperature of "device" on the client. By
|
|
4
|
+
default, this will be a CPU.'
|
|
5
|
+
option :device, default: 'Physical id 0'
|
|
6
|
+
metric!
|
|
7
|
+
|
|
8
|
+
def run
|
|
9
|
+
if `uname -s`.strip == 'Darwin'
|
|
10
|
+
degrees = `istats cpu temp`.split[2].match(/([0-9\.]+)/)[0]
|
|
11
|
+
else
|
|
12
|
+
degrees = `sensors | grep "#{options.device}:"`.match(/#{options.device}:\s+(\S+)/)[1]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
{temp: degrees.to_f}
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Perus::Pinger
|
|
2
|
+
class Value < Command
|
|
3
|
+
description 'Searches the file specified by "path" with the regular
|
|
4
|
+
expression specified by "grep". Returns the resulting
|
|
5
|
+
string to the server under the metric called "name". Valid
|
|
6
|
+
values for "path" are contained in the pinger config file.'
|
|
7
|
+
option :path, restricted: true
|
|
8
|
+
option :grep
|
|
9
|
+
option :name
|
|
10
|
+
metric!
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
line = `cat #{options.path} | grep #{options.grep}`
|
|
14
|
+
value = line.match(Regexp.compile(options.match))[1]
|
|
15
|
+
{options.name => value}
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
require 'securerandom'
|
|
2
|
+
require 'rest-client'
|
|
3
|
+
require 'ostruct'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'uri'
|
|
6
|
+
|
|
7
|
+
DEFAULT_PINGER_OPTIONS = {
|
|
8
|
+
'__anonymous__' => {
|
|
9
|
+
'system_id' => 1,
|
|
10
|
+
'server' => 'http://127.0.0.1:3000/'
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
# restricted values
|
|
14
|
+
'Value' => {
|
|
15
|
+
'path' => []
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
'Screenshot' => {
|
|
19
|
+
'path' => []
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
'Process' => {
|
|
23
|
+
'process_path' => []
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
'Upload' => {
|
|
27
|
+
'path' => []
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
'Replace' => {
|
|
31
|
+
'path' => []
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
'RemovePath' => {
|
|
35
|
+
'path' => []
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
'KillProcess' => {
|
|
39
|
+
'process_name' => []
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module Perus::Pinger
|
|
44
|
+
class Pinger
|
|
45
|
+
def self.options
|
|
46
|
+
@options ||= Perus::Options.new
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def initialize(options_path = DEFAULT_PINGER_OPTIONS_PATH)
|
|
50
|
+
Pinger.options.load(options_path, DEFAULT_PINGER_OPTIONS)
|
|
51
|
+
|
|
52
|
+
# cache urls on initialisation since the urls depend on values known
|
|
53
|
+
# at startup and that won't change over the object lifetime
|
|
54
|
+
config_path = URI("/systems/#{Pinger.options.system_id}/config")
|
|
55
|
+
pinger_path = URI("/systems/#{Pinger.options.system_id}/ping")
|
|
56
|
+
server_uri = URI(Pinger.options.server)
|
|
57
|
+
|
|
58
|
+
@config_url = (server_uri + config_path).to_s
|
|
59
|
+
@pinger_url = (server_uri + pinger_path).to_s
|
|
60
|
+
|
|
61
|
+
@metrics = []
|
|
62
|
+
@metric_results = {}
|
|
63
|
+
@metric_errors = {}
|
|
64
|
+
|
|
65
|
+
@actions = []
|
|
66
|
+
@action_results = {}
|
|
67
|
+
@late_actions = []
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def run
|
|
71
|
+
load_config
|
|
72
|
+
run_metrics
|
|
73
|
+
run_actions
|
|
74
|
+
send_response
|
|
75
|
+
cleanup
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
#----------------------
|
|
79
|
+
# configuration
|
|
80
|
+
#----------------------
|
|
81
|
+
def load_config
|
|
82
|
+
# load the system config by requesting it from the perus server
|
|
83
|
+
json = JSON.parse(RestClient.get(@config_url))
|
|
84
|
+
json['metrics'] ||= []
|
|
85
|
+
json['actions'] ||= []
|
|
86
|
+
|
|
87
|
+
# load metric and command modules based on the config
|
|
88
|
+
json['metrics'].each do |config|
|
|
89
|
+
begin
|
|
90
|
+
if ::Perus::Pinger.const_defined?(config['type'])
|
|
91
|
+
metric = ::Perus::Pinger.const_get(config['type'])
|
|
92
|
+
@metric_errors[metric.name] ||= []
|
|
93
|
+
@metrics << metric.new(config['options'])
|
|
94
|
+
else
|
|
95
|
+
@metric_errors[config['type']] = e.inspect
|
|
96
|
+
end
|
|
97
|
+
rescue => e
|
|
98
|
+
@metric_errors[metric.name] << e.inspect
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
json['actions'].each do |config|
|
|
103
|
+
begin
|
|
104
|
+
command = ::Perus::Pinger.const_get(config['type'])
|
|
105
|
+
@actions << command.new(config['options'], config['id'])
|
|
106
|
+
rescue => e
|
|
107
|
+
if config['id']
|
|
108
|
+
@action_results[config['id']] = e.inspect
|
|
109
|
+
else
|
|
110
|
+
puts 'Error - action does not have an associated id'
|
|
111
|
+
p config
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
#----------------------
|
|
118
|
+
# run
|
|
119
|
+
#----------------------
|
|
120
|
+
def run_metrics
|
|
121
|
+
@metrics.each do |metric|
|
|
122
|
+
begin
|
|
123
|
+
result = metric.run
|
|
124
|
+
@metric_results.merge!(result)
|
|
125
|
+
rescue => e
|
|
126
|
+
@metric_errors[metric.class.name] << e.inspect
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def run_actions
|
|
132
|
+
@actions.each do |action|
|
|
133
|
+
begin
|
|
134
|
+
result = action.run
|
|
135
|
+
|
|
136
|
+
if result.instance_of?(Proc)
|
|
137
|
+
@late_actions << result
|
|
138
|
+
result = true
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
@action_results[action.id] = result
|
|
142
|
+
|
|
143
|
+
rescue => e
|
|
144
|
+
@action_results[action.id] = e.inspect
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
#----------------------
|
|
150
|
+
# response
|
|
151
|
+
#----------------------
|
|
152
|
+
def add_to_payload(payload, field, results)
|
|
153
|
+
results.each do |name, val|
|
|
154
|
+
next unless val.instance_of?(File)
|
|
155
|
+
uuid = SecureRandom.uuid
|
|
156
|
+
results[name] = {file: uuid}
|
|
157
|
+
payload[uuid] = val
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
payload[field] = JSON.dump(results)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def send_response
|
|
164
|
+
# prepare the response and replace file results with a reference
|
|
165
|
+
# to the uploaded file. files are sent as top level parameters in
|
|
166
|
+
# the payload, while metric and action results are sent as a json
|
|
167
|
+
# object with a reference to these files.
|
|
168
|
+
payload = {}
|
|
169
|
+
add_to_payload(payload, 'metrics', @metric_results)
|
|
170
|
+
add_to_payload(payload, 'actions', @action_results)
|
|
171
|
+
|
|
172
|
+
# metric_errors is created with a key for each metric type. most
|
|
173
|
+
# metrics should run without any errors, so remove these entries
|
|
174
|
+
# before adding errors to the payload.
|
|
175
|
+
@metric_errors.reject! {|metric, errors| errors.empty?}
|
|
176
|
+
add_to_payload(payload, 'metric_errors', @metric_errors)
|
|
177
|
+
|
|
178
|
+
begin
|
|
179
|
+
RestClient.post(@pinger_url, payload)
|
|
180
|
+
rescue => e
|
|
181
|
+
puts 'Ping failed with exception'
|
|
182
|
+
puts e.inspect
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
#----------------------
|
|
187
|
+
# cleanup
|
|
188
|
+
#----------------------
|
|
189
|
+
def cleanup
|
|
190
|
+
@metrics.each do |metric|
|
|
191
|
+
begin
|
|
192
|
+
metric.cleanup
|
|
193
|
+
rescue => e
|
|
194
|
+
puts 'Error running metric cleanup'
|
|
195
|
+
puts e.inspect
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
@actions.each do |action|
|
|
200
|
+
begin
|
|
201
|
+
action.cleanup
|
|
202
|
+
rescue => e
|
|
203
|
+
puts 'Error running action cleanup'
|
|
204
|
+
puts e.inspect
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
@late_actions.each do |code|
|
|
209
|
+
begin
|
|
210
|
+
code.call
|
|
211
|
+
rescue => e
|
|
212
|
+
puts 'Error running late action'
|
|
213
|
+
puts e.inspect
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
data/lib/perus/pinger.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Perus
|
|
2
|
+
module Pinger
|
|
3
|
+
Dir.chdir(__dir__) do
|
|
4
|
+
# commands
|
|
5
|
+
require './pinger/command'
|
|
6
|
+
require './pinger/chrome_command'
|
|
7
|
+
require './pinger/commands/chrome_execute'
|
|
8
|
+
require './pinger/commands/chrome_navigate'
|
|
9
|
+
require './pinger/commands/chrome_reload'
|
|
10
|
+
require './pinger/commands/kill_process'
|
|
11
|
+
require './pinger/commands/remove_path'
|
|
12
|
+
require './pinger/commands/replace'
|
|
13
|
+
require './pinger/commands/restart'
|
|
14
|
+
require './pinger/commands/upload'
|
|
15
|
+
require './pinger/commands/upgrade'
|
|
16
|
+
require './pinger/commands/script'
|
|
17
|
+
|
|
18
|
+
# metrics
|
|
19
|
+
require './pinger/metrics/chrome'
|
|
20
|
+
require './pinger/metrics/cpu'
|
|
21
|
+
require './pinger/metrics/hd'
|
|
22
|
+
require './pinger/metrics/mem'
|
|
23
|
+
require './pinger/metrics/process'
|
|
24
|
+
require './pinger/metrics/screenshot'
|
|
25
|
+
require './pinger/metrics/temp'
|
|
26
|
+
require './pinger/metrics/value'
|
|
27
|
+
require './pinger/metrics/uptime'
|
|
28
|
+
|
|
29
|
+
# pinger
|
|
30
|
+
require './pinger/pinger'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# options file
|
|
34
|
+
DEFAULT_PINGER_OPTIONS_PATH = '/etc/perus-pinger'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Pinger::Pinger.new.run if __FILE__ == $0
|
|
38
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module Perus::Server
|
|
2
|
+
module Admin
|
|
3
|
+
def admin(type, redirect_to_record = false)
|
|
4
|
+
plural = type.to_s.pluralize
|
|
5
|
+
singular = plural.singularize
|
|
6
|
+
title = singular.titleize
|
|
7
|
+
klass = title
|
|
8
|
+
|
|
9
|
+
class_eval "
|
|
10
|
+
use Sinatra.new {
|
|
11
|
+
helpers Helpers
|
|
12
|
+
|
|
13
|
+
before do
|
|
14
|
+
@plural = '#{plural}'
|
|
15
|
+
@title = '#{title}'
|
|
16
|
+
load_site_information
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# list
|
|
20
|
+
get '/admin/#{plural}' do
|
|
21
|
+
@records = #{klass}.all
|
|
22
|
+
erb :'admin/index'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# new form
|
|
26
|
+
get '/admin/#{plural}/new' do
|
|
27
|
+
@record = #{klass}.new
|
|
28
|
+
@form = Form.new(@record)
|
|
29
|
+
erb :'admin/new'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# create
|
|
33
|
+
post '/admin/#{plural}' do
|
|
34
|
+
@record = #{klass}.new(params[:record])
|
|
35
|
+
if @record.valid?
|
|
36
|
+
begin
|
|
37
|
+
@record.save
|
|
38
|
+
if #{redirect_to_record}
|
|
39
|
+
redirect url_prefix + 'admin/#{plural}/' + @record.id.to_s
|
|
40
|
+
else
|
|
41
|
+
redirect url_prefix + 'admin/#{plural}'
|
|
42
|
+
end
|
|
43
|
+
rescue
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
@form = Form.new(@record)
|
|
48
|
+
erb :'admin/new'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# edit
|
|
52
|
+
get '/admin/#{plural}/:id' do
|
|
53
|
+
@record = #{klass}.with_pk!(params['id'])
|
|
54
|
+
@form = Form.new(@record)
|
|
55
|
+
erb :'admin/edit'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# update
|
|
59
|
+
put '/admin/#{plural}/:id' do
|
|
60
|
+
@record = #{klass}.with_pk!(params['id'])
|
|
61
|
+
if @record.valid?
|
|
62
|
+
begin
|
|
63
|
+
@record.update(params[:record])
|
|
64
|
+
redirect url_prefix + 'admin/#{plural}'
|
|
65
|
+
rescue
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
@form = Form.new(@record)
|
|
70
|
+
erb :'admin/edit'
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# delete
|
|
74
|
+
delete '/admin/#{plural}/:id' do
|
|
75
|
+
@record = #{klass}.with_pk!(params['id'])
|
|
76
|
+
@record.destroy
|
|
77
|
+
redirect url_prefix + 'admin/#{plural}'
|
|
78
|
+
end
|
|
79
|
+
}
|
|
80
|
+
"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|