noah 0.4 → 0.6.pre
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/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/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/models.rb +14 -25
- 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/lib/noah.rb +1 -0
- 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 +23 -16
- data/lib/noah/configuration_routes.rb +0 -81
- data/lib/noah/models/link_member.rb +0 -18
data/Rakefile
CHANGED
@@ -11,7 +11,6 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
11
11
|
spec.pattern = FileList['spec/**/*_spec.rb']
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
14
|
task :default => :run
|
16
15
|
task :test => :run
|
17
16
|
|
@@ -40,75 +39,9 @@ end
|
|
40
39
|
desc "Populate database with sample dataset"
|
41
40
|
task :sample, :redis_url do |t, args|
|
42
41
|
require 'noah'
|
43
|
-
|
44
42
|
Ohm::connect(:url => args.redis_url)
|
45
|
-
|
46
|
-
|
47
|
-
Noah::Watcher.create :endpoint => "dummy://applications", :pattern => "//noah/applications"
|
48
|
-
Noah::Watcher.create :endpoint => "dummy://configurations", :pattern => "//noah/configurations"
|
49
|
-
Noah::Watcher.create :endpoint => "dummy://hosts", :pattern => "//noah/hosts"
|
50
|
-
Noah::Watcher.create :endpoint => "dummy://services", :pattern => "//noah/services"
|
51
|
-
Noah::Watcher.create :endpoint => "dummy://ephemerals", :pattern => "//noah/ephemerals"
|
52
|
-
puts "Creating Host entry for 'localhost'"
|
53
|
-
h = Noah::Host.create(:name => 'localhost', :status => "up")
|
54
|
-
if h.save
|
55
|
-
%w[redis noah].each do |service|
|
56
|
-
puts "Create Service entry for #{service}"
|
57
|
-
s = Noah::Service.create(:name => service, :status => "up", :host => h)
|
58
|
-
h.services << s
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
puts "Creating Application entry for 'noah'"
|
63
|
-
a = Noah::Application.create(:name => 'noah')
|
64
|
-
if a.save
|
65
|
-
puts "Creating Configuration entry for 'noah'"
|
66
|
-
cr = Noah::Configuration.create(:name => 'redis', :format => 'string', :body => 'redis://127.0.0.1:6379/0', :application => a)
|
67
|
-
ch = Noah::Configuration.create(:name => 'host', :format => 'string', :body => 'localhost', :application => a)
|
68
|
-
cp = Noah::Configuration.create(:name => 'port', :format => 'string', :body => '9292', :application => a)
|
69
|
-
%w[cr ch cp].each do |c|
|
70
|
-
a.configurations << eval(c)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
puts "Creating sample entries - Host and Service"
|
75
|
-
%w[host1.domain.com host2.domain.com host3.domain.com].each do |host|
|
76
|
-
h = Noah::Host.create(:name => host, :status => "up")
|
77
|
-
if h.save
|
78
|
-
%w[http https smtp mysql].each do |service|
|
79
|
-
s = Noah::Service.create(:name => service, :status => "pending", :host => h)
|
80
|
-
h.services << s
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
puts "Creating sample entries - Application and Configuration"
|
86
|
-
my_yaml = <<EOY
|
87
|
-
development:
|
88
|
-
database: development_database
|
89
|
-
adapter: mysql
|
90
|
-
username: dev_user
|
91
|
-
password: dev_password
|
92
|
-
EOY
|
93
|
-
my_json = <<EOJ
|
94
|
-
{
|
95
|
-
"id":"hostname",
|
96
|
-
"data":"localhost"
|
97
|
-
}
|
98
|
-
EOJ
|
99
|
-
|
100
|
-
a1 = Noah::Application.create(:name => 'myrailsapp1')
|
101
|
-
if a1.save
|
102
|
-
c1 = Noah::Configuration.create(:name => 'database.yml', :format => 'yaml', :body => my_yaml, :application => a1)
|
103
|
-
a1.configurations << c1
|
104
|
-
end
|
105
|
-
|
106
|
-
a2 = Noah::Application.create(:name => 'myrestapp1')
|
107
|
-
if a2.save
|
108
|
-
c2 = Noah::Configuration.create(:name => 'config.json', :format => 'json', :body => my_json, :application => a2)
|
109
|
-
a2.configurations << c2
|
110
|
-
end
|
111
|
-
puts "Sample data populated!"
|
43
|
+
sample_data = File.expand_path(File.join("..", "spec", "support","sample_data.rb"),__FILE__)
|
44
|
+
instance_eval(File.open(sample_data).read)
|
112
45
|
end
|
113
46
|
|
114
47
|
begin
|
data/lib/noah/agent.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module Noah::Agents
|
2
2
|
class Base
|
3
3
|
|
4
|
-
PREFIX = "base"
|
4
|
+
PREFIX = "base://"
|
5
5
|
NAME = "base-agent"
|
6
6
|
DEFAULT_CONCURRENCY = 1
|
7
|
+
NEEDS_TRANSFORM = false
|
7
8
|
|
8
9
|
def self.inherited(base)
|
9
10
|
Noah::Watchers.register_agent(base)
|
@@ -11,12 +12,13 @@ module Noah::Agents
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def notify(event, message, watch_list)
|
14
|
-
logger.info("#{self.class} worker initiated")
|
15
|
+
logger.info("#{self.class.to_s} worker initiated")
|
15
16
|
worklist = []
|
16
17
|
watch_list.select{|w| worklist << w[:endpoint] if (w[:endpoint] =~ /^#{self.class::PREFIX}/ && event =~ /^#{w[:pattern]}/) }
|
17
18
|
if worklist.size >= 1
|
18
19
|
logger.info("Dispatching message to #{worklist.size} #{self.class.to_s} endpoints")
|
19
20
|
EM::Iterator.new(worklist, self.class::DEFAULT_CONCURRENCY).each do |ep, iter|
|
21
|
+
ep, message = transform(ep, message) if self.class::NEEDS_TRANSFORM == true
|
20
22
|
work!(ep, message)
|
21
23
|
iter.next
|
22
24
|
end
|
data/lib/noah/app.rb
CHANGED
@@ -58,12 +58,14 @@ module Noah
|
|
58
58
|
erb :'500'
|
59
59
|
end
|
60
60
|
|
61
|
-
load File.join(File.dirname(__FILE__), '
|
62
|
-
load File.join(File.dirname(__FILE__), '
|
63
|
-
load File.join(File.dirname(__FILE__), '
|
64
|
-
load File.join(File.dirname(__FILE__), '
|
65
|
-
load File.join(File.dirname(__FILE__), '
|
66
|
-
load File.join(File.dirname(__FILE__), '
|
61
|
+
load File.join(File.dirname(__FILE__), 'routes/tags.rb')
|
62
|
+
load File.join(File.dirname(__FILE__), 'routes/hosts.rb')
|
63
|
+
load File.join(File.dirname(__FILE__), 'routes/services.rb')
|
64
|
+
load File.join(File.dirname(__FILE__), 'routes/applications.rb')
|
65
|
+
load File.join(File.dirname(__FILE__), 'routes/configurations.rb')
|
66
|
+
load File.join(File.dirname(__FILE__), 'routes/watchers.rb')
|
67
|
+
load File.join(File.dirname(__FILE__), 'routes/ephemerals.rb')
|
68
|
+
load File.join(File.dirname(__FILE__), 'routes/links.rb')
|
67
69
|
|
68
70
|
end
|
69
71
|
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Noah::Linkable
|
2
|
+
def self.included(model)
|
3
|
+
model.send :set, :links, ::Noah::Link
|
4
|
+
model.send :index, :links
|
5
|
+
end
|
6
|
+
|
7
|
+
def link!(link_name)
|
8
|
+
link = Noah::Link.find_or_create(:path => link_name)
|
9
|
+
link.nodes = self
|
10
|
+
links << link
|
11
|
+
end
|
12
|
+
|
13
|
+
def unlink!(link_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
link_arr = Array.new
|
18
|
+
self.links.sort.each {|l| link_arr << l.path} if self.links.size != 0
|
19
|
+
super.merge(:links => link_arr)
|
20
|
+
end
|
21
|
+
end
|
@@ -1,30 +1,36 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'configurations')
|
2
2
|
module Noah
|
3
3
|
class Application < Model
|
4
|
+
include Taggable
|
5
|
+
include Linkable
|
4
6
|
attribute :name
|
5
|
-
|
7
|
+
set :configurations, Configuration
|
6
8
|
|
7
9
|
index :name
|
10
|
+
index :configurations
|
8
11
|
|
9
12
|
def validate
|
10
13
|
super
|
11
14
|
assert_present :name
|
15
|
+
assert_unique :name
|
12
16
|
end
|
13
17
|
|
14
18
|
def to_hash
|
15
|
-
|
16
|
-
configurations.sort.each
|
17
|
-
|
19
|
+
cfg_hash = Hash.new
|
20
|
+
configurations.sort.each do |cfg|
|
21
|
+
cfg_hash["#{cfg.name}"] = {:format => cfg.to_hash[:format], :body => cfg.to_hash[:body]}
|
22
|
+
end
|
23
|
+
{name => {:id => id, :created_at => created_at, :updated_at => updated_at, :configurations => cfg_hash}}
|
18
24
|
end
|
19
25
|
|
20
26
|
class << self
|
21
27
|
def find_or_create(opts = {})
|
22
28
|
begin
|
23
|
-
find(opts).first.nil? ? (
|
24
|
-
if
|
25
|
-
|
29
|
+
find(opts).first.nil? ? (obj = new(opts)) : (obj = find(opts).first)
|
30
|
+
if obj.valid?
|
31
|
+
obj.save
|
26
32
|
end
|
27
|
-
|
33
|
+
obj
|
28
34
|
rescue Exception => e
|
29
35
|
e.message
|
30
36
|
end
|
@@ -35,7 +41,11 @@ module Noah
|
|
35
41
|
|
36
42
|
class Applications
|
37
43
|
def self.all(options = {})
|
38
|
-
|
44
|
+
app_hash = Hash.new
|
45
|
+
options.empty? ? apps=Application.all.sort : apps=Application.find(options).sort
|
46
|
+
#apps.each {|x| app_hash["#{x.name}"] = x.to_hash.reject {|k,v| k == :name} }
|
47
|
+
apps.each {|x| app_hash.merge!(x.to_hash) }
|
48
|
+
app_hash
|
39
49
|
end
|
40
50
|
end
|
41
51
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'applications')
|
1
2
|
module Noah
|
2
3
|
class Configuration < Model
|
3
|
-
|
4
|
+
include Taggable
|
5
|
+
include Linkable
|
4
6
|
attribute :name
|
5
7
|
attribute :format
|
6
8
|
attribute :body
|
7
|
-
attribute :new_record
|
8
|
-
reference :application, Application
|
9
9
|
|
10
10
|
index :name
|
11
11
|
index :format
|
@@ -16,23 +16,39 @@ module Noah
|
|
16
16
|
assert_present :name
|
17
17
|
assert_present :format
|
18
18
|
assert_present :body
|
19
|
-
|
20
|
-
assert_unique [:name, :application_id]
|
19
|
+
assert_unique :name
|
21
20
|
end
|
22
21
|
|
23
22
|
def to_hash
|
24
|
-
|
25
|
-
|
23
|
+
super.merge(:name => name, :format => format, :body => body, :created_at => created_at, :updated_at => updated_at)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Because we're not doing a 2-way relationship
|
27
|
+
# we need to clean up any applications that use
|
28
|
+
# this configuration ourself
|
29
|
+
def delete
|
30
|
+
@affected_applications = Array.new
|
31
|
+
Noah::Application.all.each do |app|
|
32
|
+
if app.configurations.member?(self)
|
33
|
+
app.configurations.delete(self)
|
34
|
+
@affected_applications << app.name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
super
|
38
|
+
end
|
39
|
+
|
40
|
+
def affected_applications
|
41
|
+
@affected_applications
|
26
42
|
end
|
27
43
|
|
28
44
|
class << self
|
29
45
|
def find_or_create(opts={})
|
30
46
|
begin
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
47
|
+
find(opts).first.nil? ? (obj = new(opts)) : (obj = find(opts).first)
|
48
|
+
if obj.valid?
|
49
|
+
obj.save
|
50
|
+
end
|
51
|
+
obj
|
36
52
|
rescue Exception => e
|
37
53
|
e.message
|
38
54
|
end
|
@@ -43,7 +59,10 @@ module Noah
|
|
43
59
|
|
44
60
|
class Configurations
|
45
61
|
def self.all(options = {})
|
46
|
-
|
62
|
+
config_hash = Hash.new
|
63
|
+
options.empty? ? configs=Configuration.all.sort : configs=Configuration.find(options).sort
|
64
|
+
configs.each {|x| config_hash["#{x.name}"] = x.to_hash.reject {|k,v| k == :name} }
|
65
|
+
config_hash
|
47
66
|
end
|
48
67
|
end
|
49
68
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Noah
|
2
2
|
class Ephemeral < Model
|
3
3
|
include EphemeralValidations
|
4
|
-
|
4
|
+
include Taggable
|
5
|
+
include Linkable
|
5
6
|
attribute :path
|
6
7
|
attribute :data
|
7
8
|
attribute :lifetime
|
@@ -28,12 +29,12 @@ module Noah
|
|
28
29
|
def find_or_create(opts = {})
|
29
30
|
begin
|
30
31
|
path, data = opts[:path], opts[:data]
|
31
|
-
find(:path => path).first.nil? ? (
|
32
|
-
|
33
|
-
if
|
34
|
-
|
32
|
+
find(:path => path).first.nil? ? (obj = new(:path => path)) : (obj = find(:path => path).first)
|
33
|
+
obj.data = data
|
34
|
+
if obj.valid?
|
35
|
+
obj.save
|
35
36
|
end
|
36
|
-
|
37
|
+
obj
|
37
38
|
rescue Exception => e
|
38
39
|
e.message
|
39
40
|
end
|
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