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
@@ -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
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Configuration < Ohm::Model
|
2
|
+
include Ohm::Typecast
|
3
|
+
include Ohm::Timestamping
|
4
|
+
include Ohm::Callbacks
|
5
|
+
include Ohm::ExtraValidations
|
6
|
+
|
7
|
+
attribute :name
|
8
|
+
attribute :format
|
9
|
+
attribute :body
|
10
|
+
attribute :new_record
|
11
|
+
reference :application, Application
|
12
|
+
|
13
|
+
index :name
|
14
|
+
|
15
|
+
def validate
|
16
|
+
assert_present :name
|
17
|
+
assert_present :format
|
18
|
+
assert_present :body
|
19
|
+
assert_unique [:name, :application_id]
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_hash
|
23
|
+
super.merge(:name => name, :format => format, :body => body, :update_at => updated_at, :application => Application[application_id].name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_new?
|
27
|
+
self.created_at == self.updated_at
|
28
|
+
end
|
29
|
+
|
30
|
+
class << self
|
31
|
+
def find_or_create(opts={})
|
32
|
+
begin
|
33
|
+
if find(opts).first.nil?
|
34
|
+
conf = create(opts)
|
35
|
+
else
|
36
|
+
conf = find(opts).first
|
37
|
+
end
|
38
|
+
rescue Exception => e
|
39
|
+
e.message
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Configurations
|
46
|
+
def self.all(options = {})
|
47
|
+
options.empty? ? Configuration.all.sort : Configuration.find(options).sort
|
48
|
+
end
|
49
|
+
end
|
data/lib/noah/helpers.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'models')
|
2
|
+
module Noah
|
3
|
+
module SinatraHelpers
|
4
|
+
extend(Ohm)
|
5
|
+
|
6
|
+
def host(opts = {})
|
7
|
+
Host.find(opts).first
|
8
|
+
end
|
9
|
+
|
10
|
+
def hosts(opts = {})
|
11
|
+
Hosts.all(opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def service(opts = {})
|
15
|
+
Service.find(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def services(opts = {})
|
19
|
+
Services.all(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def host_service(hostname, servicename)
|
23
|
+
h = Host.find(:name => hostname).first
|
24
|
+
if h.nil?
|
25
|
+
nil
|
26
|
+
else
|
27
|
+
Service.find(:host_id => h.id, :name => servicename).first
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def host_services(hostname)
|
32
|
+
h = Host.find(:name => hostname).first
|
33
|
+
if h.nil?
|
34
|
+
nil
|
35
|
+
else
|
36
|
+
Services.all(:host_id => id)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def application(opts = {})
|
41
|
+
Application.find(opts).first
|
42
|
+
end
|
43
|
+
|
44
|
+
def applications(opts = {})
|
45
|
+
Applications.all(opts)
|
46
|
+
end
|
47
|
+
|
48
|
+
def configuration(opts = {})
|
49
|
+
Configuration.find(opts).first
|
50
|
+
end
|
51
|
+
|
52
|
+
def configurations(opts = {})
|
53
|
+
Configurations.all(opts)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/lib/noah/hosts.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
class Host < Ohm::Model
|
2
|
+
include Ohm::Typecast
|
3
|
+
include Ohm::Timestamping
|
4
|
+
include Ohm::Callbacks
|
5
|
+
include Ohm::ExtraValidations
|
6
|
+
|
7
|
+
attribute :name
|
8
|
+
attribute :status
|
9
|
+
collection :services, Service
|
10
|
+
|
11
|
+
index :name
|
12
|
+
index :status
|
13
|
+
|
14
|
+
def validate
|
15
|
+
assert_present :name
|
16
|
+
assert_present :status
|
17
|
+
assert_unique :name
|
18
|
+
assert_member :status, ["up","down","pending"]
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_hash
|
22
|
+
arr = []
|
23
|
+
services.sort.each {|s| arr << s.to_hash}
|
24
|
+
h = {:name => name, :status => status, :created_at => created_at, :updated_at => updated_at, :services => arr}
|
25
|
+
super.merge(h)
|
26
|
+
end
|
27
|
+
|
28
|
+
def is_new?
|
29
|
+
self.created_at == self.updated_at
|
30
|
+
end
|
31
|
+
|
32
|
+
class << self
|
33
|
+
def find_or_create(opts = {})
|
34
|
+
begin
|
35
|
+
# exclude requested status from lookup
|
36
|
+
h = find(opts.reject{|key,value| key == :status}).first
|
37
|
+
host = h.nil? ? create(opts) : h
|
38
|
+
host.status = opts[:status]
|
39
|
+
if host.valid?
|
40
|
+
host.save
|
41
|
+
end
|
42
|
+
host
|
43
|
+
rescue Exception => e
|
44
|
+
e.message
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Hosts
|
51
|
+
def self.all(options = {})
|
52
|
+
options.empty? ? Host.all.sort : Host.find(options).sort
|
53
|
+
end
|
54
|
+
end
|
data/lib/noah/models.rb
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'hosts')
|
2
|
+
require File.join(File.dirname(__FILE__),'services')
|
3
|
+
require File.join(File.dirname(__FILE__),'applications')
|
4
|
+
require File.join(File.dirname(__FILE__),'configurations')
|
5
|
+
require File.join(File.dirname(__FILE__),'watchers')
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Service < Ohm::Model
|
2
|
+
include Ohm::Typecast
|
3
|
+
include Ohm::Timestamping
|
4
|
+
include Ohm::Callbacks
|
5
|
+
include Ohm::ExtraValidations
|
6
|
+
|
7
|
+
attribute :name
|
8
|
+
attribute :status
|
9
|
+
reference :host, Host
|
10
|
+
|
11
|
+
index :name
|
12
|
+
index :status
|
13
|
+
|
14
|
+
def validate
|
15
|
+
assert_present :name
|
16
|
+
assert_present :status
|
17
|
+
assert_present :host_id
|
18
|
+
assert_unique [:name, :host_id]
|
19
|
+
assert_member :status, ["up", "down", "pending"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_hash
|
23
|
+
super.merge(:name => name, :status => status, :updated_at => updated_at, :host => Host[host_id].name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_new?
|
27
|
+
self.created_at == self.updated_at
|
28
|
+
end
|
29
|
+
|
30
|
+
class << self
|
31
|
+
def find_or_create(opts = {})
|
32
|
+
begin
|
33
|
+
# convert passed host object to host_id if passed
|
34
|
+
if opts.has_key?(:host)
|
35
|
+
opts.merge!({:host_id => opts[:host].id})
|
36
|
+
opts.reject!{|key, value| key == :host}
|
37
|
+
end
|
38
|
+
# exclude requested status from lookup
|
39
|
+
s = find(opts.reject{|key,value| key == :status}).first
|
40
|
+
service = s.nil? ? create(opts) : s
|
41
|
+
service.status = opts[:status]
|
42
|
+
if service.valid?
|
43
|
+
service.save
|
44
|
+
end
|
45
|
+
service
|
46
|
+
rescue Exception => e
|
47
|
+
e.message
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Services
|
54
|
+
def self.all(options = {})
|
55
|
+
options.empty? ? Service.all.sort : Service.find(options).sort
|
56
|
+
end
|
57
|
+
end
|
data/lib/noah/version.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class Watcher < Ohm::Model #NYI
|
2
|
+
include Ohm::Typecast
|
3
|
+
include Ohm::Timestamping
|
4
|
+
include Ohm::Callbacks
|
5
|
+
|
6
|
+
attribute :client
|
7
|
+
attribute :endpoint
|
8
|
+
attribute :event
|
9
|
+
attribute :action
|
10
|
+
|
11
|
+
index :client
|
12
|
+
index :event
|
13
|
+
|
14
|
+
def validate
|
15
|
+
assert_present :client, :endpoint, :event, :action
|
16
|
+
assert_unique [:client, :endpoint, :event, :action]
|
17
|
+
end
|
18
|
+
end
|
data/noah.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "noah/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "noah"
|
7
|
+
s.version = Noah::VERSION
|
8
|
+
s.platform = RUBY_ENGINE
|
9
|
+
s.authors = ["lusis"]
|
10
|
+
s.email = ["lusis.org+rubygems.org@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/lusis/noah"
|
12
|
+
s.summary = %q{Application registry based on Apache Zookeeper}
|
13
|
+
s.description = %q{Application registry based on Apache Zookeeper}
|
14
|
+
|
15
|
+
s.rubyforge_project = "noah"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency("rake", ["= 0.8.7"])
|
23
|
+
s.add_dependency("sinatra", ["= 1.1.2"])
|
24
|
+
s.add_dependency("sinatra-namespace", ["0.6.1"])
|
25
|
+
s.add_dependency("ohm", ["= 0.1.3"])
|
26
|
+
s.add_dependency("ohm-contrib", ["= 0.1.0"])
|
27
|
+
s.add_dependency("haml", ["= 3.0.25"])
|
28
|
+
s.add_dependency("vegas", ["= 0.1.8"])
|
29
|
+
s.add_dependency("yajl-ruby", ["= 0.7.9"]) if s.platform.to_s == 'ruby'
|
30
|
+
s.add_dependency("jruby-json", ["= 1.5.0"]) if s.platform.to_s == 'jruby'
|
31
|
+
s.add_dependency("thin", ["= 1.2.7"]) if s.platform.to_s == 'ruby'
|
32
|
+
s.add_dependency("json-jruby", ["= 1.4.6"]) if s.platform.to_s == 'jruby'
|
33
|
+
s.add_dependency("jruby-openssl", ["= 0.7.3"]) if s.platform.to_s == 'jruby'
|
34
|
+
|
35
|
+
s.add_development_dependency("sinatra-reloader", ["= 0.5.0"])
|
36
|
+
s.add_development_dependency("rspec", ["= 2.4.0"])
|
37
|
+
s.add_development_dependency("rcov", ["= 0.9.9"]) if s.platform.to_s == 'ruby'
|
38
|
+
s.add_development_dependency("rack-test", ["= 0.5.7"])
|
39
|
+
s.add_development_dependency("ZenTest", ["= 4.4.2"])
|
40
|
+
s.add_development_dependency("autotest", ["= 4.4.6"])
|
41
|
+
s.add_development_dependency("autotest-growl", ["= 0.2.9"])
|
42
|
+
s.add_development_dependency("warbler", ["= 1.2.1"]) if s.platform.to_s == 'java'
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Using the Application Model", :reset_redis => true do
|
4
|
+
before(:all) do
|
5
|
+
@appdata1 = {:name => "my_application"}
|
6
|
+
@appdata2 = {:name => "my_other_app"}
|
7
|
+
@appconf_string = {:name => "mystringconf", :format => "string", :body => "some_var"}
|
8
|
+
@appconf_json = {:name => "myjsonconf", :format => "json", :body => @appconf_string.to_json}
|
9
|
+
end
|
10
|
+
before(:each) do
|
11
|
+
Ohm.redis.flushdb
|
12
|
+
end
|
13
|
+
after(:each) do
|
14
|
+
Ohm.redis.flushdb
|
15
|
+
end
|
16
|
+
describe "should" do
|
17
|
+
it "create a new Application" do
|
18
|
+
a = Application.create(@appdata1)
|
19
|
+
a.valid?.should == true
|
20
|
+
a.is_new?.should == true
|
21
|
+
b = Application.find(@appdata1).first
|
22
|
+
b.should == a
|
23
|
+
end
|
24
|
+
it "create a new Application with Configurations" do
|
25
|
+
a = Application.create(@appdata1)
|
26
|
+
a.configurations << Configuration.create(@appconf_string.merge({:application => a}))
|
27
|
+
a.valid?.should == true
|
28
|
+
a.is_new?.should == true
|
29
|
+
a.save
|
30
|
+
b = Application.find(@appdata1).first
|
31
|
+
b.should == a
|
32
|
+
b.configurations.size.should == 1
|
33
|
+
b.configurations.first.name.should == @appconf_string[:name]
|
34
|
+
b.configurations.first.format.should == @appconf_string[:format]
|
35
|
+
b.configurations.first.body.should == @appconf_string[:body]
|
36
|
+
end
|
37
|
+
it "create a new Application via find_or_create" do
|
38
|
+
a = Application.find_or_create(@appdata2)
|
39
|
+
a.valid?.should == true
|
40
|
+
a.is_new?.should == true
|
41
|
+
b = Application.find(@appdata2).first
|
42
|
+
b.should == a
|
43
|
+
end
|
44
|
+
it "update an existing Application via find_or_create" do
|
45
|
+
a = Application.create(@appdata1)
|
46
|
+
a.is_new?.should == true
|
47
|
+
sleep 2
|
48
|
+
b = Application.find_or_create(@appdata1)
|
49
|
+
b.is_new?.should == false
|
50
|
+
end
|
51
|
+
it "delete an existing Application" do
|
52
|
+
a = Application.create(@appdata1)
|
53
|
+
b = Application.find(@appdata1).first
|
54
|
+
b.should == a
|
55
|
+
b.delete
|
56
|
+
c = Application.find(@appdata1).first
|
57
|
+
c.nil?.should == true
|
58
|
+
end
|
59
|
+
it "return all Applications" do
|
60
|
+
a = Application.create(@appdata1)
|
61
|
+
b = Application.create(@appdata2)
|
62
|
+
c = Applications.all
|
63
|
+
c.size.should == 2
|
64
|
+
c.member?(a).should == true
|
65
|
+
c.member?(b).should == true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "should not" do
|
70
|
+
it "should not create a new Application without a name" do
|
71
|
+
a = Application.create
|
72
|
+
a.valid?.should == false
|
73
|
+
a.errors.should == [[:name, :not_present]]
|
74
|
+
end
|
75
|
+
it "should not create a duplicate Application" do
|
76
|
+
a = Application.create(@appdata1)
|
77
|
+
a.valid?.should == true
|
78
|
+
b = Application.create(@appdata1)
|
79
|
+
b.valid?.should == false
|
80
|
+
b.errors.should == [[:name, :not_unique]]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Using the Configuration Model", :reset_redis => true do
|
4
|
+
|
5
|
+
describe "should" do
|
6
|
+
|
7
|
+
it "create a new Configuration"
|
8
|
+
it "create a new Configuration via find_or_create"
|
9
|
+
it "update an existing Configuration via find_or_create"
|
10
|
+
it "delete an existing Configuration"
|
11
|
+
it "return all Configurations"
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "should not" do
|
16
|
+
|
17
|
+
it "create a new Configuration without a name"
|
18
|
+
it "create a new Configuration without a format"
|
19
|
+
it "create a new Configuration without a body"
|
20
|
+
it "create a new Configuration without an Application"
|
21
|
+
it "create a duplicate Configuration"
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|