noah 0.6.pre → 0.8

Sign up to get free protection for your applications and to get access to all the features.
data/lib/noah/app.rb CHANGED
@@ -45,7 +45,7 @@ module Noah
45
45
  get '/' do
46
46
  content_type "text/html"
47
47
 
48
- haml :index, :format => :html5, :locals => {:redis_url => settings.redis_url, :noah_version => Noah::VERSION}
48
+ haml :index, :format => :html5, :locals => {:redis_version => Ohm.redis.info["redis_version"].to_s, :noah_version => Noah::VERSION}
49
49
  end
50
50
 
51
51
  not_found do
data/lib/noah/helpers.rb CHANGED
@@ -59,7 +59,54 @@ module Noah
59
59
  else
60
60
  Noah::Services.all(:host_id => id)
61
61
  end
62
- end
62
+ end
63
+
64
+ def find_hosts_by_service(servicename)
65
+ affected_hosts = []
66
+ s = Noah::Service.find(:name => servicename)
67
+ if s.nil?
68
+ affected_hosts
69
+ else
70
+ Noah::Host.all.each {|x| affected_hosts << x if (x.services.to_a & s.to_a).length > 0}
71
+ affected_hosts
72
+ end
73
+ end
74
+
75
+ def delete_service_from_host(servicename, hostname)
76
+ host = Noah::Host.find(:name => hostname).first
77
+ (halt 404) if host.nil?
78
+ service = Noah::Service.find(:name => servicename, :host_id => host.id).first
79
+ (halt 404) if service.nil?
80
+ service.delete
81
+ r = {"action" => "delete", "result" => "success", "id" => service.id, "host" => host.name, "service" => servicename}
82
+ r.to_json
83
+ end
84
+
85
+ def add_config_to_app(appname, config_hash)
86
+ begin
87
+ config = Noah::Configuration.find_or_create(config_hash)
88
+ if config.valid?
89
+ dep_action = config.is_new? ? "create" : "update"
90
+ else
91
+ raise "#{format_errors(config)}"
92
+ end
93
+ app = Noah::Application.find_or_create(:name => appname)
94
+ if app.valid?
95
+ action = app.is_new? ? "create" : "update"
96
+ app.configurations << config
97
+ r = {"result" => "success", "id" => "#{app.id}", "name" => "#{app.name}", "action" => action, "configuration" => {"action" => dep_action, "id" => "#{config.id}", "item" => "#{config.name}"}}
98
+ r.to_json
99
+ else
100
+ raise "#{format_errors(app)}"
101
+ end
102
+ rescue Exception => e
103
+ e.message
104
+ ensure
105
+ # Clean up partial objects
106
+ app.delete if app.valid? == false
107
+ config.delete if config.valid? == false
108
+ end
109
+ end
63
110
 
64
111
  def application(opts = {})
65
112
  Noah::Application.find(opts).first
@@ -20,7 +20,8 @@ module Noah
20
20
  configurations.sort.each do |cfg|
21
21
  cfg_hash["#{cfg.name}"] = {:format => cfg.to_hash[:format], :body => cfg.to_hash[:body]}
22
22
  end
23
- {name => {:id => id, :created_at => created_at, :updated_at => updated_at, :configurations => cfg_hash}}
23
+ res_hash = {:name => name, :created_at => created_at, :updated_at => updated_at, :configurations => cfg_hash}
24
+ super.merge(res_hash)
24
25
  end
25
26
 
26
27
  class << self
@@ -43,8 +44,7 @@ module Noah
43
44
  def self.all(options = {})
44
45
  app_hash = Hash.new
45
46
  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) }
47
+ apps.each {|x| app_hash["#{x.name}"] = x.to_hash.reject {|k,v| k == :name} }
48
48
  app_hash
49
49
  end
50
50
  end
@@ -44,9 +44,13 @@ module Noah
44
44
  class << self
45
45
  def find_or_create(opts={})
46
46
  begin
47
- find(opts).first.nil? ? (obj = new(opts)) : (obj = find(opts).first)
48
- if obj.valid?
47
+ find(:name => opts[:name]).first.nil? ? (obj = new(opts)) : (obj = find(:name => opts[:name]).first)
48
+ if obj.valid? && obj.new?
49
49
  obj.save
50
+ else
51
+ obj.format = opts[:format]
52
+ obj.body = opts[:body]
53
+ obj.save if obj.valid?
50
54
  end
51
55
  obj
52
56
  rescue Exception => e
@@ -11,6 +11,7 @@ module Noah
11
11
 
12
12
  index :name
13
13
  index :status
14
+ index :services
14
15
 
15
16
  def validate
16
17
  super
@@ -33,9 +34,9 @@ module Noah
33
34
  class << self
34
35
  def find_or_create(opts = {})
35
36
  begin
36
- # exclude requested status from lookup
37
- h = find(opts.reject{|key,value| key == :status}).first
38
- host = h.nil? ? create(opts) : h
37
+ h = find(:name => opts[:name]).first
38
+ #h = find(opts.reject{|key,value| key == :status}).first
39
+ h.nil? ? host=new(opts) : host=h
39
40
  host.status = opts[:status]
40
41
  if host.valid?
41
42
  host.save
@@ -33,8 +33,8 @@ module Noah
33
33
  opts.reject!{|key, value| key == :host}
34
34
  end
35
35
  # exclude requested status from lookup
36
- s = find(opts.reject{|key,value| key == :status}).first
37
- service = s.nil? ? create(opts) : s
36
+ s = find(:name => opts[:name], :host_id => opts[:host_id]).first
37
+ s.nil? ? service=new(opts) : service=s
38
38
  service.status = opts[:status]
39
39
  if service.valid?
40
40
  service.save
@@ -48,7 +48,7 @@ module Noah
48
48
 
49
49
  private
50
50
  def node_to_class(node)
51
- node.match(/^Noah::(.*):(\d+)$/)
51
+ node.match(/^Noah::(.*):(.*)$/)
52
52
  Noah.const_get($1).send(:[], $2)
