noah 0.0.5-jruby

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.
@@ -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