noah 0.0.5
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.
- data/.autotest +13 -0
- data/.gitignore +7 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +85 -0
- data/README.md +213 -0
- data/Rakefile +105 -0
- data/autotest/discover.rb +1 -0
- data/bin/noah +8 -0
- data/config.ru +3 -0
- data/doc/coverage/index.html +138 -0
- data/doc/coverage/jquery-1.3.2.min.js +19 -0
- data/doc/coverage/jquery.tablesorter.min.js +15 -0
- data/doc/coverage/lib-helpers_rb.html +393 -0
- data/doc/coverage/lib-models_rb.html +1449 -0
- data/doc/coverage/noah_rb.html +2019 -0
- data/doc/coverage/print.css +12 -0
- data/doc/coverage/rcov.js +42 -0
- data/doc/coverage/screen.css +270 -0
- data/lib/noah.rb +18 -0
- data/lib/noah/app.rb +317 -0
- data/lib/noah/applications.rb +46 -0
- data/lib/noah/configurations.rb +49 -0
- data/lib/noah/helpers.rb +57 -0
- data/lib/noah/hosts.rb +54 -0
- data/lib/noah/models.rb +5 -0
- data/lib/noah/services.rb +57 -0
- data/lib/noah/version.rb +3 -0
- data/lib/noah/watchers.rb +18 -0
- data/noah.gemspec +44 -0
- data/spec/application_spec.rb +83 -0
- data/spec/configuration_spec.rb +25 -0
- data/spec/host_spec.rb +119 -0
- data/spec/noahapp_application_spec.rb +108 -0
- data/spec/noahapp_configuration_spec.rb +112 -0
- data/spec/noahapp_host_spec.rb +116 -0
- data/spec/noahapp_service_spec.rb +121 -0
- data/spec/noahapp_spec.rb +20 -0
- data/spec/service_spec.rb +112 -0
- data/spec/spec_helper.rb +105 -0
- data/views/200.erb +1 -0
- data/views/404.erb +1 -0
- data/views/500.erb +1 -0
- data/views/index.haml +49 -0
- metadata +348 -0
data/spec/host_spec.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Using the Host Model", :reset_redis => true do
|
4
|
+
|
5
|
+
describe "should" do
|
6
|
+
it "create a new Host with no services" do
|
7
|
+
hostname = "host1.domain.com"
|
8
|
+
hoststatus = "up"
|
9
|
+
host = Host.create(:name => hostname, :status => hoststatus)
|
10
|
+
host.valid?.should == true
|
11
|
+
host.save
|
12
|
+
host.name.should == hostname
|
13
|
+
host.status.should == hoststatus
|
14
|
+
host.services.size.should == 0
|
15
|
+
end
|
16
|
+
|
17
|
+
it "create a new Host with services" do
|
18
|
+
hostname = "host2.domain.com"
|
19
|
+
hoststatus = "down"
|
20
|
+
servicename = 'myservice'
|
21
|
+
servicestatus = 'pending'
|
22
|
+
host = Host.create(:name => hostname, :status => hoststatus)
|
23
|
+
host.valid?.should == true
|
24
|
+
host.save
|
25
|
+
host.services << Service.create(:name => servicename, :status => servicestatus, :host => host)
|
26
|
+
host.name.should == hostname
|
27
|
+
host.status.should == hoststatus
|
28
|
+
host.services.size.should == 1
|
29
|
+
host.services[1].valid?.should == true
|
30
|
+
host.services[1].name.should == servicename
|
31
|
+
host.services[1].status.should == servicestatus
|
32
|
+
host.services[1].host_id.should == host.id
|
33
|
+
end
|
34
|
+
|
35
|
+
it "create a Host via find_or_create" do
|
36
|
+
hostname = "host3.domain.com"
|
37
|
+
hoststatus = "up"
|
38
|
+
host = Host.find_or_create(:name => hostname, :status => hoststatus)
|
39
|
+
host.valid?.should == true
|
40
|
+
host.save
|
41
|
+
host.is_new?.should == true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "update a Host via find_or_create" do
|
45
|
+
hostname = "host3.domain.com"
|
46
|
+
hoststatus = "pending"
|
47
|
+
newstatus = "down"
|
48
|
+
host = Host.find_or_create(:name => hostname, :status => hoststatus)
|
49
|
+
host.valid?.should == true
|
50
|
+
host.save
|
51
|
+
host.is_new?.should == true
|
52
|
+
sleep 1
|
53
|
+
host1 = Host.find_or_create(:name => hostname, :status => newstatus)
|
54
|
+
host1.save
|
55
|
+
host1.is_new?.should == false
|
56
|
+
end
|
57
|
+
|
58
|
+
it "delete a Host" do
|
59
|
+
hostname = "host3.domain.com"
|
60
|
+
hoststatus = "pending"
|
61
|
+
host = Host.create(:name => hostname, :status => hoststatus)
|
62
|
+
host.save
|
63
|
+
host.delete
|
64
|
+
Host.find(:name => hostname).empty?.should == true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return all Hosts" do
|
68
|
+
hostname1 = "host1.domain.com"
|
69
|
+
status1 = "up"
|
70
|
+
hostname2 = "host2.domain.com"
|
71
|
+
status2= "down"
|
72
|
+
host1 = Host.create(:name => hostname1, :status => status1)
|
73
|
+
host2 = Host.create(:name => hostname2, :status => status2)
|
74
|
+
host1.save
|
75
|
+
host2.save
|
76
|
+
Hosts.all.class.should == Array
|
77
|
+
Hosts.all.size.should == 2
|
78
|
+
Hosts.all.first.name.should == hostname1
|
79
|
+
Hosts.all.first.status.should == status1
|
80
|
+
Hosts.all.last.name.should == hostname2
|
81
|
+
Hosts.all.last.status.should == status2
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "should not" do
|
86
|
+
it "create a new Host with missing status" do
|
87
|
+
hostname ="host3.domain.com"
|
88
|
+
host = Host.create(:name => hostname)
|
89
|
+
host.valid?.should == false
|
90
|
+
host.errors.should == [[:status, :not_present], [:status, :not_member]]
|
91
|
+
end
|
92
|
+
|
93
|
+
it "create a new Host with missing hostname" do
|
94
|
+
status = "up"
|
95
|
+
host = Host.create(:status => status)
|
96
|
+
host.valid?.should == false
|
97
|
+
host.errors.should == [[:name, :not_present]]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "create a new Host with an invalid status" do
|
101
|
+
hostname = "host3.domain.com"
|
102
|
+
status = "online"
|
103
|
+
host = Host.create(:name => hostname, :status => status)
|
104
|
+
host.valid?.should == false
|
105
|
+
host.errors.should == [[:status, :not_member]]
|
106
|
+
end
|
107
|
+
|
108
|
+
it "create a duplicate Host" do
|
109
|
+
hostname = "host1.domain.com"
|
110
|
+
status = "up"
|
111
|
+
host1 = Host.create(:name => hostname, :status => status)
|
112
|
+
host1.save
|
113
|
+
host2 = Host.create(:name => hostname, :status => status)
|
114
|
+
host2.valid?.should == false
|
115
|
+
host2.errors.should == [[:name, :not_unique]]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Using the Application API", :reset_redis => false do
|
4
|
+
before(:all) do
|
5
|
+
@a = Application.create(:name => 'rspec_sample_app')
|
6
|
+
@a.configurations << Configuration.create(:name => 'rspec_config', :format => 'string', :body => 'rspec is great', :application => @a)
|
7
|
+
@a.save
|
8
|
+
@c = @a.configurations.first
|
9
|
+
end
|
10
|
+
describe "calling" do
|
11
|
+
|
12
|
+
describe "GET" do
|
13
|
+
it "all applications should work" do
|
14
|
+
get '/a'
|
15
|
+
last_response.should be_ok
|
16
|
+
response = last_response.should return_json
|
17
|
+
response.is_a?(Array).should == true
|
18
|
+
end
|
19
|
+
it "named application should work" do
|
20
|
+
get '/a/rspec_sample_app'
|
21
|
+
last_response.should be_ok
|
22
|
+
response = last_response.should return_json
|
23
|
+
|
24
|
+
response["id"].should == @a.id
|
25
|
+
response["name"].should == @a.name
|
26
|
+
c = response["configurations"].first
|
27
|
+
c["id"].should == @c.id
|
28
|
+
c["name"].should == @c.name
|
29
|
+
c["body"].should == @c.body
|
30
|
+
c["format"].should == @c.format
|
31
|
+
end
|
32
|
+
it "named configuration for application should work" do
|
33
|
+
get "/a/#{@a.name}/#{@c.name}"
|
34
|
+
last_response.should be_ok
|
35
|
+
response = last_response.should return_json
|
36
|
+
|
37
|
+
response["id"].should == @c.id
|
38
|
+
response["name"].should == @c.name
|
39
|
+
response["format"].should == @c.format
|
40
|
+
response["body"].should == @c.body
|
41
|
+
response["application"].should == @a.name
|
42
|
+
end
|
43
|
+
it "invalid application should not work" do
|
44
|
+
get "/a/should_not_exist"
|
45
|
+
last_response.should be_missing
|
46
|
+
end
|
47
|
+
it "invalid configuration for application should not work" do
|
48
|
+
get "/a/should_not_exist/should_not_exist"
|
49
|
+
last_response.should be_missing
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "PUT" do
|
54
|
+
before(:all) do
|
55
|
+
@appdata = {:name => "should_now_exist"}
|
56
|
+
end
|
57
|
+
it "new application should work" do
|
58
|
+
put "/a/#{@appdata[:name]}", @appdata.to_json, "CONTENT_TYPE" => "application/json"
|
59
|
+
last_response.should be_ok
|
60
|
+
response = last_response.should return_json
|
61
|
+
response["result"].should == "success"
|
62
|
+
response["id"].nil?.should == false
|
63
|
+
response["name"].should == @appdata[:name]
|
64
|
+
response["action"].should == "create"
|
65
|
+
Application.find(:name => @appdata[:name]).size.should == 1
|
66
|
+
Application.find(:name => @appdata[:name]).first.is_new?.should == true
|
67
|
+
end
|
68
|
+
it "new application with missing name should not work" do
|
69
|
+
put "/a/should_not_work", '{"foo":"bar"}', "CONTENT_TYPE" => "application/json"
|
70
|
+
last_response.should be_invalid
|
71
|
+
end
|
72
|
+
it "existing application should work" do
|
73
|
+
sleep 3
|
74
|
+
|
75
|
+
put "/a/#{@appdata[:name]}", @appdata.to_json, "CONTENT_TYPE" => "application/json"
|
76
|
+
last_response.should be_ok
|
77
|
+
response = last_response.should return_json
|
78
|
+
response["result"].should == "success"
|
79
|
+
response["id"].nil?.should == false
|
80
|
+
response["name"].should == @appdata[:name]
|
81
|
+
response["action"].should == "update"
|
82
|
+
Application.find(:name => @appdata[:name]).size.should == 1
|
83
|
+
Application.find(:name => @appdata[:name]).first.is_new?.should == false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "DELETE" do
|
88
|
+
before(:each) do
|
89
|
+
@appdata = {:name => "should_now_exist"}
|
90
|
+
end
|
91
|
+
it "existing application should work" do
|
92
|
+
delete "/a/#{@appdata[:name]}"
|
93
|
+
last_response.should be_ok
|
94
|
+
response = last_response.should return_json
|
95
|
+
response["result"].should == "success"
|
96
|
+
response["action"].should == "delete"
|
97
|
+
response["id"].nil?.should == false
|
98
|
+
response["name"].should == @appdata[:name]
|
99
|
+
response["configurations"].should == "0"
|
100
|
+
end
|
101
|
+
it "invalid application should not work" do
|
102
|
+
delete "/a/should_not_work"
|
103
|
+
last_response.should be_missing
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Using the Configuration API", :reset_redis => false, :populate_sample_data => true do
|
4
|
+
describe "calling" do
|
5
|
+
|
6
|
+
describe "GET" do
|
7
|
+
it "all configurations should work" do
|
8
|
+
get '/c'
|
9
|
+
last_response.should be_ok
|
10
|
+
last_response.should return_json
|
11
|
+
end
|
12
|
+
it "named application should work" do
|
13
|
+
get '/c/noah'
|
14
|
+
last_response.should be_ok
|
15
|
+
response = last_response.should return_json
|
16
|
+
|
17
|
+
response.is_a?(Array).should == true
|
18
|
+
response.first["name"].should == "redis"
|
19
|
+
response.first["format"].should == "string"
|
20
|
+
response.first["body"].should == "redis://127.0.0.1:6379/0"
|
21
|
+
response.first["application"].should == "noah"
|
22
|
+
end
|
23
|
+
it "named configuration for application should work" do
|
24
|
+
get '/c/noah/redis'
|
25
|
+
last_response.should be_ok
|
26
|
+
response = last_response.body
|
27
|
+
response.should == "redis://127.0.0.1:6379/0"
|
28
|
+
end
|
29
|
+
it "named configuration should work with mime-type" do
|
30
|
+
require 'yaml'
|
31
|
+
get '/c/myrailsapp1/database.yml'
|
32
|
+
last_response.should be_ok
|
33
|
+
last_response.headers["Content-Type"].should == "text/x-yaml;charset=utf-8"
|
34
|
+
response = YAML.load(last_response.body)
|
35
|
+
response.is_a?(Hash).should == true
|
36
|
+
response.keys.should == ["development"]
|
37
|
+
response["development"].keys.should == ["database", "adapter", "username", "password"]
|
38
|
+
response["development"].values.should == ["development_database", "mysql", "dev_user", "dev_password"]
|
39
|
+
end
|
40
|
+
it "invalid application should not work" do
|
41
|
+
get '/c/badapp'
|
42
|
+
last_response.should be_missing
|
43
|
+
end
|
44
|
+
it "invalid configuration for application should not work" do
|
45
|
+
get '/c/badapp/badconfig'
|
46
|
+
last_response.should be_missing
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "PUT" do
|
51
|
+
it "new configuration should work" do
|
52
|
+
config_data = {:format => "string", :body => "sample_config_entry"}.to_json
|
53
|
+
put '/c/newapp/newconfig', config_data, "CONTENT_TYPE" => "application/json"
|
54
|
+
last_response.should be_ok
|
55
|
+
response = last_response.should return_json
|
56
|
+
response["result"].should == "success"
|
57
|
+
response["action"].should == "create"
|
58
|
+
response["dependencies"].should == "created"
|
59
|
+
response["application"].should == "newapp"
|
60
|
+
response["item"].should == "newconfig"
|
61
|
+
end
|
62
|
+
it "existing configuration should work" do
|
63
|
+
config_data = {:format => "string", :body => "sample_config_entry"}.to_json
|
64
|
+
sleep 3
|
65
|
+
put '/c/newapp/newconfig', config_data, "CONTENT_TYPE" => "application/json"
|
66
|
+
last_response.should be_ok
|
67
|
+
response = last_response.should return_json
|
68
|
+
response["result"].should == "success"
|
69
|
+
response["action"].should == "update"
|
70
|
+
response["dependencies"].should == "updated"
|
71
|
+
response["application"].should == "newapp"
|
72
|
+
response["item"].should == "newconfig"
|
73
|
+
end
|
74
|
+
it "new configuration with missing format should not work" do
|
75
|
+
config_data = {:body => "a string"}.to_json
|
76
|
+
put '/c/newnewapp/someconfig', config_data, "CONTENT_TYPE" => "application/json"
|
77
|
+
last_response.should be_invalid
|
78
|
+
end
|
79
|
+
it "new configuration with missing body should not work" do
|
80
|
+
config_data = {:body => "a string"}.to_json
|
81
|
+
put '/c/newnewapp/someconfig', config_data, "CONTENT_TYPE" => "application/json"
|
82
|
+
last_response.should be_invalid
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "DELETE" do
|
87
|
+
before(:all) do
|
88
|
+
cparms = {:name => 'a', :format => 'string', :body => 'asdf'}
|
89
|
+
@a = Application.create(:name => 'delete_test_app')
|
90
|
+
@a.configurations << Configuration.create(cparms)
|
91
|
+
@a.save
|
92
|
+
@c = @a.configurations.first
|
93
|
+
end
|
94
|
+
|
95
|
+
it "existing configuration should work" do
|
96
|
+
delete "/c/#{@a.name}/#{@c.name}"
|
97
|
+
last_response.should be_ok
|
98
|
+
response = last_response.should return_json
|
99
|
+
response["result"].should == "success"
|
100
|
+
response["id"].should == @c.id
|
101
|
+
response["action"].should == "delete"
|
102
|
+
response["application"].should == @a.name
|
103
|
+
response["item"].should == @c.name
|
104
|
+
end
|
105
|
+
it "invalid configuration should not work" do
|
106
|
+
delete "/c/#{@a.name}/#{@c.name}"
|
107
|
+
last_response.should be_missing
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Using the Host API", :reset_redis => false, :populate_sample_data => true do
|
4
|
+
describe "calling" do
|
5
|
+
|
6
|
+
describe "GET" do
|
7
|
+
it "all hosts should work" do
|
8
|
+
get '/h'
|
9
|
+
last_response.should be_ok
|
10
|
+
last_response.should return_json
|
11
|
+
end
|
12
|
+
|
13
|
+
it "existing host should work" do
|
14
|
+
get '/h/localhost'
|
15
|
+
last_response.should be_ok
|
16
|
+
response = last_response.should return_json
|
17
|
+
|
18
|
+
services = response["services"]
|
19
|
+
|
20
|
+
response["name"].should == "localhost"
|
21
|
+
response["status"].should == "up"
|
22
|
+
services.size.should == 2
|
23
|
+
services.first["name"].should == "redis"
|
24
|
+
services.first["status"].should == "up"
|
25
|
+
services.first["host"].should == "localhost"
|
26
|
+
services.last["name"].should == "noah"
|
27
|
+
services.last["status"].should == "up"
|
28
|
+
services.last["host"].should == "localhost"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "named service for host should work" do
|
32
|
+
get '/h/localhost/noah'
|
33
|
+
last_response.should be_ok
|
34
|
+
response = last_response.should return_json
|
35
|
+
|
36
|
+
response["name"].should == "noah"
|
37
|
+
response["status"].should == "up"
|
38
|
+
response["host"].should == "localhost"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "PUT" do
|
43
|
+
it "new host should work" do
|
44
|
+
host_data = {:name => "host99.domain.com", :status => "down"}.to_json
|
45
|
+
put '/h/host99.domain.com', host_data, "CONTENT_TYPE" => "application/json"
|
46
|
+
last_response.should be_ok
|
47
|
+
response = last_response.should return_json
|
48
|
+
|
49
|
+
response["result"].should == "success"
|
50
|
+
response["id"].nil?.should == false
|
51
|
+
response["name"].should == "host99.domain.com"
|
52
|
+
response["status"].should == "down"
|
53
|
+
response["new_record"].should == true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "existing host should work" do
|
57
|
+
sleep 3
|
58
|
+
host_data = {:name => "host99.domain.com", :status => "pending"}.to_json
|
59
|
+
put '/h/host99.domain.com', host_data, "CONTENT_TYPE" => "application/json"
|
60
|
+
last_response.should be_ok
|
61
|
+
response = last_response.should return_json
|
62
|
+
|
63
|
+
response["new_record"].should == false
|
64
|
+
end
|
65
|
+
|
66
|
+
it "host missing name parameter should not work" do
|
67
|
+
host_data = {:status => "pending"}.to_json
|
68
|
+
put '/h/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
|
69
|
+
last_response.should be_invalid
|
70
|
+
end
|
71
|
+
|
72
|
+
it "host missing status parameter should not work" do
|
73
|
+
host_data = {:name => "host100.domain.com"}.to_json
|
74
|
+
put '/h/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
|
75
|
+
last_response.should be_invalid
|
76
|
+
end
|
77
|
+
|
78
|
+
it "host with invalid status parameter should not work" do
|
79
|
+
host_data = {:name => "host100.domain.com", :status => "fscked"}.to_json
|
80
|
+
put '/h/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
|
81
|
+
last_response.should_not be_ok
|
82
|
+
response = last_response.should return_json
|
83
|
+
|
84
|
+
response["result"].should == "failure"
|
85
|
+
response["error_message"].should == "[[:status, :not_member]]"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "DELETE" do
|
90
|
+
before(:all) do
|
91
|
+
@h = Host.create(:name => 'h', :status => 'up')
|
92
|
+
sparms = {:name => 's', :status => "up"}
|
93
|
+
@h.services << Service.create(sparms.merge({:host => @h}))
|
94
|
+
@h.save
|
95
|
+
@s = @h.services.first
|
96
|
+
end
|
97
|
+
it "existing host should work" do
|
98
|
+
svc_size = @h.services.size
|
99
|
+
delete "/h/#{@h.name}"
|
100
|
+
last_response.should be_ok
|
101
|
+
response = last_response.should return_json
|
102
|
+
|
103
|
+
response["result"].should == "success"
|
104
|
+
response["id"].should == @h.id
|
105
|
+
response["name"].should == @h.name
|
106
|
+
response["service_count"].should == svc_size.to_s
|
107
|
+
end
|
108
|
+
|
109
|
+
it "invalid host should not work" do
|
110
|
+
delete "/h/#{@h.name}"
|
111
|
+
last_response.should be_missing
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|