Commit 1941fd0c authored by John E. Vincent's avatar John E. Vincent

major refactor of hosts and services. convert ids to guids

parent 8ea031e9
......@@ -59,7 +59,28 @@ module Noah
else
Noah::Services.all(:host_id => id)
end
end
end
def find_hosts_by_service(servicename)
affected_hosts = []
s = Noah::Service.find(:name => servicename)
if s.nil?
affected_hosts
else
Noah::Host.all.each {|x| affected_hosts << x if (x.services.to_a & s.to_a).length > 0}
affected_hosts
end
end
def delete_service_from_host(servicename, hostname)
host = Noah::Host.find(:name => hostname).first
(halt 404) if host.nil?
service = Noah::Service.find(:name => servicename, :host_id => host.id).first
(halt 404) if service.nil?
service.delete
r = {"action" => "delete", "result" => "success", "id" => service.id, "host" => host.name, "service" => servicename}
r.to_json
end
def application(opts = {})
Noah::Application.find(opts).first
......
require 'ohm'
require 'ohm/contrib'
require 'guid'
module Noah
class Model < Ohm::Model
......@@ -96,6 +98,11 @@ module Noah
end
end
private
def initialize_id
@id ||= Guid.new.to_s
end
end
class RegisteredModels
......
......@@ -11,6 +11,7 @@ module Noah
index :name
index :status
index :services
def validate
super
......@@ -33,9 +34,9 @@ module Noah
class << self
def find_or_create(opts = {})
begin
# exclude requested status from lookup
h = find(opts.reject{|key,value| key == :status}).first
host = h.nil? ? create(opts) : h
h = find(:name => opts[:name]).first
#h = find(opts.reject{|key,value| key == :status}).first
h.nil? ? host=new(opts) : host=h
host.status = opts[:status]
if host.valid?
host.save
......
......@@ -33,8 +33,8 @@ module Noah
opts.reject!{|key, value| key == :host}
end
# exclude requested status from lookup
s = find(opts.reject{|key,value| key == :status}).first
service = s.nil? ? create(opts) : s
s = find(:name => opts[:name], :host_id => opts[:host_id]).first
s.nil? ? service=new(opts) : service=s
service.status = opts[:status]
if service.valid?
service.save
......
......@@ -48,7 +48,7 @@ module Noah
private
def node_to_class(node)
node.match(/^Noah::(.*):(\d+)$/)
node.match(/^Noah::(.*):(.*)$/)
Noah.const_get($1).send(:[], $2)
end
......
......@@ -2,7 +2,7 @@ class Noah::App
# Host URIs
# GET named {Service} for named {Host}
get '/hosts/:hostname/:servicename/?' do |hostname, servicename|
get '/hosts/:hostname/services/:servicename/?' do |hostname, servicename|
h = host_service(hostname, servicename)
if h.nil?
halt 404
......@@ -35,6 +35,7 @@ class Noah::App
put '/hosts/:hostname/tag' do |hostname|
required_params = ["tags"]
data = JSON.parse(request.body.read)
raise "Missing parameters" if data.nil?
(data.keys.sort == required_params.sort) ? (a=Noah::Host.find(:name=>hostname).first) : (raise "Missing Parameters")
a.nil? ? (halt 404) : (a.tag!(data['tags']))
a.to_json
......@@ -43,6 +44,7 @@ class Noah::App
put '/hosts/:hostname/watch' do |hostname|
required_params = ["endpoint"]
data = JSON.parse(request.body.read)
raise "Missing parameters" if data.nil?
(data.keys.sort == required_params.sort) ? (h = Noah::Host.find(:name => hostname).first) : (raise "Missing Parameters")
h.nil? ? (halt 404) : (w = h.watch!(:endpoint => data['endpoint']))
w.to_json
......@@ -51,15 +53,17 @@ class Noah::App
put '/hosts/:hostname/link' do |hostname|
required_params = ["link_name"]
data = JSON.parse(request.body.read)
raise "Missing parameters" if data.nil?
(data.keys.sort == required_params.sort) ? (a = Noah::Host.find(:name => hostname).first) : (raise "Missing Parameters")
a.nil? ? (halt 404) : (a.link! data["link_name"])
a.to_json
end
put '/hosts/:hostname/?' do |hostname|
required_params = ["name", "status"]
required_params = ["status"]
data = JSON.parse(request.body.read)
(data.keys.sort == required_params.sort && data['name'] == hostname) ? (host = Noah::Host.find_or_create(:name => data['name'], :status => data['status'])) : (raise "Missing Parameters")
raise "Missing parameters" if data.nil?
(data.keys.sort == required_params.sort) ? (host = Noah::Host.find_or_create(:name => hostname, :status => data['status'])) : (raise "Missing Parameters")
if host.valid?
r = {"result" => "success","id" => "#{host.id}","status" => "#{host.status}", "name" => "#{host.name}", "new_record" => host.is_new?}
r.to_json
......@@ -70,15 +74,16 @@ class Noah::App
delete '/hosts/:hostname/?' do |hostname|
host = Noah::Host.find(:name => hostname).first
if host
services = []
Noah::Service.find(:host_id => host.id).sort.each {|x| services << x; x.delete} if host.services.size > 0
host.delete
r = {"result" => "success", "id" => "#{host.id}", "name" => "#{hostname}", "service_count" => "#{services.size}"}
r.to_json
else
halt 404
end
(halt 404) if host.nil?
services = []
Noah::Service.find(:host_id => host.id).sort.each {|x| services << x; x.delete} if host.services.size > 0
host.delete
r = {"result" => "success", "id" => "#{host.id}", "name" => "#{hostname}", "service_count" => "#{services.size}"}
r.to_json
end
delete '/hosts/:hostname/services/:servicename/?' do |hostname, servicename|
delete_service_from_host(servicename, hostname)
end
end
......@@ -54,19 +54,26 @@ class Noah::App
w.to_json
end
put '/services/:servicename/?' do |servicename|
required_params = ["status", "host", "name"]
put '/services/:servicename/:hostname?' do |servicename, hostname|
required_params = ["status", "host_status"]
data = JSON.parse(request.body.read)
raise ("Missing Parameters") if data.nil?
if data.keys.sort == required_params.sort
h = Noah::Host.find(:name => data['host']).first || (raise "Invalid Host")
service = Noah::Service.find_or_create(:name => servicename, :status => data['status'], :host => h)
if service.valid?
action = service.is_new? ? "create" : "update"
service.save
r = {"action" => action, "result" => "success", "id" => service.id, "host" => h.name, "name" => service.name}
r.to_json
else
raise "#{format_errors(service)}"
begin
host = Noah::Host.find_or_create(:name => hostname, :status => data['host_status'])
if host.valid?
service = Noah::Service.find_or_create(:name => servicename, :status => data['status'], :host => host)
if service.valid?
service_action = service.is_new? ? "create" : "update"
host_action = host.is_new? ? "create" : "update"
r = {"action" => service_action, "result" => "success", "id" => service.id, "name" => service.name, "host" => {"name" => host.name, "action" => host_action, "status" => host.status}}
r.to_json
else
raise "#{format_errors(service)}"
end
else
raise "#{format_errors(host)}"
end
end
else
raise "Missing Parameters"
......@@ -74,14 +81,15 @@ class Noah::App
end
delete '/services/:servicename/:hostname/?' do |servicename, hostname|
host = Noah::Host.find(:name => hostname).first || (halt 404)
service = Noah::Service.find(:name => servicename, :host_id => host.id).first || (halt 404)
if host && service
service.delete
r = {"action" => "delete", "result" => "success", "id" => service.id, "host" => host.name, "service" => servicename}
r.to_json
else
halt 404
end
end
delete_service_from_host(servicename, hostname)
end
delete '/services/:servicename/?' do |servicename|
affected_hosts = find_hosts_by_service(servicename)
(halt 404) if affected_hosts.size == 0
service = Noah::Service.find(:name => servicename)
service.each {|x| x.delete}
r = {"action" => "delete", "result" => "success", "affected_hosts" => affected_hosts.size, "service" => servicename}
r.to_json
end
end
......@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
s.add_dependency("ohm-contrib", ["= 0.1.1"])
s.add_dependency("haml", ["= 3.0.25"])
s.add_dependency("vegas", ["= 0.1.8"])
s.add_dependency("guid", ["= 0.1.1"])
if RUBY_PLATFORM =~ /java/
......
......@@ -26,10 +26,10 @@ describe "Using the Host Model", :reset_redis => true do
host.name.should == hostname
host.status.should == hoststatus
host.services.size.should == 1
host.services[1].valid?.should == true
host.services[1].name.should == servicename
host.services[1].status.should == servicestatus
host.services[1].host_id.should == host.id
host.services.first.valid?.should == true
host.services.first.name.should == servicename
host.services.first.status.should == servicestatus
host.services.first.host_id.should == host.id
end
it "create a Host via find_or_create" do
......
......@@ -114,9 +114,7 @@ describe "Using the Configuration API", :reset_redis => true, :populate_sample_d
@c = Noah::Configuration.create(cparms)
@a.configurations << @c
get "/configurations/asdf"
p last_response
delete "/configurations/#{@c.name}"
p last_response
last_response.should be_ok
response = last_response.should return_json
response["result"].should == "success"
......
......@@ -27,7 +27,7 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
end
it "named service for host should work" do
get '/hosts/localhost/noah'
get '/hosts/localhost/services/noah'
last_response.should be_ok
response = last_response.should return_json
......@@ -39,7 +39,7 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
describe "PUT" do
it "new host should work" do
host_data = {:name => "host99.domain.com", :status => "down"}.to_json
host_data = {:status => "down"}.to_json
put '/hosts/host99.domain.com', host_data, "CONTENT_TYPE" => "application/json"
last_response.should be_ok
response = last_response.should return_json
......@@ -53,7 +53,7 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
it "existing host should work" do
sleep 3
host_data = {:name => "host99.domain.com", :status => "pending"}.to_json
host_data = {:status => "pending"}.to_json
put '/hosts/host99.domain.com', host_data, "CONTENT_TYPE" => "application/json"
last_response.should be_ok
response = last_response.should return_json
......@@ -61,20 +61,13 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
response["new_record"].should == false
end
it "host missing name parameter should not work" do
host_data = {:status => "pending"}.to_json
put '/hosts/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
last_response.should be_invalid
end
it "host missing status parameter should not work" do
host_data = {:name => "host100.domain.com"}.to_json
put '/hosts/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
put '/hosts/host100.domain.com', "{}", "CONTENT_TYPE" => "application/json"
last_response.should be_invalid
end
it "host with invalid status parameter should not work" do
host_data = {:name => "host100.domain.com", :status => "fscked"}.to_json
host_data = {:status => "fscked"}.to_json
put '/hosts/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
last_response.should_not be_ok
response = last_response.should return_json
......@@ -85,7 +78,8 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
end
describe "DELETE" do
before(:all) do
before(:each) do
Ohm.redis.flushdb
@h = Noah::Host.create(:name => 'h', :status => 'up')
sparms = {:name => 's', :status => "up"}
@h.services << Noah::Service.create(sparms.merge({:host => @h}))
......@@ -97,15 +91,25 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
delete "/hosts/#{@h.name}"
last_response.should be_ok
response = last_response.should return_json
response["result"].should == "success"
response["id"].should == @h.id
response["name"].should == @h.name
response["service_count"].should == svc_size.to_s
end
it "valid service from valid host should work" do
delete "/hosts/#{@h.name}/services/#{@s.name}"
last_response.should be_ok
response = last_response.should return_json
response["result"].should == "success"
response["action"].should == "delete"
response["id"].should == @s.id
response["host"].should == @h.name
response["service"].should == @s.name
end
it "invalid host should not work" do
delete "/hosts/#{@h.name}"
delete "/hosts/not_a_valid_hsot"
last_response.should be_missing
end
end
......
......@@ -46,76 +46,143 @@ describe "Using the Service API", :reset_redis => false, :populate_sample_data =
end
describe "PUT" do
before(:all) do
@payload = {:name => 'another_rspec_service', :status => 'up', :host => @h.name}
end
it "new service should work" do
put "/services/#{@payload[:name]}/", @payload.to_json, "CONTENT_TYPE" => "application/json"
before(:each) do
Ohm.redis.flushdb
@host_name = 'rspec_sample_host'
@service_name = 'rspec_sample_service'
@payload = {:status => 'up', :host_status => 'up'}
end
after(:each) do
Ohm.redis.flushdb
end
it "new service on new host should work" do
put "/services/#{@service_name}/#{@host_name}", @payload.to_json, "CONTENT_TYPE" => "application/json"
last_response.should be_ok
response = last_response.should return_json
response["result"].should == "success"
response["action"].should == "create"
response["id"].nil?.should == false
response["name"].should == @payload[:name]
response["host"].should == @payload[:host]
Noah::Service.find(:name => @payload[:name]).size.should == 1
Noah::Service.find(:name => @payload[:name]).first.is_new?.should == true
response["name"].should == @service_name
response["host"]["name"].should == @host_name
response["host"]["status"].should == 'up'
response["host"]["action"].should == 'create'
response["host"]["status"].should == 'up'
Noah::Service.find(:name => @service_name).size.should == 1
Noah::Service.find(:name => @service_name).first.is_new?.should == true
Noah::Host.find(:name => @host_name).size.should == 1
Noah::Host.find(:name => @host_name).first.is_new?.should == true
end
it "new service without host should not work" do
put "/services/foobar", {:name => "foobar", :status => "up"}.to_json, "CONTENT_TYPE" => "application/json"
last_response.should be_invalid
it "new service on existing host should work" do
hostname = 'non-existant-rspec-host'
servicename = 'non-existant-rspec-service'
Noah::Host.create(:name => hostname, :status => 'up')
sleep(3)
put "/services/#{servicename}/#{hostname}", @payload.to_json, "CONTENT_TYPE" => "application/json"
last_response.should be_ok
response = last_response.should return_json
response["result"].should == "success"
response["action"].should == "create"
response["id"].nil?.should == false
response["name"].should == servicename
response["host"]["name"].should == hostname
response["host"]["status"].should == 'up'
response["host"]["action"].should == 'update'
Noah::Service.find(:name => servicename).size.should == 1
Noah::Service.find(:name => servicename).first.is_new?.should == true
end
it "new service with invalid host status should not work" do
put "/services/foobar/#{@host_name}", {:host_status => "fsck", :status => "up"}.to_json, "CONTENT_TYPE" => "application/json"
last_response.should_not be_ok
response = last_response.should return_json
response["error_message"].should == "Status must be up, down or pending"
end
it "new service with invalid status should not work" do
put "/services/foobar", {:name => "foobar", :status => "fsck", :host => @h.name}.to_json, "CONTENT_TYPE" => "application/json"
it "new service with invalid service status should not work" do
put "/services/foobar/#{@host_name}", {:host_status => "up", :status => "fsck"}.to_json, "CONTENT_TYPE" => "application/json"
last_response.should_not be_ok
response = last_response.should return_json
response["error_message"].should == "Status must be up, down or pending"
end
it "new service with missing name should not work" do
put "/services/foobar", {:status => "fsck", :host => @h.name}.to_json, "CONTENT_TYPE" => "application/json"
it "new service with missing host_status should not work" do
put "/services/foobar/#{@host_name}", {:status => "up"}.to_json, "CONTENT_TYPE" => "application/json"
last_response.should be_invalid
end
it "new service with missing status should not work" do
put "/services/foobar", {:name => "foobar", :host => @h.name}.to_json, "CONTENT_TYPE" => "application/json"
put "/services/foobar/#{@host_name}", {:host_status => 'up'}.to_json, "CONTENT_TYPE" => "application/json"
last_response.should be_invalid
end
it "existing service should work" do
sleep 3
put "/services/#{@payload[:name]}", {:name => @payload[:name], :status => "down", :host => @payload[:host]}.to_json, "CONTENT_TYPE" => "application/json"
a = Noah::Host.create(:name => @host_name, :status => 'up')
b = Noah::Service.create(:name => @service_name, :status => 'pending', :host => a)
sleep(3)
put "/services/#{@service_name}/#{@host_name}", @payload.to_json, "CONTENT_TYPE" => "application/json"
last_response.should be_ok
response = last_response.should return_json
response["result"].should == "success"
response["action"].should == "update"
response["id"].nil?.should == false
response["name"].should == @payload[:name]
response["host"].should == @payload[:host]
Noah::Service.find(:name => @payload[:name]).size.should == 1
Noah::Service.find(:name => @payload[:name]).first.is_new?.should == false
response["name"].should == @service_name
response["host"]["name"].should == @host_name
response["host"]["status"].should == 'up'
response["host"]["action"].should == 'update'
end
end
describe "DELETE" do
before(:all) do
Ohm.redis.flushdb
@h = Noah::Host.create(:name => "h1", :status => "up")
@h.services << Noah::Service.create(:name => "s1", :status => "up", :host => @h)
@h.save
@s = @h.services.first
end
it "existing host should work" do
it "service from existing host should work" do
delete "/services/#{@s.name}/#{@h.name}"
last_response.should be_ok
response = last_response.should return_json
response["result"].should == "success"
response["action"].should == "delete"
response["id"].should == @s.id
response["host"].should == @h.name
response["service"].should == @s.name
end
it "invalid host should not work" do
end
it "all entries for a valid service" do
all_svc_name = 'my_sample_service'
foo_svc_name = 'my_sample_service_two'
bar_svc_name = 'my_sample_service_three'
%w[foo bar baz].each do |host|
h = Noah::Host.create(:name => host, :status => "up")
Noah::Service.create(:name => all_svc_name, :status => 'up', :host => h)
end
foo_host = Noah::Host.find(:name => 'foo').first
bar_host = Noah::Host.find(:name => 'bar').first
Noah::Service.create(:name => foo_svc_name, :status => 'down', :host => foo_host)
Noah::Service.create(:name => bar_svc_name, :status => 'pending', :host => bar_host)
delete "/services/#{all_svc_name}"
last_response.should be_ok
response = last_response.should return_json
response["result"].should == "success"
response["action"].should == "delete"
response["affected_hosts"].should == 3
delete "/services/#{foo_svc_name}"
last_response.should be_ok
response = last_response.should return_json
response["affected_hosts"].should == 1
end
it "service for invalid host should not work" do
delete "/services/#{@s.name}/#{@h.name}"
last_response.should be_missing
end
it "invalid service for valid host should not work" do
Noah::Host.create(:name => 'valid_host', :status => 'up')
delete "/services/not_really_here/valid_host"
last_response.should be_missing
end
it "all entries for an invalid service should not_work" do
delete "/services/not_really_here"
last_response.should be_missing
end
end
end
......
......@@ -16,7 +16,7 @@ describe "Noah Service Model", :reset_redis => true do
service.name.should == servicename
service.status.should == servicestatus
service.host_id.should == host.id
host.services[1].name.should == servicename
host.services[service.id].name.should == servicename
end
it "create a new Service with find_or_create" do
......
......@@ -78,9 +78,8 @@ l1.nodes = [a1, c2, Noah::Host.find(:name => 'localhost').first, Noah::Service.f
a1.tag! ["production", "sample_data"]
e2.tag! ["ephemeral", "development"]
c1.tag! "development"
Noah::Service[1].tag! "development"
Noah::Service[2].tag! ["development", "out-of-service"]
Noah::Service[2].link! "/my_sample_organization"
Noah::Service.all.first.tag! ["development", "out-of-service"]
Noah::Service.all.first.link! "/my_sample_organization"
puts "Sample data populated!"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment