noah 0.0.5-jruby

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ /* Hide controls */
2
+
3
+ body {
4
+ color: #000000;
5
+ background-color: #ffffff;
6
+ }
7
+
8
+ /* Hide controls */
9
+
10
+ div.filters {
11
+ display: none;
12
+ }
@@ -0,0 +1,42 @@
1
+ function toggleCode( id ) {
2
+ if ( document.getElementById ) {
3
+ elem = document.getElementById( id );
4
+ } else if ( document.all ) {
5
+ elem = eval( "document.all." + id );
6
+ } else {
7
+ return false;
8
+ }
9
+
10
+ elemStyle = elem.style;
11
+
12
+ if ( elemStyle.display != "block" ) {
13
+ elemStyle.display = "block";
14
+ } else {
15
+ elemStyle.display = "none";
16
+ }
17
+
18
+ return true;
19
+ }
20
+
21
+ function restripe() {
22
+ i = 0;
23
+ $('table#report_table tbody tr').each(function(){
24
+ if (this.style.display != "none") {
25
+ i += 1;
26
+ classes = this.className.split(" ");
27
+ if ($.inArray("even",classes) != -1) {
28
+ classes.splice($.inArray("even",classes),1);
29
+ } else if ($.inArray("odd",classes) != -1) {
30
+ classes.splice($.inArray("odd",classes),1);
31
+ }
32
+ if (i % 2 === 0) {
33
+ this.className = classes.join(" ") + " odd";
34
+ } else {
35
+ this.className = classes.join(" ") + " even";
36
+ }
37
+ }
38
+ });
39
+ }
40
+
41
+ // Fix IE's lack of support for indexOf (!)
42
+ if (!Array.indexOf) { Array.prototype.indexOf = function(obj){ for(var i=0; i<this.length; i++){ if(this[i]==obj){return i;} } return -1; }}
@@ -0,0 +1,270 @@
1
+ /* @group General */
2
+
3
+ body {
4
+ font-family: Verdana, Helvetica, Arial, Sans-Serif;
5
+ font-size: 12px;
6
+ color: #4C4C4C;
7
+ background-color: #F4F2ED;
8
+ padding: 1em;
9
+ }
10
+
11
+ a:link {
12
+ color: #191919;
13
+ }
14
+
15
+ a:visited {
16
+ color: #191919;
17
+ }
18
+
19
+ pre, code {
20
+ color: #000000;
21
+ font-family: "Bitstream Vera Sans Mono","Monaco","Courier New",monospace;
22
+ font-size: 95%;
23
+ line-height: 1.3em;
24
+ margin-top: 0;
25
+ margin-bottom: 0;
26
+ padding: 0;
27
+ word-wrap: break-word;
28
+ }
29
+
30
+ h1, h2, h3, h4, h5, h6 {
31
+ margin: 0em 0em 1em 0em;
32
+ color: #666666;
33
+ }
34
+
35
+ h1 {
36
+ display: block;
37
+ font-size: 2em;
38
+ letter-spacing: -1px;
39
+ }
40
+
41
+ h2 {
42
+ margin-top: -1em;
43
+ }
44
+
45
+ fieldset {
46
+ display: inline;
47
+ border: 0px;
48
+ padding: 0px;
49
+ margin-right: 1em;
50
+ }
51
+
52
+ div.filters {
53
+ margin-bottom: 1em;
54
+ }
55
+
56
+ .hidden {
57
+ display: none;
58
+ }
59
+
60
+ /* @end */
61
+
62
+ /* @group Cross-References */
63
+
64
+ span.cross-ref-title {
65
+ font-size: 140%;
66
+ }
67
+
68
+ span.cross-ref a {
69
+ text-decoration: none;
70
+ }
71
+
72
+ span.cross-ref {
73
+ background-color:#f3f7fa;
74
+ border: 1px dashed #333;
75
+ margin: 1em;
76
+ padding: 0.5em;
77
+ overflow: hidden;
78
+ }
79
+
80
+ a.crossref-toggle {
81
+ text-decoration: none;
82
+ }
83
+
84
+ /* @end */
85
+
86
+ /* @group Report Table */
87
+
88
+ div.report_table_wrapper {
89
+ min-width: 900px;
90
+ }
91
+
92
+ table.report {
93
+ border-collapse: collapse;
94
+ border: 1px solid #666666;
95
+ width: 100%;
96
+ margin-bottom: 1em;
97
+ }
98
+
99
+ table.report tr {
100
+ line-height: 1.75em;
101
+ }
102
+
103
+ table.report th {
104
+ background: #666666;
105
+ color: #ffffff;
106
+ text-align: right;
107
+ text-transform: uppercase;
108
+ font-size: .8em;
109
+ font-weight: bold;
110
+ padding: 0em .5em;
111
+ border: 1px solid #666666;
112
+ }
113
+
114
+ table.report tfoot tr {
115
+ background: #dddddd;
116
+ font-weight: bold;
117
+ padding: .5em;
118
+ border: 1px solid #666666;
119
+ }
120
+
121
+ th.left_align, td.left_align {
122
+ text-align: left !important;
123
+ }
124
+
125
+ th.right_align, td.right_align {
126
+ text-align: right;
127
+ padding-right: 2em !important;
128
+ }
129
+
130
+ table.report th.header:hover {
131
+ cursor: pointer;
132
+ text-decoration: underline;
133
+ }
134
+
135
+ table.report th.headerSortUp:after{
136
+ content: "\25BC";
137
+ margin-left: 1em;
138
+ }
139
+
140
+ table.report th.headerSortDown:after {
141
+ content: "\25B2";
142
+ margin-left: 1em;
143
+ }
144
+
145
+ table.report tr.summary_row {
146
+ background: #cccccc;
147
+ border: 1px solid #cccccc;
148
+ }
149
+
150
+ table.report tr.summary_row td {
151
+ padding-left: .2em !important;
152
+ color: #333333;
153
+ font-weight: bold;
154
+ }
155
+
156
+ table.report td {
157
+ padding: .2em .5em .2em .5em;
158
+ }
159
+
160
+ table.report td a {
161
+ text-decoration: none;
162
+ }
163
+
164
+ table.report tbody tr:hover {
165
+ background: #cccccc !important;
166
+ }
167
+
168
+ table.report tr.summary_row td {
169
+ border-bottom: 1px solid #aaaaaa;
170
+ }
171
+
172
+ table.report tr {
173
+ background-color: #eeeeee;
174
+ }
175
+
176
+ table.report tr.odd {
177
+ background-color: #dddddd;
178
+ }
179
+
180
+ /* @end */
181
+
182
+ /* @group Percentage Graphs */
183
+
184
+ div.percent_graph_legend {
185
+ width: 5.5em;
186
+ float: left;
187
+ margin: .5em 1em .5em 0em;
188
+ height: 1em;
189
+ line-height: 1em;
190
+ }
191
+
192
+ div.percent_graph {
193
+ height: 1em;
194
+ border: #333333 1px solid;
195
+ empty-cells: show;
196
+ padding: 0px;
197
+ border-collapse: collapse;
198
+ width: 100px !important;
199
+ float: left;
200
+ margin: .5em 1em .5em 0em;
201
+ }
202
+
203
+ div.percent_graph div {
204
+ float: left;
205
+ height: 1em;
206
+ padding: 0px !important;
207
+ }
208
+
209
+ div.percent_graph div.covered {
210
+ background: #649632;
211
+ }
212
+
213
+ div.percent_graph div.uncovered {
214
+ background: #a92730;
215
+ }
216
+
217
+ div.percent_graph div.NA {
218
+ background: #eaeaea;
219
+ }
220
+
221
+ /* @end */
222
+
223
+ /* @group Details page */
224
+
225
+ table.details {
226
+ margin-top: 1em;
227
+ border-collapse: collapse;
228
+ width: 100%;
229
+ border: 1px solid #666666;
230
+ }
231
+
232
+ table.details tr {
233
+ line-height: 1.75em;
234
+ }
235
+
236
+ table.details td {
237
+ padding: .25em;
238
+ }
239
+
240
+ span.inferred, span.inferred1, span.marked, span.marked1, span.uncovered, span.uncovered1 {
241
+ display: block;
242
+ padding: .25em;
243
+ }
244
+
245
+ tr.inferred td, span.inferred {
246
+ background-color: #e0dedb;
247
+ }
248
+
249
+ tr.inferred1 td, span.inferred1 {
250
+ background-color: #e0dedb;
251
+ }
252
+
253
+ tr.marked td, span.marked, span.marked1 {
254
+ background-color: #bed2be;
255
+ }
256
+
257
+ tr.uncovered td, span.uncovered {
258
+ background-color: #ce8b8c;
259
+ }
260
+
261
+ tr.uncovered1 td, span.uncovered1 {
262
+ background-color: #ce8b8c;
263
+ }
264
+
265
+ div.key {
266
+ border: 1px solid #666666;
267
+ margin: 1em 0em;
268
+ }
269
+
270
+ /* @end */
data/lib/noah/app.rb ADDED
@@ -0,0 +1,317 @@
1
+ require 'sinatra/base'
2
+ require 'sinatra/namespace'
3
+ require 'ohm'
4
+ require 'ohm/contrib'
5
+
6
+ require File.join(File.dirname(__FILE__), 'helpers')
7
+ require File.join(File.dirname(__FILE__), 'models')
8
+
9
+ module Noah
10
+ class App < Sinatra::Base
11
+ register ::Sinatra::Namespace
12
+
13
+ helpers Noah::SinatraHelpers
14
+
15
+ configure do
16
+ set :app_file, __FILE__
17
+ set :root, File.expand_path(File.join(File.dirname(__FILE__), "..",".."))
18
+ set :server, %w[thin mongrel webrick]
19
+ set :logging, true
20
+ set :raise_errors, false
21
+ set :show_exceptions, false
22
+ end
23
+
24
+ configure(:development) do
25
+ begin
26
+ require 'sinatra/reloader'
27
+ register Sinatra::Reloader
28
+ also_reload File.join(File.dirname(__FILE__), 'models.rb')
29
+ also_reload File.join(File.dirname(__FILE__), 'helpers.rb')
30
+ rescue LoadError
31
+ puts "sinatra-reloader gem missing. reloading disabled"
32
+ end
33
+ end
34
+
35
+ before do
36
+ content_type "application/json"
37
+ end
38
+
39
+ get '/' do
40
+ content_type "text/html"
41
+
42
+ haml :index, :format => :html5
43
+ end
44
+
45
+ not_found do
46
+ content_type "application/json"
47
+ erb :'404'
48
+ end
49
+
50
+ error do
51
+ content_type "application/json"
52
+ erb :'500'
53
+ end
54
+
55
+ namespace "/h" do
56
+
57
+ get '/:hostname/:servicename/?' do |hostname, servicename|
58
+ h = host_service(hostname, servicename)
59
+ if h.nil?
60
+ halt 404
61
+ else
62
+ h.to_json
63
+ end
64
+ end
65
+
66
+ get '/:hostname/?' do |hostname|
67
+ h = host(:name => hostname)
68
+ if h.nil?
69
+ halt 404
70
+ else
71
+ h.to_json
72
+ end
73
+ end
74
+
75
+ get '/?' do
76
+ hosts.map {|h| h.to_hash}
77
+ if hosts.size == 0
78
+ halt 404
79
+ else
80
+ hosts.to_json
81
+ end
82
+ end
83
+
84
+ put '/:hostname/?' do |hostname|
85
+ required_params = ["name", "status"]
86
+ data = JSON.parse(request.body.read)
87
+ (data.keys.sort == required_params.sort && data['name'] == hostname) ? (host = ::Host.find_or_create(:name => data['name'], :status => data['status'])) : (raise "Missing Parameters")
88
+ if host.valid?
89
+ r = {"result" => "success","id" => "#{host.id}","status" => "#{host.status}", "name" => "#{host.name}", "new_record" => host.is_new?}
90
+ r.to_json
91
+ else
92
+ raise "#{host.errors}"
93
+ end
94
+ end
95
+
96
+ delete '/:hostname/?' do |hostname|
97
+ host = ::Host.find(:name => hostname).first
98
+ if host
99
+ services = []
100
+ Service.find(:host_id => host.id).sort.each {|x| services << x; x.delete} if host.services.size > 0
101
+ host.delete
102
+ r = {"result" => "success", "id" => "#{host.id}", "name" => "#{hostname}", "service_count" => "#{services.size}"}
103
+ r.to_json
104
+ else
105
+ halt 404
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ namespace "/s" do
112
+
113
+ get '/:servicename/:hostname/?' do |servicename, hostname|
114
+ hs = host_service(hostname, servicename)
115
+ if hs.nil?
116
+ halt 404
117
+ else
118
+ hs.to_json
119
+ end
120
+ end
121
+
122
+ get '/:servicename/?' do |servicename|
123
+ s = services(:name => servicename)
124
+ s.map {|x| x.to_hash}
125
+ if s.empty?
126
+ halt 404
127
+ else
128
+ s.to_json
129
+ end
130
+ end
131
+
132
+ get '/?' do
133
+ if services.empty?
134
+ halt 404
135
+ else
136
+ services.map {|s| s.to_hash}
137
+ services.to_json
138
+ end
139
+ end
140
+
141
+ put '/:servicename/?' do |servicename|
142
+ required_params = ["status", "host", "name"]
143
+ data = JSON.parse(request.body.read)
144
+ if data.keys.sort == required_params.sort
145
+ h = ::Host.find(:name => data['host']).first || (raise "Invalid Host")
146
+ service = ::Service.find_or_create(:name => servicename, :status => data['status'], :host => h)
147
+ if service.valid?
148
+ action = service.is_new? ? "create" : "update"
149
+ service.save
150
+ r = {"action" => action, "result" => "success", "id" => service.id, "host" => h.name, "name" => service.name}
151
+ r.to_json
152
+ else
153
+ raise "#{service.errors}"
154
+ end
155
+ else
156
+ raise "Missing Parameters"
157
+ end
158
+ end
159
+
160
+ delete '/:servicename/:hostname/?' do |servicename, hostname|
161
+ host = ::Host.find(:name => hostname).first || (halt 404)
162
+ service = ::Service.find(:name => servicename, :host_id => host.id).first || (halt 404)
163
+ if host && service
164
+ service.delete
165
+ r = {"action" => "delete", "result" => "success", "id" => service.id, "host" => host.name, "service" => servicename}
166
+ r.to_json
167
+ else
168
+ halt 404
169
+ end
170
+ end
171
+
172
+ end
173
+
174
+ namespace "/a" do
175
+
176
+ get '/:appname/:config/?' do |appname, config|
177
+ app = ::Application.find(:name => appname).first
178
+ if app.nil?
179
+ halt 404
180
+ else
181
+ c = ::Configuration.find(:name => config, :application_id => app.id).first
182
+ c.to_json
183
+ end
184
+ end
185
+
186
+ get '/:appname/?' do |appname|
187
+ app = ::Application.find(:name => appname).first
188
+ if app.nil?
189
+ halt 404
190
+ else
191
+ app.to_json
192
+ end
193
+ end
194
+
195
+ put '/:appname/?' do |appname|
196
+ required_params = ["name"]
197
+ data = JSON.parse(request.body.read)
198
+ if data.keys.sort == required_params.sort && data['name'] == appname
199
+ app = ::Application.find_or_create(:name => appname)
200
+ else
201
+ raise "Missing Parameters"
202
+ end
203
+ if app.valid?
204
+ action = app.is_new? ? "create" : "update"
205
+ app.save
206
+ r = {"result" => "success","id" => app.id, "action" => action, "name" => app.name }
207
+ r.to_json
208
+ else
209
+ raise "#{app.errors}"
210
+ end
211
+ end
212
+
213
+ delete '/:appname/?' do |appname|
214
+ app = ::Application.find(:name => appname).first
215
+ if app.nil?
216
+ halt 404
217
+ else
218
+ configurations = []
219
+ ::Configuration.find(:application_id => app.id).sort.each {|x| configurations << x; x.delete} if app.configurations.size > 0
220
+ app.delete
221
+ r = {"result" => "success", "action" => "delete", "id" => "#{app.id}", "name" => "#{appname}", "configurations" => "#{configurations.size}"}
222
+ r.to_json
223
+ end
224
+ end
225
+
226
+ get '/?' do
227
+ apps = []
228
+ ::Application.all.sort.each {|a| apps << a.to_hash}
229
+ if apps.empty?
230
+ halt 404
231
+ else
232
+ apps.to_json
233
+ end
234
+ end
235
+
236
+ end
237
+
238
+ namespace '/c' do
239
+
240
+ # Need to move this out to configuration.
241
+ # Maybe bootstrap them from itself?
242
+ content_type_mapping = {
243
+ :yaml => "text/x-yaml",
244
+ :json => "application/json",
245
+ :xml => "text/xml",
246
+ :string => "text/plain"
247
+ }
248
+
249
+ get '/:appname/:element/?' do |appname, element|
250
+ a = ::Application.find(:name => appname).first
251
+ if a.nil?
252
+ halt 404
253
+ else
254
+ c = ::Configuration.find(:name => element, :application_id => a.id).first
255
+ content_type content_type_mapping[c.format.to_sym] if content_type_mapping[c.format.to_sym]
256
+ c.body
257
+ end
258
+ end
259
+
260
+ get '/:appname/?' do |appname|
261
+ config = []
262
+ a = ::Application.find(:name => appname).first
263
+ if a.nil?
264
+ halt 404
265
+ else
266
+ ::Configuration.find(:application_id => a.id).sort.each {|c| config << c.to_hash}
267
+ config.to_json
268
+ end
269
+ end
270
+
271
+ get '/?' do
272
+ configs = []
273
+ ::Configuration.all.sort.each {|c| configs << c.to_hash}
274
+ if configs.empty?
275
+ halt 404
276
+ else
277
+ configs.to_json
278
+ end
279
+ end
280
+
281
+ put '/:appname/:element?' do |appname, element|
282
+ app = ::Application.find_or_create(:name => appname)
283
+ config = ::Configuration.find_or_create(:name => element, :application_id => app.id)
284
+ required_params = ["format", "body"]
285
+ data = JSON.parse(request.body.read)
286
+ data.keys.sort == required_params.sort ? (config.format = data["format"]; config.body = data["body"]) : (raise "Missing Parameters")
287
+ if config.valid?
288
+ config.save
289
+ action = config.is_new? ? "create" : "update"
290
+ dependency_action = app.is_new? ? "created" : "updated"
291
+ r = {"result" => "success","id" => "#{config.id}", "action" => action, "dependencies" => dependency_action, "application" => app.name, "item" => config.name}
292
+ r.to_json
293
+ else
294
+ raise "#{config.errors}"
295
+ end
296
+ end
297
+
298
+ delete '/:appname/:element?' do |appname, element|
299
+ app = ::Application.find(:name => appname).first
300
+ if app
301
+ config = ::Configuration.find(:name=> element, :application_id => app.id).first
302
+ if config
303
+ config.delete
304
+ r = {"result" => "success", "id" => "#{config.id}", "action" => "delete", "application" => "#{app.name}", "item" => "#{element}"}
305
+ r.to_json
306
+ else
307
+ halt 404
308
+ end
309
+ else
310
+ halt 404
311
+ end
312
+ end
313
+
314
+ end
315
+ # run! if app_file == $0
316
+ end
317
+ end
@@ -0,0 +1,46 @@
1
+ class Application < Ohm::Model
2
+ include Ohm::Typecast
3
+ include Ohm::Timestamping
4
+ include Ohm::Callbacks
5
+ include Ohm::ExtraValidations
6
+
7
+ attribute :name
8
+ collection :configurations, Configuration
9
+
10
+ index :name
11
+
12
+ def validate
13
+ assert_present :name
14
+ assert_unique :name
15
+ end
16
+
17
+ def to_hash
18
+ arr = []
19
+ configurations.sort.each {|c| arr << c.to_hash}
20
+ super.merge(:name => name, :updated_at => updated_at, :configurations => arr)
21
+ end
22
+
23
+ def is_new?
24
+ self.created_at == self.updated_at
25
+ end
26
+
27
+ class << self
28
+ def find_or_create(opts = {})
29
+ begin
30
+ find(opts).first.nil? ? (app = create(opts)) : (app = find(opts).first)
31
+ if app.valid?
32
+ app.save
33
+ end
34
+ app
35
+ rescue Exception => e
36
+ e.message
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ class Applications
43
+ def self.all(options = {})
44
+ options.empty? ? Application.all.sort : Application.find(options).sort
45
+ end
46
+ end