53
53
  end
54
54
 
data/lib/noah/models.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'ohm'
2
2
  require 'ohm/contrib'
3
+ require 'guid'
4
+
3
5
  module Noah
4
6
  class Model < Ohm::Model
5
7
 
@@ -96,6 +98,11 @@ module Noah
96
98
  end
97
99
  end
98
100
 
101
+ private
102
+ def initialize_id
103
+ @id ||= Guid.new.to_s
104
+ end
105
+
99
106
  end
100
107
 
101
108
  class RegisteredModels
@@ -1,10 +1,10 @@
1
1
  class Noah::App
2
2
  # Application URIs
3
- get '/applications/:appname/:config/?' do |appname, config|
3
+ get '/applications/:appname/configurations/:config/?' do |appname, config|
4
4
  app = Noah::Application.find(:name => appname).first
5
5
  (halt 404) if app.nil?
6
- c = app.configurations.find(:name => config).first
7
- c.to_json
6
+ request.path_info = "/configurations/#{config}"
7
+ pass
8
8
  end
9
9
 
10
10
  get '/applications/:appname/?' do |appname|
@@ -37,6 +37,14 @@ class Noah::App
37
37
  a.to_json
38
38
  end
39
39
 
40
+ put '/applications/:appname/configurations/:configname/?' do |appname, configname|
41
+ required_params = ["format", "body"]
42
+ raise "Missing Parameters" if request.body.nil?
43
+ data = JSON.parse(request.body.read)
44
+ raise "Missing Parameters" if data.keys.sort != required_params.sort
45
+ add_config_to_app(appname, {:name => configname, :format => data['format'], :body => data['body']})
46
+ end
47
+
40
48
  put '/applications/:appname/?' do |appname|
41
49
  required_params = ["name"]
42
50
  data = JSON.parse(request.body.read)
@@ -64,6 +72,17 @@ class Noah::App
64
72
  end
65
73
 
66
74
  delete '/applications/:appname/configurations/:configname/?' do |appname, configname|
75
+ app = Noah::Application.find(:name => appname).first
76
+ (halt 404) if app.nil?
77
+ config = Noah::Configuration.find(:name => configname).first
78
+ (halt 404) if config.nil?
79
+ if app.configurations.member?(config)
80
+ app.configurations.delete(config)
81
+ r = {"result" => "success", "action" => "delete", "id" => "#{app.id}", "name" => "#{app.name}", "configuration" => "#{config.name}"}
82
+ r.to_json
83
+ else
84
+ halt 404
85
+ end
67
86
  end
68
87
 
69
88
  get '/applications/?' do
@@ -5,19 +5,17 @@ class Noah::App
5
5
  :xml => "text/xml",
6
6
  :string => "text/plain"
7
7
  }
8
- # GET the raw data of a configuration object
9
- get '/configurations/:configname/data/?' do |configname|
8
+ get '/configurations/:configname/?', :provides => :json do |configname|
10
9
  c = Noah::Configuration.find(:name => configname).first
