1
2
3
4
5
6
7
8
9
10
11
12
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
module Noah
class Link < Model
attribute :path
attribute :nodes
index :path
index :nodes
def nodes
arr = []
self.key[:nodes].smembers.each do |node|
arr << node
end
arr
end
def nodes=(node)
case node.class.to_s
when "Array"
node.each do |n|
self.key[:nodes].sadd(n.key)
n.links << self
end
else
self.key[:nodes].sadd(node.key)
n.links << self
end
end
def validate
super
assert_present :path
end
def to_hash
# TODO Holy shit, is this messy or what?
# Prepopulate instance variables of each object type instead?
%w[applications configurations hosts services ephemerals].each {|x| instance_variable_set("@#{x}", Hash.new)}
if nodes.size > 0
nodes.each do |node|
n = node_to_class(node)
cls = class_to_lower(n.class.to_s)
hsh = instance_variable_get("@#{cls}s")
# all of this bs is because services are unique per [servicename, hostname]
# so if I add multiple services just by name to the hash, I'll wipe the previous one
# a better option would be for services to be named slug style
hsh["#{n.name}"] = Hash.new unless hsh.has_key?(n.name)
case cls
when "service"
sh = Noah::Host[n.host_id].name
hsh["#{n.name}"]["#{sh}"] = Hash.new unless hsh["#{n.name}"].has_key?("#{sh}")
hsh["#{n.name}"]["#{sh}"].merge!({:id => n.id, :status => n.status, :tags => n.to_hash[:tags]})
when "host"
hsh["#{n.name}"].merge!({:id => n.id, :status => n.status, :tags => n.to_hash[:tags], :services => n.to_hash[:services]})
else
hsh[n.name].merge!(n.to_hash.reject{|key, value| key == :created_at || key == :updated_at || key == :name})
end
end
end
h = {:name => name, :hosts => @hosts, :services => @services, :applications => @applications, :configurations => @configurations, :ephemerals => @ephemerals, :created_at => created_at, :updated_at => updated_at}
super.merge(h)
end
def name
@name = path
end
class <<self
def find_or_create(opts={})
begin
find(opts).first.nil? ? obj=new(opts) : obj=find(opts).first
if obj.valid?
obj.save
end
obj
rescue Exception => e
e.message
end
end
end
private
def node_to_class(node)
node.match(/^Noah::(.*):(\d+)$/)
Noah.const_get($1).send(:[], $2)
end
end
end