noah 0.4-jruby → 0.6.pre-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.
- data/Rakefile +2 -69
- data/lib/noah.rb +1 -0
- data/lib/noah/agent.rb +1 -0
- data/lib/noah/agents/base_agent.rb +4 -2
- data/lib/noah/agents/http_agent.rb +1 -1
- data/lib/noah/agents/https_agent.rb +6 -0
- data/lib/noah/app.rb +8 -6
- data/lib/noah/exceptions.rb +0 -0
- data/lib/noah/linkable.rb +21 -0
- data/lib/noah/models.rb +14 -25
- data/lib/noah/models/applications.rb +19 -9
- data/lib/noah/models/configurations.rb +32 -13
- data/lib/noah/models/ephemerals.rb +7 -6
- data/lib/noah/models/hosts.rb +11 -5
- data/lib/noah/models/link.rb +70 -29
- data/lib/noah/models/services.rb +11 -2
- data/lib/noah/models/tags.rb +86 -5
- data/lib/noah/models/watchers.rb +0 -1
- data/lib/noah/{application_routes.rb → routes/applications.rb} +31 -27
- data/lib/noah/routes/configurations.rb +77 -0
- data/lib/noah/{ephemeral_routes.rb → routes/ephemerals.rb} +5 -5
- data/lib/noah/{host_routes.rb → routes/hosts.rb} +16 -1
- data/lib/noah/routes/links.rb +16 -0
- data/lib/noah/{service_routes.rb → routes/services.rb} +28 -12
- data/lib/noah/routes/tags.rb +15 -0
- data/lib/noah/{watcher_routes.rb → routes/watchers.rb} +0 -0
- data/lib/noah/taggable.rb +30 -0
- data/lib/noah/version.rb +1 -1
- data/noah.gemspec +5 -4
- data/spec/application_spec.rb +3 -3
- data/spec/configuration_spec.rb +19 -12
- data/spec/host_spec.rb +5 -5
- data/spec/noahapp_application_spec.rb +11 -13
- data/spec/noahapp_configuration_spec.rb +63 -40
- data/spec/noahapp_ephemeral_spec.rb +15 -15
- data/spec/noahapp_host_spec.rb +4 -6
- data/spec/noahapp_service_spec.rb +8 -7
- data/spec/service_spec.rb +2 -2
- data/spec/spec_helper.rb +5 -5
- data/spec/support/sample_data.rb +87 -0
- data/spec/tag_spec.rb +78 -0
- data/views/index.haml +7 -1
- metadata +335 -311
- data/lib/noah/configuration_routes.rb +0 -81
- data/lib/noah/models/link_member.rb +0 -18
data/lib/noah/models/hosts.rb
CHANGED
@@ -3,7 +3,8 @@ module Noah
|
|
3
3
|
class Host < Model
|
4
4
|
# Host model
|
5
5
|
# @return {Host} a {Host} object
|
6
|
-
|
6
|
+
include Taggable
|
7
|
+
include Linkable
|
7
8
|
attribute :name
|
8
9
|
attribute :status
|
9
10
|
collection :services, Service
|
@@ -21,9 +22,11 @@ module Noah
|
|
21
22
|
|
22
23
|
# @return [Hash] A hash representation of a {Host}
|
23
24
|
def to_hash
|
24
|
-
|
25
|
-
services.sort.each
|
26
|
-
|
25
|
+
services_hash = Hash.new
|
26
|
+
services.sort.each do |svc|
|
27
|
+
services_hash["#{svc.name}"] = svc.status
|
28
|
+
end
|
29
|
+
h = {:name => name, :status => status, :created_at => created_at, :updated_at => updated_at, :services => services_hash}
|
27
30
|
super.merge(h)
|
28
31
|
end
|
29
32
|
|
@@ -50,7 +53,10 @@ module Noah
|
|
50
53
|
# @param [Hash] optional filters for results
|
51
54
|
# @return [Array] Array of {Host} objects
|
52
55
|
def self.all(options = {})
|
53
|
-
|
56
|
+
host_hash = Hash.new
|
57
|
+
options.empty? ? hosts=Noah::Host.all.sort : hosts=Noah::Host.find(options).sort
|
58
|
+
hosts.each {|x| host_hash["#{x.name}"] = x.to_hash.reject {|k,v| k == :name } }
|
59
|
+
host_hash
|
54
60
|
end
|
55
61
|
end
|
56
62
|
end
|
data/lib/noah/models/link.rb
CHANGED
@@ -1,45 +1,86 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'link_member')
|
2
1
|
module Noah
|
3
2
|
class Link < Model
|
4
3
|
attribute :path
|
5
|
-
|
6
|
-
|
4
|
+
attribute :nodes
|
5
|
+
|
7
6
|
index :path
|
7
|
+
index :nodes
|
8
|
+
|
9
|
+
def nodes
|
10
|
+
arr = []
|
11
|
+
self.key[:nodes].smembers.each do |node|
|
12
|
+
arr << node
|
13
|
+
end
|
14
|
+
arr
|
15
|
+
end
|
16
|
+
|
17
|
+
def nodes=(node)
|
18
|
+
case node.class.to_s
|
19
|
+
when "Array"
|
20
|
+
node.each do |n|
|
21
|
+
self.key[:nodes].sadd(n.key)
|
22
|
+
n.links << self
|
23
|
+
end
|
24
|
+
else
|
25
|
+
self.key[:nodes].sadd(node.key)
|
26
|
+
node.links << self
|
27
|
+
end
|
28
|
+
end
|
8
29
|
|
9
30
|
def validate
|
10
31
|
super
|
11
32
|
assert_present :path
|
12
33
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
|
35
|
+
def to_hash
|
36
|
+
# TODO Holy shit, is this messy or what?
|
37
|
+
# Prepopulate instance variables of each object type instead?
|
38
|
+
%w[applications configurations hosts services ephemerals].each {|x| instance_variable_set("@#{x}", Hash.new)}
|
39
|
+
if nodes.size > 0
|
40
|
+
nodes.each do |node|
|
41
|
+
rejected_vals = [:created_at, :updated_at, :links, :name]
|
42
|
+
n = node_to_class(node)
|
43
|
+
cls = class_to_lower(n.class.to_s)
|
44
|
+
hsh = instance_variable_get("@#{cls}s")
|
45
|
+
# all of this bs is because services are unique per [servicename, hostname]
|
46
|
+
# so if I add multiple services just by name to the hash, I'll wipe the previous one
|
47
|
+
# a better option would be for services to be named slug style
|
48
|
+
hsh["#{n.name}"] = Hash.new unless hsh.has_key?(n.name)
|
49
|
+
case cls
|
50
|
+
when "service"
|
51
|
+
sh = Noah::Host[n.host_id].name
|
52
|
+
hsh["#{n.name}"]["#{sh}"] = Hash.new unless hsh["#{n.name}"].has_key?("#{sh}")
|
53
|
+
hsh["#{n.name}"]["#{sh}"].merge!({:id => n.id, :status => n.status, :tags => n.to_hash[:tags]})
|
54
|
+
when "host"
|
55
|
+
hsh["#{n.name}"].merge!({:id => n.id, :status => n.status, :tags => n.to_hash[:tags], :services => n.to_hash[:services]})
|
56
|
+
else
|
57
|
+
hsh["#{n.name}"].merge!(n.to_hash.reject{|key, value| rejected_vals.member?(key)})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
h = {:name => name, :hosts => @hosts, :services => @services, :applications => @applications, :configurations => @configurations, :ephemerals => @ephemerals, :created_at => created_at, :updated_at => updated_at}
|
62
|
+
super.merge(h)
|
63
|
+
end
|
39
64
|
|
40
65
|
def name
|
41
66
|
@name = path
|
42
67
|
end
|
43
68
|
|
69
|
+
class <<self
|
70
|
+
def find_or_create(opts={})
|
71
|
+
begin
|
72
|
+
find(opts).first.nil? ? obj=create(opts) : obj=find(opts).first
|
73
|
+
obj
|
74
|
+
rescue Exception => e
|
75
|
+
e.message
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
def node_to_class(node)
|
82
|
+
node.match(/^Noah::(.*):(\d+)$/)
|
83
|
+
Noah.const_get($1).send(:[], $2)
|
84
|
+
end
|
44
85
|
end
|
45
86
|
end
|
data/lib/noah/models/services.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module Noah
|
2
2
|
|
3
3
|
class Service < Model
|
4
|
-
|
4
|
+
include Taggable
|
5
|
+
include Linkable
|
5
6
|
attribute :name
|
6
7
|
attribute :status
|
7
8
|
reference :host, Host
|
@@ -48,7 +49,15 @@ module Noah
|
|
48
49
|
|
49
50
|
class Services
|
50
51
|
def self.all(options = {})
|
51
|
-
|
52
|
+
service_hash = Hash.new
|
53
|
+
options.empty? ? services=Service.all.sort : services=Service.find(options).sort
|
54
|
+
services.each do |svc|
|
55
|
+
service_hash["#{svc.name}"] = Hash.new unless service_hash.has_key?(svc.name)
|
56
|
+
host_name = Noah::Host[svc.host_id].name
|
57
|
+
service_hash["#{svc.name}"]["#{host_name}"] = Hash.new
|
58
|
+
service_hash["#{svc.name}"]["#{host_name}"].merge!({:id => svc.id, :status => svc.status, :tags => svc.to_hash[:tags], :links => svc.to_hash[:links], :created_at => svc.created_at, :updated_at => svc.updated_at})
|
59
|
+
end
|
60
|
+
service_hash
|
52
61
|
end
|
53
62
|
end
|
54
63
|
end
|
data/lib/noah/models/tags.rb
CHANGED
@@ -1,13 +1,94 @@
|
|
1
1
|
module Noah
|
2
|
+
|
2
3
|
class Tag < Model
|
3
|
-
|
4
|
+
attribute :name
|
5
|
+
attribute :members
|
6
|
+
index :members
|
7
|
+
index :name
|
8
|
+
|
9
|
+
def validate
|
10
|
+
super
|
11
|
+
assert_present :name
|
12
|
+
assert_unique :name
|
13
|
+
end
|
14
|
+
|
15
|
+
def members=(member)
|
16
|
+
self.key[:members].sadd(member.key)
|
17
|
+
member.tag! self.name unless member.tags.member?(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def members
|
21
|
+
hsh = Hash.new
|
22
|
+
self.key[:members].smembers.each do |member|
|
23
|
+
n = node_to_class(member)
|
24
|
+
cls = class_to_lower(n.class.to_s)
|
25
|
+
hash_key = "#{cls}s".to_sym
|
26
|
+
hsh[hash_key] = Array.new unless hsh.has_key?(hash_key)
|
27
|
+
hsh[hash_key] << n
|
28
|
+
end
|
29
|
+
hsh
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_hash
|
33
|
+
h = {:name => name, :created_at => created_at, :updated_at => updated_at}
|
34
|
+
h.merge!(members_to_hash)
|
35
|
+
super.merge(h)
|
36
|
+
end
|
37
|
+
|
38
|
+
class <<self
|
39
|
+
def find_or_create(opts={})
|
40
|
+
begin
|
41
|
+
find(opts).first.nil? ? obj=create(opts) : obj=find(opts).first
|
42
|
+
obj
|
43
|
+
rescue Exception => e
|
44
|
+
e.message
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def node_to_class(node)
|
51
|
+
node.match(/^Noah::(.*):(\d+)$/)
|
52
|
+
Noah.const_get($1).send(:[], $2)
|
53
|
+
end
|
54
|
+
|
55
|
+
def members_to_hash
|
56
|
+
new_hash = Hash.new
|
57
|
+
members.keys.each {|k| new_hash[k] = Hash.new}
|
58
|
+
members.each do |category, member_array|
|
59
|
+
rejected_vals = [:created_at, :updated_at, :tags, :name, :host]
|
60
|
+
h = new_hash[category]
|
61
|
+
member_array.each {|mem| h["#{mem.name}"] = Hash.new unless h.has_key?(mem.name)}
|
62
|
+
case category
|
63
|
+
when :services
|
64
|
+
member_array.each do |s|
|
65
|
+
sh = Noah::Host[s.host_id].name
|
66
|
+
h["#{s.name}"]["#{sh}"] = Hash.new unless h["#{s.name}"].has_key?(sh)
|
67
|
+
h["#{s.name}"]["#{sh}"].merge!(s.to_hash.reject{|k,v| rejected_vals.member?(k)})
|
68
|
+
end
|
69
|
+
else
|
70
|
+
member_array.each do |m|
|
71
|
+
h["#{m.name}"].merge!(m.to_hash.reject{|k,v| rejected_vals.member?(k)})
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
new_hash
|
76
|
+
end
|
77
|
+
end
|
4
78
|
|
5
|
-
|
6
|
-
|
79
|
+
class Tags
|
80
|
+
def self.all(options = {})
|
81
|
+
tag_hash = Hash.new
|
82
|
+
options.empty? ? tags=Tag.all.sort : tags=Tag.find(options).sort
|
83
|
+
tags.each {|t| tag_hash["#{t.name}"] = t.to_hash.reject {|k,v| k == :name } }
|
84
|
+
tag_hash
|
7
85
|
end
|
8
86
|
|
9
|
-
|
10
|
-
|
87
|
+
class <<self
|
88
|
+
def tagged(tag)
|
89
|
+
t = Tag.find(:name => tag).first
|
90
|
+
t.members
|
91
|
+
end
|
11
92
|
end
|
12
93
|
end
|
13
94
|
|
data/lib/noah/models/watchers.rb
CHANGED
@@ -2,21 +2,23 @@ class Noah::App
|
|
2
2
|
# Application URIs
|
3
3
|
get '/applications/:appname/:config/?' do |appname, config|
|
4
4
|
app = Noah::Application.find(:name => appname).first
|
5
|
-
if app.nil?
|
6
|
-
|
7
|
-
|
8
|
-
c = Noah::Configuration.find(:name => config, :application_id => app.id).first
|
9
|
-
c.to_json
|
10
|
-
end
|
5
|
+
(halt 404) if app.nil?
|
6
|
+
c = app.configurations.find(:name => config).first
|
7
|
+
c.to_json
|
11
8
|
end
|
12
9
|
|
13
10
|
get '/applications/:appname/?' do |appname|
|
14
11
|
app = Noah::Application.find(:name => appname).first
|
15
|
-
if app.nil?
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
(halt 404) if app.nil?
|
13
|
+
app.to_json
|
14
|
+
end
|
15
|
+
|
16
|
+
put '/applications/:appname/tag' do |appname|
|
17
|
+
required_params = ["tags"]
|
18
|
+
data = JSON.parse(request.body.read)
|
19
|
+
(data.keys.sort == required_params.sort) ? (a=Noah::Application.find(:name=>appname).first) : (raise "Missing Parameters")
|
20
|
+
a.nil? ? (halt 404) : (a.tag!(data['tags']))
|
21
|
+
a.to_json
|
20
22
|
end
|
21
23
|
|
22
24
|
put '/applications/:appname/watch' do |appname|
|
@@ -27,6 +29,14 @@ class Noah::App
|
|
27
29
|
w.to_json
|
28
30
|
end
|
29
31
|
|
32
|
+
put '/applications/:appname/link' do |appname|
|
33
|
+
required_params = ["link_name"]
|
34
|
+
data = JSON.parse(request.body.read)
|
35
|
+
(data.keys.sort == required_params.sort) ? (a = Noah::Application.find(:name => appname).first) : (raise "Missing Parameters")
|
36
|
+
a.nil? ? (halt 404) : (a.link! data["link_name"])
|
37
|
+
a.to_json
|
38
|
+
end
|
39
|
+
|
30
40
|
put '/applications/:appname/?' do |appname|
|
31
41
|
required_params = ["name"]
|
32
42
|
data = JSON.parse(request.body.read)
|
@@ -47,24 +57,18 @@ class Noah::App
|
|
47
57
|
|
48
58
|
delete '/applications/:appname/?' do |appname|
|
49
59
|
app = Noah::Application.find(:name => appname).first
|
50
|
-
if app.nil?
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
r.to_json
|
58
|
-
end
|
60
|
+
(halt 404) if app.nil?
|
61
|
+
app.delete
|
62
|
+
r = {"result" => "success", "action" => "delete", "id" => "#{app.id}", "name" => "#{appname}"}
|
63
|
+
r.to_json
|
64
|
+
end
|
65
|
+
|
66
|
+
delete '/applications/:appname/configurations/:configname/?' do |appname, configname|
|
59
67
|
end
|
60
68
|
|
61
69
|
get '/applications/?' do
|
62
|
-
apps =
|
63
|
-
|
64
|
-
|
65
|
-
halt 404
|
66
|
-
else
|
67
|
-
apps.to_json
|
68
|
-
end
|
70
|
+
apps = Noah::Applications.all
|
71
|
+
(halt 404) if apps.size == 0
|
72
|
+
apps.to_json
|
69
73
|
end
|
70
74
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class Noah::App
|
2
|
+
content_type_mapping = {
|
3
|
+
:yaml => "text/x-yaml",
|
4
|
+
:json => "application/json",
|
5
|
+
:xml => "text/xml",
|
6
|
+
:string => "text/plain"
|
7
|
+
}
|
8
|
+
# GET the raw data of a configuration object
|
9
|
+
get '/configurations/:configname/data/?' do |configname|
|
10
|
+
c = Noah::Configuration.find(:name => configname).first
|
11
|
+
(halt 404) if c.nil?
|
12
|
+
content_type content_type_mapping[c.format.to_sym] if content_type_mapping[c.format.to_sym]
|
13
|
+
response.headers['Content-Disposition'] = "attachment; filename=#{configname}"
|
14
|
+
c.body
|
15
|
+
end
|
16
|
+
# GET the JSON representation of a configuration object
|
17
|
+
get '/configurations/:configname/?' do |configname|
|
18
|
+
c = Noah::Configuration.find(:name => configname).first
|
19
|
+
(halt 404) if c.nil?
|
20
|
+
c.to_json
|
21
|
+
end
|
22
|
+
# GET all configurations
|
23
|
+
get '/configurations/?' do
|
24
|
+
configs = Noah::Configurations.all.to_hash
|
25
|
+
(halt 404) if configs.size == 0
|
26
|
+
configs.to_json
|
27
|
+
end
|
28
|
+
# Add configuration object to a custom link hierarchy
|
29
|
+
put '/configurations/:configname/link' do |configname|
|
30
|
+
required_params = ["link_name"]
|
31
|
+
data = JSON.parse(request.body.read)
|
32
|
+
(data.keys.sort == required_params.sort) ? (a = Noah::Configuration.find(:name => configname).first) : (raise "Missing Parameters")
|
33
|
+
a.nil? ? (halt 404) : (a.link! data["link_name"])
|
34
|
+
a.to_json
|
35
|
+
end
|
36
|
+
# Add a tag to a configuration object
|
37
|
+
put '/configurations/:configname/tag' do |configname|
|
38
|
+
required_params = ["tags"]
|
39
|
+
data = JSON.parse(request.body.read)
|
40
|
+
(data.keys.sort == required_params.sort) ? (c=Noah::Configuration.find(:name=>configname).first) : (raise "Missing Parameters")
|
41
|
+
c.nil? ? (halt 404) : (c.tag!(data['tags']))
|
42
|
+
c.to_json
|
43
|
+
|
44
|
+
end
|
45
|
+
# Add a watch to a configuration object
|
46
|
+
put '/configurations/:configname/watch' do |configname|
|
47
|
+
required_params = ["endpoint"]
|
48
|
+
data = JSON.parse(request.body.read)
|
49
|
+
(data.keys.sort == required_params.sort) ? (c = Noah::Configuration.find(:name => configname).first) : (raise "Missing Parameters")
|
50
|
+
c.nil? ? (halt 404) : (w = c.watch!(:endpoint => data['endpoint']))
|
51
|
+
w.to_json
|
52
|
+
end
|
53
|
+
# Attach a configuration object to an application object
|
54
|
+
put '/configurations/:configname/?' do |configname|
|
55
|
+
required_params = ["format", "body"]
|
56
|
+
data = JSON.parse(request.body.read)
|
57
|
+
data.keys.sort == required_params.sort ? config=Noah::Configuration.find_or_create(:name => configname) : (raise "Missing Parameters")
|
58
|
+
config.body = data["body"]
|
59
|
+
config.format = data["format"]
|
60
|
+
if config.valid?
|
61
|
+
config.save
|
62
|
+
action = config.is_new? ? "create" : "update"
|
63
|
+
r = {"result" => "success","id" => "#{config.id}", "action" => action, "item" => config.name}
|
64
|
+
r.to_json
|
65
|
+
else
|
66
|
+
raise "#{format_errors(config)}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
delete '/configurations/:configname/?' do |configname|
|
71
|
+
cfg = Noah::Configuration.find(:name => configname).first
|
72
|
+
(halt 404) if cfg.nil?
|
73
|
+
cfg.delete
|
74
|
+
r = {"result" => "success", "id" => cfg.id, "action" => "delete", "affected_applications" => cfg.affected_applications, "item" => cfg.name}
|
75
|
+
r.to_json
|
76
|
+
end
|
77
|
+
end
|