11
10
  (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
11
+ c.to_json
15
12
  end
16
- # GET the JSON representation of a configuration object
17
13
  get '/configurations/:configname/?' do |configname|
18
14
  c = Noah::Configuration.find(:name => configname).first
19
15
  (halt 404) if c.nil?
20
- c.to_json
16
+ content_type content_type_mapping[c.format.to_sym] if content_type_mapping[c.format.to_sym]
17
+ #response.headers['Content-Disposition'] = "attachment; filename=#{configname}"
18
+ c.body
21
19
  end
22
20
  # GET all configurations
23
21
  get '/configurations/?' do
@@ -2,7 +2,7 @@ class Noah::App
2
2
  # Host URIs
3
3
 
4
4
  # GET named {Service} for named {Host}
5
- get '/hosts/:hostname/:servicename/?' do |hostname, servicename|
5
+ get '/hosts/:hostname/services/:servicename/?' do |hostname, servicename|
6
6
  h = host_service(hostname, servicename)
7
7
  if h.nil?
8
8
  halt 404
@@ -35,6 +35,7 @@ class Noah::App
35
35
  put '/hosts/:hostname/tag' do |hostname|
36
36
  required_params = ["tags"]
37
37
  data = JSON.parse(request.body.read)
38
+ raise "Missing parameters" if data.nil?
38
39
  (data.keys.sort == required_params.sort) ? (a=Noah::Host.find(:name=>hostname).first) : (raise "Missing Parameters")
39
40
  a.nil? ? (halt 404) : (a.tag!(data['tags']))
40
41
  a.to_json
@@ -43,6 +44,7 @@ class Noah::App
43
44
  put '/hosts/:hostname/watch' do |hostname|
44
45
  required_params = ["endpoint"]
45
46
  data = JSON.parse(request.body.read)
47
+ raise "Missing parameters" if data.nil?
46
48
  (data.keys.sort == required_params.sort) ? (h = Noah::Host.find(:name => hostname).first) : (raise "Missing Parameters")
47
49
  h.nil? ? (halt 404) : (w = h.watch!(:endpoint => data['endpoint']))
48
50
  w.to_json
@@ -51,15 +53,17 @@ class Noah::App
51
53
  put '/hosts/:hostname/link' do |hostname|
52
54
  required_params = ["link_name"]
53
55
  data = JSON.parse(request.body.read)
56
+ raise "Missing parameters" if data.nil?
54
57
  (data.keys.sort == required_params.sort) ? (a = Noah::Host.find(:name => hostname).first) : (raise "Missing Parameters")
55
58
  a.nil? ? (halt 404) : (a.link! data["link_name"])
56
59
  a.to_json
57
60
  end
58
61
 
59
62
  put '/hosts/:hostname/?' do |hostname|
60
- required_params = ["name", "status"]
63
+ required_params = ["status"]
61
64
  data = JSON.parse(request.body.read)
62
- (data.keys.sort == required_params.sort && data['name'] == hostname) ? (host = Noah::Host.find_or_create(:name => data['name'], :status => data['status'])) : (raise "Missing Parameters")
65
+ raise "Missing parameters" if data.nil?
66
+ (data.keys.sort == required_params.sort) ? (host = Noah::Host.find_or_create(:name => hostname, :status => data['status'])) : (raise "Missing Parameters")
63
67
  if host.valid?
64
68
  r = {"result" => "success","id" => "#{host.id}","status" => "#{host.status}", "name" => "#{host.name}", "new_record" => host.is_new?}
65
69
  r.to_json
@@ -70,15 +74,16 @@ class Noah::App
70
74
 
71
75
  delete '/hosts/:hostname/?' do |hostname|
72
76
  host = Noah::Host.find(:name => hostname).first
73
- if host
74
- services = []
75
- Noah::Service.find(:host_id => host.id).sort.each {|x| services << x; x.delete} if host.services.size > 0
76
- host.delete
77
- r = {"result" => "success", "id" => "#{host.id}", "name" => "#{hostname}", "service_count" => "#{services.size}"}
78
- r.to_json
79
- else
80
- halt 404
81
- end
77
+ (halt 404) if host.nil?
78
+ services = []
79
+ Noah::Service.find(:host_id => host.id).sort.each {|x| services << x; x.delete} if host.services.size > 0
80
+ host.delete
81
+ r = {"result" => "success", "id" => "#{host.id}", "name" => "#{hostname}", "service_count" => "#{services.size}"}
82
+ r.to_json
83
+ end
84
+
85
+ delete '/hosts/:hostname/services/:servicename/?' do |hostname, servicename|
86
+ delete_service_from_host(servicename, hostname)
82
87
  end
83
88
 
84
89
  end
@@ -54,19 +54,26 @@ class Noah::App
54
54
  w.to_json
55
55
  end
56
56
 
57
- put '/services/:servicename/?' do |servicename|
58
- required_params = ["status", "host", "name"]
57
+ put '/services/:servicename/:hostname?' do |servicename, hostname|
58
+ required_params = ["status", "host_status"]
59
59
  data = JSON.parse(request.body.read)
60
+ raise ("Missing Parameters") if data.nil?
60
61
  if data.keys.sort == required_params.sort
61
- h = Noah::Host.find(:name => data['host']).first || (raise "Invalid Host")
62
- service = Noah::Service.find_or_create(:name => servicename, :status => data['status'], :host => h)
63
- if service.valid?
64
- action = service.is_new? ? "create" : "update"
65
- service.save
66
- r = {"action" => action, "result" => "success", "id" => service.id, "host" => h.name, "name" => service.name}
67
- r.to_json
68
- else
69
- raise "#{format_errors(service)}"
62
+ begin
63
+ host = Noah::Host.find_or_create(:name => hostname, :status => data['host_status'])
64
+ if host.valid?
65
+ service = Noah::Service.find_or_create(:name => servicename, :status => data['status'], :host => host)
66
+ if service.valid?
67
+ service_action = service.is_new? ? "create" : "update"
68
+ host_action = host.is_new? ? "create" : "update"
69
+ r = {"action" => service_action, "result" => "success", "id" => service.id, "name" => service.name, "host" => {"name" => host.name, "action" => host_action, "status" => host.status}}
70
+ r.to_json
71
+ else
72
+ raise "#{format_errors(service)}"
73
+ end
74
+ else
75
+ raise "#{format_errors(host)}"
76
+ end
70
77
  end
71
78
  else
72
79
  raise "Missing Parameters"
@@ -74,14 +81,15 @@ class Noah::App
74
81
  end
75
82
 
76
83
  delete '/services/:servicename/:hostname/?' do |servicename, hostname|
77
- host = Noah::Host.find(:name => hostname).first || (halt 404)
78
- service = Noah::Service.find(:name => servicename, :host_id => host.id).first || (halt 404)
79
- if host && service
80
- service.delete
81
- r = {"action" => "delete", "result" => "success", "id" => service.id, "host" => host.name, "service" => servicename}
82
- r.to_json
83
- else
84
- halt 404
85
- end
86
- end
84
+ delete_service_from_host(servicename, hostname)
85
+ end
86
+
87
+ delete '/services/:servicename/?' do |servicename|
88
+ affected_hosts = find_hosts_by_service(servicename)
89
+ (halt 404) if affected_hosts.size == 0
90
+ service = Noah::Service.find(:name => servicename)
91
+ service.each {|x| x.delete}
92
+ r = {"action" => "delete", "result" => "success", "affected_hosts" => affected_hosts.size, "service" => servicename}
93
+ r.to_json
94
+ end
87
95
  end
data/lib/noah/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Noah
2
- VERSION = "0.6"
2
+ VERSION = "0.8"
3
3
  end
data/noah.gemspec CHANGED
@@ -4,7 +4,7 @@ require "noah/version"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "noah"
7
- s.version = "#{Noah::VERSION}.pre"
7
+ s.version = "#{Noah::VERSION}"
8
8
  s.post_install_message = %q{This release has backwards incompatible changes to the API. Please watch http://goo.gl/jYqp2 for details}
9
9
  s.platform = Gem::Platform::RUBY
10
10
  #s.platform = "jruby"
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
32
32
  s.add_dependency("ohm-contrib", ["= 0.1.1"])
33
33
  s.add_dependency("haml", ["= 3.0.25"])
34
34
  s.add_dependency("vegas", ["= 0.1.8"])
35
+ s.add_dependency("guid", ["= 0.1.1"])
35
36
 
36
37
 
37
38
  if RUBY_PLATFORM =~ /java/
data/spec/host_spec.rb CHANGED
@@ -26,10 +26,10 @@ describe "Using the Host Model", :reset_redis => true do
26
26
  host.name.should == hostname
27
27
  host.status.should == hoststatus
28
28
  host.services.size.should == 1
29
- host.services[1].valid?.should == true
30
- host.services[1].name.should == servicename
31
- host.services[1].status.should == servicestatus
32
- host.services[1].host_id.should == host.id
29
+ host.services.first.valid?.should == true
30
+ host.services.first.name.should == servicename
31
+ host.services.first.status.should == servicestatus
32
+ host.services.first.host_id.should == host.id
33
33
  end
34
34
 
35
35
  it "create a Host via find_or_create" do
@@ -2,7 +2,9 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Using the Application API", :reset_redis => false do
4
4
  before(:all) do
5
+ Ohm.redis.flushdb
5
6
  @a = Noah::Application.create(:name => 'rspec_sample_app')
7
+ @b = Noah::Application.create(:name => 'rspec_sample_app_2')
6
8
  @c = Noah::Configuration.create(:name => 'rspec_config', :format => 'string', :body => 'rspec is great')
7
9
  @a.configurations << @c
8
10
  @a.save
@@ -15,30 +17,39 @@ describe "Using the Application API", :reset_redis => false do
15
17
  last_response.should be_ok
16
18
  response = last_response.should return_json
17
19
  response.is_a?(Hash).should == true
20
+ response.size.should == 2
18
21
  end
19
22
  it "named application should work" do
20
23
  get '/applications/rspec_sample_app'
21
24
  last_response.should be_ok
22
25
  response = last_response.should return_json
23
- response.has_key?(@a.name).should == true
24
- response[@a.name].class.to_s.should == 'Hash'
25
- response[@a.name]["id"].should == @a.id.to_s
26
- response[@a.name].has_key?("configurations").should == true
27
- c = response[@a.name]["configurations"]
26
+ response["id"].should == @a.id.to_s
27
+ response["name"].should == @a.name
28
+ response.has_key?("configurations").should == true
29
+ c = response["configurations"]
28
30
  c.has_key?(@c.name).should == true
29
31
  c["#{@c.name}"]["format"].should == "#{@c.format}"
30
32
  c["#{@c.name}"]["body"].should == "#{@c.body}"
31
33
  end
32
- it "named configuration for application should work" do
33
- get "/applications/#{@a.name}/#{@c.name}"
34
+ it "named configuration for application should work as JSON" do
35
+ header "Accept", "application/json"
36
+ get "/applications/#{@a.name}/configurations/#{@c.name}"
34
37
  last_response.should be_ok
35
38
  response = last_response.should return_json
36
-
37
39
  response["id"].should == @c.id
38
40
  response["name"].should == @c.name
39
41
  response["format"].should == @c.format
40
42
  response["body"].should == @c.body
41
43
  end
44
+ it "named configuration for application should work as raw" do
45
+ header "Accept", "application/octet"
46
+ get "/applications/#{@a.name}/configurations/#{@c.name}"
47
+ last_response.should be_ok
48
+ headers = last_response.headers
49
+ body = last_response.body
50
+ headers["Content-Type"].should == 'text/plain;charset=utf-8'
51
+ body.should == @c.body
52
+ end
42
53
  it "invalid application should not work" do
43
54
  get "/applications/should_not_exist"
44
55
  last_response.should be_missing
@@ -64,6 +75,7 @@ describe "Using the Application API", :reset_redis => false do
64
75
  Noah::Application.find(:name => @appdata[:name]).size.should == 1
65
76
  Noah::Application.find(:name => @appdata[:name]).first.is_new?.should == true
66
77
  end
78
+ it "new application with new configuration should work"
67
79
  it "new application with missing name should not work" do
68
80
  put "/applications/should_not_work", '{"foo":"bar"}', "CONTENT_TYPE" => "application/json"
69
81
  last_response.should be_invalid
@@ -80,7 +92,9 @@ describe "Using the Application API", :reset_redis => false do
80
92
  response["action"].should == "update"
81
93
  Noah::Application.find(:name => @appdata[:name]).size.should == 1
82
94
  Noah::Application.find(:name => @appdata[:name]).first.is_new?.should == false
83
- end
95
+ end
96
+ it "existing application with new configuration"
97
+ it "existing application with existing configuration"
84
98
  end
85
99
 
86
100
  describe "DELETE" do
@@ -41,7 +41,8 @@ describe "Using the Configuration API", :reset_redis => true, :populate_sample_d
41
41
  end
42
42
  end
43
43
  end
44
- it "named configuration should work" do
44
+ it "named configuration should work as JSON" do
45
+ header "Accept", "application/json"
45
46
  get '/configurations/redis_url'
46
47
  last_response.should be_ok
47
48
  response = last_response.should return_json
@@ -55,7 +56,7 @@ describe "Using the Configuration API", :reset_redis => true, :populate_sample_d
55
56
  end
56
57
  it "named configuration should work with mime-type" do
57
58
  require 'yaml'
58
- get '/configurations/yaml_config/data'
59
+ get '/configurations/yaml_config'
59
60
  last_response.should be_ok
60
61
  last_response.headers["Content-Type"].should == "text/x-yaml;charset=utf-8"
61
62
  response = YAML.load(last_response.body)
@@ -114,9 +115,7 @@ describe "Using the Configuration API", :reset_redis => true, :populate_sample_d
114
115
  @c = Noah::Configuration.create(cparms)
115
116
  @a.configurations << @c
116
117
  get "/configurations/asdf"
117
- p last_response
118
118
  delete "/configurations/#{@c.name}"
119
- p last_response
120
119
  last_response.should be_ok
121
120
  response = last_response.should return_json
122
121
  response["result"].should == "success"
@@ -27,7 +27,7 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
27
27
  end
28
28
 
29
29
  it "named service for host should work" do
30
- get '/hosts/localhost/noah'
30
+ get '/hosts/localhost/services/noah'
31
31
  last_response.should be_ok
32
32
  response = last_response.should return_json
33
33
 
@@ -39,7 +39,7 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
39
39
 
40
40
  describe "PUT" do
41
41
  it "new host should work" do
42
- host_data = {:name => "host99.domain.com", :status => "down"}.to_json
42
+ host_data = {:status => "down"}.to_json
43
43
  put '/hosts/host99.domain.com', host_data, "CONTENT_TYPE" => "application/json"
44
44
  last_response.should be_ok
45
45
  response = last_response.should return_json
@@ -53,7 +53,7 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
53
53
 
54
54
  it "existing host should work" do
55
55
  sleep 3
56
- host_data = {:name => "host99.domain.com", :status => "pending"}.to_json
56
+ host_data = {:status => "pending"}.to_json
57
57
  put '/hosts/host99.domain.com', host_data, "CONTENT_TYPE" => "application/json"
58
58
  last_response.should be_ok
59
59
  response = last_response.should return_json
@@ -61,20 +61,13 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
61
61
  response["new_record"].should == false
62
62
  end
63
63
 
64
- it "host missing name parameter should not work" do
65
- host_data = {:status => "pending"}.to_json
66
- put '/hosts/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
67
- last_response.should be_invalid
68
- end
69
-
70
64
  it "host missing status parameter should not work" do
71
- host_data = {:name => "host100.domain.com"}.to_json
72
- put '/hosts/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
65
+ put '/hosts/host100.domain.com', "{}", "CONTENT_TYPE" => "application/json"
73
66
  last_response.should be_invalid
74
67
  end
75
68
 
76
69
  it "host with invalid status parameter should not work" do
77
- host_data = {:name => "host100.domain.com", :status => "fscked"}.to_json
70
+ host_data = {:status => "fscked"}.to_json
78
71
  put '/hosts/host100.domain.com', host_data, "CONTENT_TYPE" => "application/json"
79
72
  last_response.should_not be_ok
80
73
  response = last_response.should return_json
@@ -85,7 +78,8 @@ describe "Using the Host API", :reset_redis => false, :populate_sample_data => t
85
78
  end
86
79
 
87
80
  describe "DELETE" do
88
- before(:all) do
81
+ before(:each) do
82
+ Ohm.redis.flushdb
89
83
  @h = Noah::Host.create(:name => 'h', :status => 'up')
90
84
  sparms = {:name => 's', :status => "up"}
91
85
  @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
97
91
  delete "/hosts/#{@h.name}"
98
92
  last_response.should be_ok
99
93
  response = last_response.should return_json
100
-
101
94
  response["result"].should == "success"
102
95
  response["id"].should == @h.id
103
96
  response["name"].should == @h.name
104
97
  response["service_count"].should == svc_size.to_s
105
98
  end
106
99
 
100
+ it "valid service from valid host should work" do
101
+ delete "/hosts/#{@h.name}/services/#{@s.name}"
102
+ last_response.should be_ok
103
+ response = last_response.should return_json
104
+ response["result"].should == "success"
105
+ response["action"].should == "delete"
106
+ response["id"].should == @s.id
107
+ response["host"].should == @h.name
108
+ response["service"].should == @s.name
109
+ end
110
+
107
111
  it "invalid host should not work" do
108
- delete "/hosts/#{@h.name}"
112
+ delete "/hosts/not_a_valid_hsot"
109
113
  last_response.should be_missing
110
114
  end
111
115
  end
@@ -46,76 +46,143 @@ describe "Using the Service API", :reset_redis => false, :populate_sample_data =
46
46
  end
47
47
 
48
48
  describe "PUT" do
49
- before(:all) do
50
- @payload = {:name => 'another_rspec_service', :status => 'up', :host => @h.name}
51
- end
52
- it "new service should work" do
53
- put "/services/#{@payload[:name]}/", @payload.to_json, "CONTENT_TYPE" => "application/json"
49
+ before(:each) do
50
+ Ohm.redis.flushdb
51
+ @host_name = 'rspec_sample_host'
52
+ @service_name = 'rspec_sample_service'
53
+ @payload = {:status => 'up', :host_status => 'up'}
54
+ end
55
+ after(:each) do
56
+ Ohm.redis.flushdb
57
+ end
58
+ it "new service on new host should work" do
59
+ put "/services/#{@service_name}/#{@host_name}", @payload.to_json, "CONTENT_TYPE" => "application/json"
54
60
  last_response.should be_ok
55
61
  response = last_response.should return_json
56
62
  response["result"].should == "success"
57
63
  response["action"].should == "create"
58
64
  response["id"].nil?.should == false
59
- response["name"].should == @payload[:name]
60
- response["host"].should == @payload[:host]
61
- Noah::Service.find(:name => @payload[:name]).size.should == 1
62
- Noah::Service.find(:name => @payload[:name]).first.is_new?.should == true
65
+ response["name"].should == @service_name
66
+ response["host"]["name"].should == @host_name
67
+ response["host"]["status"].should == 'up'
68
+ response["host"]["action"].should == 'create'
69
+ response["host"]["status"].should == 'up'
70
+ Noah::Service.find(:name => @service_name).size.should == 1
71
+ Noah::Service.find(:name => @service_name).first.is_new?.should == true
72
+ Noah::Host.find(:name => @host_name).size.should == 1
73
+ Noah::Host.find(:name => @host_name).first.is_new?.should == true
63
74
  end
64
- it "new service without host should not work" do
65
- put "/services/foobar", {:name => "foobar", :status => "up"}.to_json, "CONTENT_TYPE" => "application/json"
66
- last_response.should be_invalid
75
+ it "new service on existing host should work" do
76
+ hostname = 'non-existant-rspec-host'
77
+ servicename = 'non-existant-rspec-service'
78
+ Noah::Host.create(:name => hostname, :status => 'up')
79
+ sleep(3)
80
+ put "/services/#{servicename}/#{hostname}", @payload.to_json, "CONTENT_TYPE" => "application/json"
81
+ last_response.should be_ok
82
+ response = last_response.should return_json
83
+ response["result"].should == "success"
84
+ response["action"].should == "create"
85
+ response["id"].nil?.should == false
86
+ response["name"].should == servicename
87
+ response["host"]["name"].should == hostname
88
+ response["host"]["status"].should == 'up'
89
+ response["host"]["action"].should == 'update'
90
+ Noah::Service.find(:name => servicename).size.should == 1
91
+ Noah::Service.find(:name => servicename).first.is_new?.should == true
92
+ end
93
+ it "new service with invalid host status should not work" do
94
+ put "/services/foobar/#{@host_name}", {:host_status => "fsck", :status => "up"}.to_json, "CONTENT_TYPE" => "application/json"
95
+ last_response.should_not be_ok
96
+ response = last_response.should return_json
97
+ response["error_message"].should == "Status must be up, down or pending"
67
98
  end
68
- it "new service with invalid status should not work" do
69
- put "/services/foobar", {:name => "foobar", :status => "fsck", :host => @h.name}.to_json, "CONTENT_TYPE" => "application/json"
99
+ it "new service with invalid service status should not work" do
100
+ put "/services/foobar/#{@host_name}", {:host_status => "up", :status => "fsck"}.to_json, "CONTENT_TYPE" => "application/json"
70
101
  last_response.should_not be_ok
71
102
  response = last_response.should return_json
72
103
  response["error_message"].should == "Status must be up, down or pending"
73
104
  end
74
- it "new service with missing name should not work" do
75
- put "/services/foobar", {:status => "fsck", :host => @h.name}.to_json, "CONTENT_TYPE" => "application/json"
105
+ it "new service with missing host_status should not work" do
106
+ put "/services/foobar/#{@host_name}", {:status => "up"}.to_json, "CONTENT_TYPE" => "application/json"
76
107
  last_response.should be_invalid
77
108
  end
78
109
  it "new service with missing status should not work" do
79
- put "/services/foobar", {:name => "foobar", :host => @h.name}.to_json, "CONTENT_TYPE" => "application/json"
110
+ put "/services/foobar/#{@host_name}", {:host_status => 'up'}.to_json, "CONTENT_TYPE" => "application/json"
80
111
  last_response.should be_invalid
81
112
  end
82
113
  it "existing service should work" do
83
- sleep 3
84
- put "/services/#{@payload[:name]}", {:name => @payload[:name], :status => "down", :host => @payload[:host]}.to_json, "CONTENT_TYPE" => "application/json"
114
+ a = Noah::Host.create(:name => @host_name, :status => 'up')
115
+ b = Noah::Service.create(:name => @service_name, :status => 'pending', :host => a)
116
+ sleep(3)
117
+ put "/services/#{@service_name}/#{@host_name}", @payload.to_json, "CONTENT_TYPE" => "application/json"
85
118
  last_response.should be_ok
86
119
  response = last_response.should return_json
87
120
  response["result"].should == "success"
88
121
  response["action"].should == "update"
89
122
  response["id"].nil?.should == false
90
- response["name"].should == @payload[:name]
91
- response["host"].should == @payload[:host]
92
- Noah::Service.find(:name => @payload[:name]).size.should == 1
93
- Noah::Service.find(:name => @payload[:name]).first.is_new?.should == false
123
+ response["name"].should == @service_name
124
+ response["host"]["name"].should == @host_name
125
+ response["host"]["status"].should == 'up'
126
+ response["host"]["action"].should == 'update'
94
127
  end
95
128
  end
96
129
 
97
130
  describe "DELETE" do
98
131
  before(:all) do
132
+ Ohm.redis.flushdb
99
133
  @h = Noah::Host.create(:name => "h1", :status => "up")
100
134
  @h.services << Noah::Service.create(:name => "s1", :status => "up", :host => @h)
101
135
  @h.save
102
136
  @s = @h.services.first
103
137
  end
104
- it "existing host should work" do
138
+ it "service from existing host should work" do
105
139
  delete "/services/#{@s.name}/#{@h.name}"
106
140
  last_response.should be_ok
107
141
  response = last_response.should return_json
108
-
109
142
  response["result"].should == "success"
110
143
  response["action"].should == "delete"
111
144
  response["id"].should == @s.id
112
145
  response["host"].should == @h.name
113
146
  response["service"].should == @s.name
114
- end
115
- it "invalid host should not work" do
147
+ end
148
+ it "all entries for a valid service" do
149
+ all_svc_name = 'my_sample_service'
150
+ foo_svc_name = 'my_sample_service_two'
151
+ bar_svc_name = 'my_sample_service_three'
152
+ %w[foo bar baz].each do |host|
153
+ h = Noah::Host.create(:name => host, :status => "up")
154
+ Noah::Service.create(:name => all_svc_name, :status => 'up', :host => h)
155
+ end
156
+ foo_host = Noah::Host.find(:name => 'foo').first
157
+ bar_host = Noah::Host.find(:name => 'bar').first
158
+ Noah::Service.create(:name => foo_svc_name, :status => 'down', :host => foo_host)
159
+ Noah::Service.create(:name => bar_svc_name, :status => 'pending', :host => bar_host)
160
+
161
+ delete "/services/#{all_svc_name}"
162
+ last_response.should be_ok
163
+ response = last_response.should return_json
164
+ response["result"].should == "success"
165
+ response["action"].should == "delete"
166
+ response["affected_hosts"].should == 3
167
+
168
+ delete "/services/#{foo_svc_name}"
169
+ last_response.should be_ok
170
+ response = last_response.should return_json
171
+ response["affected_hosts"].should == 1
172
+ end
173
+ it "service for invalid host should not work" do
116
174
  delete "/services/#{@s.name}/#{@h.name}"
117
175
  last_response.should be_missing
118
176
  end
177
+ it "invalid service for valid host should not work" do
178
+ Noah::Host.create(:name => 'valid_host', :status => 'up')
179
+ delete "/services/not_really_here/valid_host"
180
+ last_response.should be_missing
181
+ end
182
+ it "all entries for an invalid service should not_work" do
183
+ delete "/services/not_really_here"
184
+ last_response.should be_missing
185
+ end
119
186
  end
120
187
 
121
188
  end
data/spec/service_spec.rb CHANGED
@@ -16,7 +16,7 @@ describe "Noah Service Model", :reset_redis => true do
16
16
  service.name.should == servicename
17
17
  service.status.should == servicestatus
18
18
  service.host_id.should == host.id
19
- host.services[1].name.should == servicename
19
+ host.services[service.id].name.should == servicename
20
20
  end
21
21
 
22
22
  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
78
78
  a1.tag! ["production", "sample_data"]
79
79
  e2.tag! ["ephemeral", "development"]
80
80
  c1.tag! "development"
81
- Noah::Service[1].tag! "development"
82
- Noah::Service[2].tag! ["development", "out-of-service"]
83
- Noah::Service[2].link! "/my_sample_organization"
81
+ Noah::Service.all.first.tag! ["development", "out-of-service"]
82
+ Noah::Service.all.first.link! "/my_sample_organization"
84
83
 
85
84
 
86
85
  puts "Sample data populated!"
data/views/index.haml CHANGED
@@ -9,7 +9,7 @@
9
9
  %li
10
10
  Noah Version: #{locals[:noah_version]}
11
11
  %li
12
- Redis URL: #{locals[:redis_url]}
12
+ Redis Version: #{locals[:redis_version]}
13
13
  #header
14
14
  %h2 Hosts
15
15
  %ul
metadata CHANGED
@@ -1,8 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: noah
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: 4
5
- version: 0.6.pre
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 8
9
+ version: "0.8"
6
10
  platform: ruby
7
11
  authors:
8
12
  - John E. Vincent
@@ -10,7 +14,7 @@ autorequire:
10
14
  bindir: bin
11
15
  cert_chain: []
12
16
 
13
- date: 2011-04-18 00:00:00 -04:00
17
+ date: 2011-04-26 00:00:00 -04:00
14
18
  default_executable:
15
19
  dependencies:
16
20
  - !ruby/object:Gem::Dependency
@@ -21,6 +25,13 @@ dependencies:
21
25
  requirements:
22
26
  - - "="
23
27
  - !ruby/object:Gem::Version
28
+ hash: 62196357
29
+ segments:
30
+ - 1
31
+ - 0
32
+ - 0
33
+ - beta
34
+ - 3
24
35
  version: 1.0.0.beta.3
25
36
  type: :runtime
26
37
  version_requirements: *id001
@@ -32,6 +43,13 @@ dependencies:
32
43
  requirements:
33
44
  - - "="
34
45
  - !ruby/object:Gem::Version
46
+ hash: 62196357
47
+ segments:
48
+ - 1
49
+ - 0
50
+ - 0
51
+ - beta
52
+ - 3
35
53
  version: 1.0.0.beta.3
36
54
  type: :runtime
37
55
  version_requirements: *id002
@@ -43,6 +61,11 @@ dependencies:
43
61
  requirements:
44
62
  - - "="
45
63
  - !ruby/object:Gem::Version
64
+ hash: 7
65
+ segments:
66
+ - 2
67
+ - 2
68
+ - 0
46
69
  version: 2.2.0
47
70
  type: :runtime
48
71
  version_requirements: *id003
@@ -54,6 +77,11 @@ dependencies:
54
77
  requirements:
55
78
  - - "="
56
79
  - !ruby/object:Gem::Version
80
+ hash: 19
81
+ segments:
82
+ - 1
83
+ - 1
84
+ - 0
57
85
  version: 1.1.0
58
86
  type: :runtime
59
87
  version_requirements: *id004
@@ -65,6 +93,11 @@ dependencies:
65
93
  requirements:
66
94
  - - "="
67
95
  - !ruby/object:Gem::Version
96
+ hash: 27
97
+ segments:
98
+ - 1
99
+ - 2
100
+ - 2
68
101
  version: 1.2.2
69
102
  type: :runtime
70
103
  version_requirements: *id005
@@ -76,6 +109,11 @@ dependencies:
76
109
  requirements:
77
110
  - - "="
78
111
  - !ruby/object:Gem::Version
112
+ hash: 27
113
+ segments:
114
+ - 1
115
+ - 2
116
+ - 2
79
117
  version: 1.2.2
80
118
  type: :runtime
81
119
  version_requirements: *id006
@@ -87,6 +125,11 @@ dependencies:
87
125
  requirements:
88
126
  - - "="
89
127
  - !ruby/object:Gem::Version
128
+ hash: 25
129
+ segments:
130
+ - 1
131
+ - 2
132
+ - 3
90
133
  version: 1.2.3
91
134
  type: :runtime
92
135
  version_requirements: *id007
@@ -98,6 +141,11 @@ dependencies:
98
141
  requirements:
99
142
  - - "="
100
143
  - !ruby/object:Gem::Version
144
+ hash: 29
145
+ segments:
146
+ - 0
147
+ - 1
148
+ - 3
101
149
  version: 0.1.3
102
150
  type: :runtime
103
151
  version_requirements: *id008
@@ -109,6 +157,11 @@ dependencies:
109
157
  requirements:
110
158
  - - "="
111
159
  - !ruby/object:Gem::Version
160
+ hash: 25
161
+ segments:
162
+ - 0
163
+ - 1
164
+ - 1
112
165
  version: 0.1.1
113
166
  type: :runtime
114
167
  version_requirements: *id009
@@ -120,6 +173,11 @@ dependencies:
120
173
  requirements:
121
174
  - - "="
122
175
  - !ruby/object:Gem::Version
176
+ hash: 53
177
+ segments:
178
+ - 3
179
+ - 0
180
+ - 25
123
181
  version: 3.0.25
124
182
  type: :runtime
125
183
  version_requirements: *id010
@@ -131,97 +189,167 @@ dependencies:
131
189
  requirements:
132
190
  - - "="
133
191
  - !ruby/object:Gem::Version
192
+ hash: 11
193
+ segments:
194
+ - 0
195
+ - 1
196
+ - 8
134
197
  version: 0.1.8
135
198
  type: :runtime
136
199
  version_requirements: *id011
137
200
  - !ruby/object:Gem::Dependency
138
- name: hiredis
201
+ name: guid
139
202
  prerelease: false
140
203
  requirement: &id012 !ruby/object:Gem::Requirement
141
204
  none: false
142
205
  requirements:
143
206
  - - "="
144
207
  - !ruby/object:Gem::Version
145
- version: 0.3.1
208
+ hash: 25
209
+ segments:
210
+ - 0
211
+ - 1
212
+ - 1
213
+ version: 0.1.1
146
214
  type: :runtime
147
215
  version_requirements: *id012
148
216
  - !ruby/object:Gem::Dependency
149
- name: yajl-ruby
217
+ name: hiredis
150
218
  prerelease: false
151
219
  requirement: &id013 !ruby/object:Gem::Requirement
152
220
  none: false
153
221
  requirements:
154
- - - ">="
222
+ - - "="
155
223
  - !ruby/object:Gem::Version
156
- version: "0"
224
+ hash: 17
225
+ segments:
226
+ - 0
227
+ - 3
228
+ - 1
229
+ version: 0.3.1
157
230
  type: :runtime
158
231
  version_requirements: *id013
159
232
  - !ruby/object:Gem::Dependency
160
- name: thin
233
+ name: yajl-ruby
161
234
  prerelease: false
162
235
  requirement: &id014 !ruby/object:Gem::Requirement
163
236
  none: false
164
237
  requirements:
165
238
  - - ">="
166
239
  - !ruby/object:Gem::Version
240
+ hash: 3
241
+ segments:
242
+ - 0
167
243
  version: "0"
168
244
  type: :runtime
169
245
  version_requirements: *id014
170
246
  - !ruby/object:Gem::Dependency
171
- name: diff-lcs
247
+ name: SystemTimer
172
248
  prerelease: false
173
249
  requirement: &id015 !ruby/object:Gem::Requirement
250
+ none: false
251
+ requirements:
252
+ - - ">="
253
+ - !ruby/object:Gem::Version
254
+ hash: 3
255
+ segments:
256
+ - 0
257
+ version: "0"
258
+ type: :runtime
259
+ version_requirements: *id015
260
+ - !ruby/object:Gem::Dependency
261
+ name: thin
262
+ prerelease: false
263
+ requirement: &id016 !ruby/object:Gem::Requirement
264
+ none: false
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ hash: 3
269
+ segments:
270
+ - 0
271
+ version: "0"
272
+ type: :runtime
273
+ version_requirements: *id016
274
+ - !ruby/object:Gem::Dependency
275
+ name: diff-lcs
276
+ prerelease: false
277
+ requirement: &id017 !ruby/object:Gem::Requirement
174
278
  none: false
175
279
  requirements:
176
280
  - - "="
177
281
  - !ruby/object:Gem::Version
282
+ hash: 23
283
+ segments:
284
+ - 1
285
+ - 1
286
+ - 2
178
287
  version: 1.1.2
179
288
  type: :development
180
- version_requirements: *id015
289
+ version_requirements: *id017
181
290
  - !ruby/object:Gem::Dependency
182
291
  name: sinatra-reloader
183
292
  prerelease: false
184
- requirement: &id016 !ruby/object:Gem::Requirement
293
+ requirement: &id018 !ruby/object:Gem::Requirement
185
294
  none: false
186
295
  requirements:
187
296
  - - "="
188
297
  - !ruby/object:Gem::Version
298
+ hash: 11
299
+ segments:
300
+ - 0
301
+ - 5
302
+ - 0
189
303
  version: 0.5.0
190
304
  type: :development
191
- version_requirements: *id016
305
+ version_requirements: *id018
192
306
  - !ruby/object:Gem::Dependency
193
307
  name: rspec
194
308
  prerelease: false
195
- requirement: &id017 !ruby/object:Gem::Requirement
309
+ requirement: &id019 !ruby/object:Gem::Requirement
196
310
  none: false
197
311
  requirements:
198
312
  - - ~>
199
313
  - !ruby/object:Gem::Version
314
+ hash: 9
315
+ segments:
316
+ - 2
317
+ - 5
200
318
  version: "2.5"
201
319
  type: :development
202
- version_requirements: *id017
320
+ version_requirements: *id019
203
321
  - !ruby/object:Gem::Dependency
204
322
  name: rcov
205
323
  prerelease: false
206
- requirement: &id018 !ruby/object:Gem::Requirement
324
+ requirement: &id020 !ruby/object:Gem::Requirement
207
325
  none: false
208
326
  requirements:
209
327
  - - "="
210
328
  - !ruby/object:Gem::Version
329
+ hash: 41
330
+ segments:
331
+ - 0
332
+ - 9
333
+ - 9
211
334
  version: 0.9.9
212
335
  type: :development
213
- version_requirements: *id018
336
+ version_requirements: *id020
214
337
  - !ruby/object:Gem::Dependency
215
338
  name: rack-test
216
339
  prerelease: false
217
- requirement: &id019 !ruby/object:Gem::Requirement
340
+ requirement: &id021 !ruby/object:Gem::Requirement
218
341
  none: false
219
342
  requirements:
220
343
  - - "="
221
344
  - !ruby/object:Gem::Version
345
+ hash: 5
346
+ segments:
347
+ - 0
348
+ - 5
349
+ - 7
222
350
  version: 0.5.7
223
351
  type: :development
224
- version_requirements: *id019
352
+ version_requirements: *id021
225
353
  description: Application registry based on Apache Zookeeper
226
354
  email:
227
355
  - lusis.org+rubygems.org@gmail.com
@@ -338,13 +466,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
338
466
  requirements:
339
467
  - - ">="
340
468
  - !ruby/object:Gem::Version
469
+ hash: 3
470
+ segments:
471
+ - 0
341
472
  version: "0"
342
473
  required_rubygems_version: !ruby/object:Gem::Requirement
343
474
  none: false
344
475
  requirements:
345
- - - ">"
476
+ - - ">="
346
477
  - !ruby/object:Gem::Version
347
- version: 1.3.1
478
+ hash: 3
479
+ segments:
480
+ - 0
481
+ version: "0"
348
482
  requirements: []
349
483
 
350
484
  rubyforge_project: noah