noah 0.8.5 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ doc
16
16
  examples/log/*
17
17
  examples/tmp/*
18
18
  *.rbc
19
+ *.gem
@@ -0,0 +1,20 @@
1
+ # Noah Changelog
2
+
3
+ ## 0.8.6
4
+ - Issue #7 *Provide url for key-only enumeration*
5
+
6
+ - top-level configurations url now accepts `?short=true` to return shortened display of entries
7
+
8
+ - Issue #10 *noah-watcher daemon doesn't support REDIS_URL env*
9
+
10
+ - **BREAKING CHANGE** noah-watcher.rb renamed to noah-watcher
11
+ - noah-watcher now supports `-r redis://host:port/dbnum` to use alternate redis server
12
+ - noah-watcher now supports `-l logfile` for logging to file
13
+
14
+ ## 0.8.5
15
+ - Issue #9 *Ephemeral Tagging is broken*
16
+
17
+ - All tagging now moved from route files to Sinatra helper
18
+
19
+ # Historical
20
+ This changelog started being maintained at 0.8.5. Previous changes can be viewed in the commit history.
data/README.md CHANGED
@@ -1,13 +1,43 @@
1
1
  # Noah
2
2
  _"look at this effing rainbow I just made for you"_
3
3
 
4
- Noah is an application registry loosely based on [Apache ZooKeeper](http://zookeeper.apache.org)
4
+ Noah is an application registry inspired by [Apache ZooKeeper](http://zookeeper.apache.org)
5
5
 
6
6
  What does that mean? From the ZooKeeper Home Page:
7
7
 
8
8
  > ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. All of these kinds of services are used in some form or another by distributed applications.
9
9
 
10
- Essentially Noah, is a port of those concepts into a stateless RESTful application.
10
+ Essentially Noah is a port of parts of that functionality into a stateless RESTish application.
11
+
12
+ ## Some background
13
+ It's probably worth reading the following blog posts before going any further to clear up any possible misunderstandings.
14
+ Noah is not a direct replacement for ZK. It's a conceptual port. More than anything, it was an itch I needed to scratch:
15
+
16
+ - [On Noah - Part 1](http://blog.lusis.org/blog/2011/05/16/on-noah-part-1/)
17
+ - [On Noah - Part 2](http://blog.lusis.org/blog/2011/05/17/on-noah-part-2/)
18
+ - [On Noah - Part 3](http://blog.lusis.org/blog/2011/05/18/on-noah-part-3/)
19
+ - [On Noah - Part 4](http://blog.lusis.org/blog/2011/05/20/on-noah-part-4/)
20
+
21
+ Also the following post was where I sort of discussed it early on:
22
+
23
+ - [Ad-hoc configuration and Coordination](http://lusislog.blogspot.com/2011/03/ad-hoc-configuration-coordination-and.html)
24
+
25
+ ## Things Noah does not do
26
+
27
+ - Paxos, ZAB or any other sort of consensus protocol
28
+ - Noah itself is not distributed (yet).
29
+ - ACLs (yet)
30
+ - Leader election of any kind
31
+
32
+ ## Things Noah can do
33
+ _note that these terms are fairly overloaded depending on who you talk to_
34
+
35
+ - Service registry
36
+ - Node registry
37
+ - Configuration Registry
38
+ - Group Services
39
+ - Watches (albeit differently)
40
+
11
41
 
12
42
  ## Quick Start
13
43
  The quickstart guide has been moved to the wiki:
@@ -68,4 +98,4 @@ Here are a list of some key [wiki](https://github.com/lusis/Noah/wiki) pages:
68
98
  * [Watchers and Callbacks](https://github.com/lusis/Noah/wiki/Watchers-and-Callbacks)
69
99
  The general idea behind how Noah would implement watches
70
100
  * [Watcher/Callback Examples](https://github.com/lusis/Noah/blob/master/examples/README.md)
71
- Some example callbacks.
101
+ Some example callbacks.
data/bin/noah CHANGED
@@ -6,4 +6,5 @@ require 'vegas'
6
6
 
7
7
  Vegas::Runner.new(Noah::App, 'noah') do |runner, opts, app|
8
8
  opts.on("-r", "--redis URL", "redis url to connect to (default: redis://localhost:6379/0)") {|r| ENV["REDIS_URL"] = r; Noah::App.set :redis_url, r }
9
+ opts.on("--esize SIZE", Integer, "Max allowed ephemeral size in bytes") {|esize| Noah::App.set :ephemeral_size, esize }
9
10
  end
@@ -8,10 +8,9 @@ Apparently we could not connect to the redis instance.
8
8
  By default the watcher will attempt to connect to "redis://localhost:6379/0"
9
9
  If your redis instance is listening elsewhere, please start like so:
10
10
 
11
- REDIS_URL="redis://hostname:port/dbnum" noah-watcher.rb
12
-
13
- This will be rectified in a future release. Sorry about that.
11
+ noah-watcher.rb -r redis://hostname:port/dbnum
14
12
  ----------------------------------------------------------------------------
13
+
15
14
  EOC
16
15
 
17
16
  HELP = <<-EOH
@@ -27,6 +26,8 @@ require 'json'
27
26
 
28
27
  opts = Slop.parse do
29
28
  banner "Usage: noah-watcher.rb [options]"
29
+ on :r, :redis_url, 'Redis URL to use. This MUST match what the Noah server is using for now', :default => 'redis://localhost:6379/0', :argument => true
30
+ on :o, :output, 'Log destination - full file path. Default is STDOUT', :default => STDOUT, :argument => true
30
31
  on '--depinstall', "Installs additional dependencies" do
31
32
  puts "Installing dependencies"
32
33
  puts "em-hiredis..."
@@ -54,6 +55,8 @@ rescue LoadError => e
54
55
  exit
55
56
  end
56
57
 
58
+ ENV['REDIS_URL'] = opts[:redis_url]
59
+
57
60
  begin
58
61
  require 'noah'
59
62
  require 'noah/agent'
@@ -62,7 +65,7 @@ rescue Errno::ECONNREFUSED
62
65
  exit
63
66
  end
64
67
 
65
- Noah::Log.logger = Logger.new(STDOUT)
68
+ Noah::Log.logger = Logger.new(opts[:output])
66
69
  LOGGER = Noah::Log.logger
67
70
  LOGGER.progname = __FILE__
68
71
 
@@ -78,10 +81,10 @@ EventMachine.run do
78
81
  r = EventMachine::Hiredis.connect(ENV["REDIS_URL"])
79
82
  r.errback{|x| LOGGER.error("Unable to connect to redis: #{x}")}
80
83
  LOGGER.info("Attaching to Redis Pubsub")
81
- r.psubscribe("*")
82
- r.on(:pmessage) do |pattern, event, message|
84
+ proc = Proc.new{ |event, message|
83
85
  noah.reread_watchers if event =~ /^\/\/noah\/watchers\/.*/
84
86
  noah.broker("#{event}|#{message}") unless noah.watchers == 0
85
- end
87
+ }
88
+ r.pubsub.psubscribe("*", proc)
86
89
 
87
90
  end
@@ -5,7 +5,7 @@ require 'em-http-request'
5
5
 
6
6
  class HttpPostWatch < Noah::CustomWatcher
7
7
  redis_host "redis://127.0.0.1:6379/0"
8
- pattern "//noah/configuration/redis_server"
8
+ pattern "//noah/configurations/redis_server"
9
9
  destination Proc.new {|x| ::EM::HttpRequest.new('http://localhost:4567/webhook', :connection_timeout => 2, :inactivity_timeout => 4).post :body => x}
10
10
  run!
11
11
  end
@@ -9,7 +9,7 @@ set :noah_client_name, 'my_sinatra_app'
9
9
 
10
10
  def get_config_from_noah(setting)
11
11
  begin
12
- c = open("#{settings.noah_server}/c/#{settings.noah_client_name}/#{setting}").read
12
+ c = open("#{settings.noah_server}/applications/#{settings.noah_client_name}/configurations/#{setting}").read
13
13
  set setting.to_sym, c
14
14
  end
15
15
  end
@@ -17,7 +17,7 @@ end
17
17
  get_config_from_noah('redis_server')
18
18
 
19
19
  def get_redis_version
20
- Ohm.connect :url => settings.redis_server
20
+ Ohm.connect :url => settings.redis_server['body']
21
21
  Ohm.redis.info["redis_version"]
22
22
  end
23
23
 
@@ -25,9 +25,10 @@ get "/" do
25
25
  "Redis version: #{get_redis_version}"
26
26
  end
27
27
 
28
- put "/webhook" do
28
+ post "/webhook" do
29
29
  data = JSON.parse(request.body.read)
30
- settings.redis_server = data["body"]
30
+ settings.redis_server = data
31
+ puts data["body"]
31
32
  resp = {:message => "reconfigured", :setting => data["name"], :body => data["body"]}.to_json
32
33
  "#{resp}"
33
34
  end
@@ -16,6 +16,8 @@ module Noah
16
16
  set :show_exceptions, false
17
17
  set :run, false
18
18
  set :redis_url, ENV['REDIS_URL'] || 'redis://localhost:6379/0'
19
+ set :ephemeral_size, ENV['NOAH_ESIZE'] || 512
20
+ disable :protection
19
21
  end
20
22
 
21
23
  configure(:development) do
@@ -43,12 +45,21 @@ module Noah
43
45
  end
44
46
 
45
47
  # Displays an overview page of all registered objects
46
- get '/' do
48
+ get '/', :provides => :html do
47
49
  content_type "text/html"
48
-
49
50
  haml :index, :format => :html5, :locals => {:redis_version => Ohm.redis.info["redis_version"].to_s, :noah_version => Noah::VERSION}
50
51
  end
51
52
 
53
+ get '/', :provides => :json do
54
+ content_type "application/json"
55
+ erb :'index.json', :locals => {:redis_version => Ohm.redis.info["redis_version"].to_s, :noah_version => Noah::VERSION}
56
+ end
57
+
58
+ get '/version', :provides => :json do
59
+ content_type "application/json"
60
+ {:redis_version => Ohm.redis.info["redis_version"].to_s, :noah_version => Noah::VERSION}.to_json
61
+ end
62
+
52
63
  not_found do
53
64
  content_type "application/json"
54
65
  erb :'404'
@@ -88,8 +88,11 @@ module Noah
88
88
  self.name.nil? ? name=@deleted_name : name=self.name
89
89
  # Pulling out dbnum for now. Need to rethink it
90
90
  #pub_category = "#{db}:noah.#{self.class.to_s}[#{name}].#{meth}"
91
+ # TODO
92
+ # Add a url in the message body containing the URL to the item
93
+ url = "/#{self.class_to_lower}s/#{name}"
91
94
  pub_category = "#{self.patternize_me}"
92
- Ohm.redis.publish(pub_category, self.to_hash.merge({"action" => meth, "pubcategory" => pub_category}).to_json)
95
+ Ohm.redis.publish(pub_category, self.to_hash.merge({"action" => meth, "pubcategory" => pub_category, "path" => url}).to_json)
93
96
 
94
97
  # The following provides a post post-action hook. It allows a class to provide it's own handling after the fact
95
98
  # good example is in [Noah::Ephemeral] where it's used to check for/clean up expired ephemeral nodes entries
@@ -31,7 +31,7 @@ module Noah
31
31
  if obj.valid?
32
32
  obj.save
33
33
  end
34
- obj
34
+ obj if obj.valid?
35
35
  rescue Exception => e
36
36
  e.message
37
37
  end
@@ -62,10 +62,25 @@ module Noah
62
62
  end
63
63
 
64
64
  class Configurations
65
- def self.all(options = {})
65
+ def self.all(options = {}, short=false)
66
+ short_keys = [:format, :created_at, :updated_at]
66
67
  config_hash = Hash.new
67
68
  options.empty? ? configs=Configuration.all.sort : configs=Configuration.find(options).sort
68
- configs.each {|x| config_hash["#{x.name}"] = x.to_hash.reject {|k,v| k == :name} }
69
+ if short == false
70
+ configs.each {|x| config_hash["#{x.name}"] = x.to_hash.reject {|k,v| k == :name} }
71
+ else
72
+ configs.each do |x|
73
+ items = x.to_hash.select {|k,v| k if short_keys.include?(k)}
74
+ # 1.8 fix for Hash#select
75
+ if items.is_a?(Array)
76
+ items_hash = {}
77
+ items.each {|item| items_hash.merge!(Hash[*item])}
78
+ else
79
+ items_hash = items
80
+ end
81
+ config_hash["#{x.name}"] = items_hash
82
+ end
83
+ end
69
84
  config_hash
70
85
  end
71
86
  end
@@ -47,7 +47,7 @@ class Noah::App
47
47
  end
48
48
  if app.valid?
49
49
  action = app.is_new? ? "create" : "update"
50
- app.save
50
+ #app.save
51
51
  r = {"result" => "success","id" => app.id, "action" => action, "name" => app.name }
52
52
  r.to_json
53
53
  else
@@ -13,16 +13,23 @@ class Noah::App
13
13
  get '/configurations/:configname/?' do |configname|
14
14
  c = Noah::Configuration.find(:name => configname).first
15
15
  (halt 404) if c.nil?
16
+ #content_type c.format.to_sym
16
17
  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
18
+ c.body.to_s
19
19
  end
20
+
20
21
  # GET all configurations
21
22
  get '/configurations/?' do
22
- configs = Noah::Configurations.all.to_hash
23
+ params[:short] ||= false
24
+ configs = Noah::Configurations.all({},params[:short])
23
25
  (halt 404) if configs.size == 0
26
+ configs.each do |config, values|
27
+ u = request.url.gsub(/(\/\?short=true|\?short=true)/,'/'+config)
28
+ values.merge!({:location=>u}) if params[:short]
29
+ end
24
30
  configs.to_json
25
31
  end
32
+
26
33
  # Add configuration object to a custom link hierarchy
27
34
  put '/configurations/:configname/link' do |configname|
28
35
  required_params = ["link_name"]
@@ -19,7 +19,7 @@ class Noah::App
19
19
  end
20
20
 
21
21
  put '/ephemerals/*' do
22
- raise("Data too large") if request.body.size > 512
22
+ raise("Data too large") if request.body.size > settings.ephemeral_size
23
23
  d = request.body.read || nil
24
24
  opts = {:path => "/#{params[:splat][0]}", :data => d}
25
25
  e = Noah::Ephemeral.find_or_create(opts)
@@ -1,3 +1,3 @@
1
1
  module Noah
2
- VERSION = "0.8.5"
2
+ VERSION = "0.8.7"
3
3
  end
@@ -21,36 +21,37 @@ Gem::Specification.new do |s|
21
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
22
  s.require_paths = ["lib"]
23
23
 
24
- s.add_dependency("eventmachine", ["1.0.0.beta.3"])
25
- s.add_dependency("em-http-request", ["1.0.0.beta.4"])
26
- s.add_dependency("redis", ["= 2.2.0"])
27
- s.add_dependency("nest", ["= 1.1.0"])
28
- s.add_dependency("rack", ["= 1.2.2"])
29
- s.add_dependency("tilt", ["= 1.2.2"])
30
- s.add_dependency("sinatra", ["= 1.2.3"])
31
- s.add_dependency("ohm", ["= 0.1.3"])
32
- s.add_dependency("ohm-contrib", ["= 0.1.1"])
33
- s.add_dependency("haml", ["= 3.0.25"])
34
- s.add_dependency("vegas", ["= 0.1.8"])
35
- s.add_dependency("guid", ["= 0.1.1"])
36
- s.add_dependency("slop", ["= 2.1.0"])
24
+ s.add_dependency("eventmachine", "1.0.0.beta.4")
25
+ s.add_dependency("em-http-request", "1.0.0.beta.4")
26
+ s.add_dependency("cookiejar")
27
+ s.add_dependency("redis", "~> 2.2")
28
+ s.add_dependency("nest", "= 1.1.0")
29
+ s.add_dependency("rack", "~> 1.4")
30
+ s.add_dependency("tilt", "~> 1.3")
31
+ s.add_dependency("sinatra", "~> 1.3")
32
+ s.add_dependency("rack-protection", "~> 1.2")
33
+ s.add_dependency("ohm", "= 0.1.3")
34
+ s.add_dependency("ohm-contrib", "= 0.1.1")
35
+ s.add_dependency("haml", "= 3.0.25")
36
+ s.add_dependency("vegas", "= 0.1.8")
37
+ s.add_dependency("guid", "= 0.1.1")
38
+ s.add_dependency("slop", "= 2.1.0")
39
+ s.add_dependency("hiredis", "0.4.5")
40
+ s.add_dependency("cs-em-hiredis", "0.1.2")
37
41
 
38
42
 
39
43
  if RUBY_PLATFORM =~ /java/
40
44
  s.add_dependency("jruby-openssl")
41
45
  s.add_dependency("json")
42
- s.add_development_dependency("warbler", ["= 1.2.1"])
46
+ s.add_development_dependency("warbler", "= 1.2.1")
43
47
  else
44
- s.add_dependency("hiredis", ["= 0.3.1"])
45
48
  s.add_dependency("yajl-ruby")
46
- s.add_dependency("SystemTimer") if RUBY_VERSION =~ /1.8/
47
49
  s.add_dependency("thin")
48
50
  end
49
51
 
50
- s.add_development_dependency("diff-lcs", ["= 1.1.2"])
51
- s.add_development_dependency("sinatra-reloader", ["= 0.5.0"])
52
- s.add_development_dependency("rspec", ["~> 2.5"])
53
- # s.add_development_dependency("rcov", ["= 0.9.9"])
54
- s.add_development_dependency("rack-test", ["= 0.5.7"])
55
- s.add_development_dependency("rake", ["= 0.8.7"])
52
+ s.add_development_dependency("diff-lcs", "= 1.1.2")
53
+ s.add_development_dependency("sinatra-reloader", "= 0.5.0")
54
+ s.add_development_dependency("rspec", "~> 2.5")
55
+ s.add_development_dependency("rack-test", "= 0.6.1")
56
+ s.add_development_dependency("rake", "= 0.8.7")
56
57
  end
@@ -65,8 +65,19 @@ describe "Using the Configuration Model", :reset_redis => true do
65
65
  c = Noah::Configurations.all
66
66
  c.class.to_s.should == 'Hash'
67
67
  c.size.should == 2
68
- c.has_key?(a.name).should == true
69
- c.has_key?(b.name).should == true
68
+ c.has_key?(a.name.to_s).should == true
69
+ c.has_key?(b.name.to_s).should == true
70
+ end
71
+
72
+ it "return all Configurations in short form" do
73
+ a = Noah::Configuration.find_or_create(@appconf_string)
74
+ b = Noah::Configuration.find_or_create(@appconf_json)
75
+ c = Noah::Configurations.all({},true)
76
+ c.class.to_s.should == 'Hash'
77
+ c.size.should == 2
78
+ c.has_key?(a.name.to_s).should == true
79
+ c.has_key?(b.name.to_s).should == true
80
+ c.each {|k,v| v.keys.map {|k| k.to_s}.sort.should == ['created_at','format','updated_at']}
70
81
  end
71
82
  end
72
83
 
@@ -58,16 +58,16 @@ describe "Using the Link Model", :reset_redis => true do
58
58
  h[:name].should == l.name
59
59
  h[:updated_at].should == l.updated_at
60
60
  h[:created_at].should == l.created_at
61
- h[:hosts].has_key?(@host.name).should == true
62
- h[:hosts][@host.name].keys.map {|k| k.to_s}.sort.should == [:id, :status, :tags, :services].map {|k| k.to_s}.sort
63
- h[:services].has_key?(@service.name).should == true
64
- h[:services][@service.name][@host.name].keys.map {|k| k.to_s}.sort.should == [:id, :status, :tags].map {|k| k.to_s}.sort
65
- h[:applications].has_key?(@application.name).should == true
66
- h[:applications][@application.name].keys.map {|k| k.to_s}.sort.should == [:id, :tags, :configurations].map {|k| k.to_s}.sort
67
- h[:configurations].has_key?(@configuration.name).should == true
68
- h[:configurations][@configuration.name].keys.map {|k| k.to_s }.sort.should == [:id, :tags, :format, :body].map {|k| k.to_s}.sort
69
- h[:ephemerals].has_key?(@ephemeral.name).should == true
70
- h[:ephemerals][@ephemeral.name].keys.map {|k| k.to_s}.sort.should == [:id, :tags, :path, :data].map {|k| k.to_s}.sort
61
+ h[:hosts].has_key?(@host.name.to_s).should == true
62
+ h[:hosts]["#{@host.name}"].keys.map {|k| k.to_s}.sort.should == [:id, :status, :tags, :services].map {|k| k.to_s}.sort
63
+ h[:services].has_key?(@service.name.to_s).should == true
64
+ h[:services]["#{@service.name}"]["#{@host.name}"].keys.map {|k| k.to_s}.sort.should == [:id, :status, :tags].map {|k| k.to_s}.sort
65
+ h[:applications].has_key?(@application.name.to_s).should == true
66
+ h[:applications]["#{@application.name}"].keys.map {|k| k.to_s}.sort.should == [:id, :tags, :configurations].map {|k| k.to_s}.sort
67
+ h[:configurations].has_key?(@configuration.name.to_s).should == true
68
+ h[:configurations]["#{@configuration.name}"].keys.map {|k| k.to_s }.sort.should == [:id, :tags, :format, :body].map {|k| k.to_s}.sort
69
+ h[:ephemerals].has_key?(@ephemeral.name.to_s).should == true
70
+ h[:ephemerals]["#{@ephemeral.name}"].keys.map {|k| k.to_s}.sort.should == [:id, :tags, :path, :data].map {|k| k.to_s}.sort
71
71
 
72
72
  end
73
73
  end
@@ -27,7 +27,7 @@ describe "Using the Application API", :reset_redis => false do
27
27
  response["name"].should == @a.name
28
28
  response.has_key?("configurations").should == true
29
29
  c = response["configurations"]
30
- c.has_key?(@c.name).should == true
30
+ c.has_key?(@c.name.to_s).should == true
31
31
  c["#{@c.name}"]["format"].should == "#{@c.format}"
32
32
  c["#{@c.name}"]["body"].should == "#{@c.body}"
33
33
  end
@@ -41,6 +41,35 @@ describe "Using the Configuration API", :reset_redis => true, :populate_sample_d
41
41
  end
42
42
  end
43
43
  end
44
+
45
+ it "all configurations in short form with no trailing slash" do
46
+ get '/configurations?short=true'
47
+ last_response.should be_ok
48
+ response = last_response.should return_json
49
+ response.keys.size.should == 3
50
+ %w[redis_url json_config yaml_config].each do |c|
51
+ response.keys.member?(c).should == true
52
+ %w[format location created_at updated_at].each do |ck|
53
+ response[c].keys.member?(ck).should == true
54
+ end
55
+ end
56
+ response.each {|k,v| v['location'].should =~ /^http:\/\/.*\/configurations\/#{k}/}
57
+ end
58
+
59
+ it "all configurations in short form with trailing slash" do
60
+ get '/configurations/?short=true'
61
+ last_response.should be_ok
62
+ response = last_response.should return_json
63
+ response.keys.size.should == 3
64
+ %w[redis_url json_config yaml_config].each do |c|
65
+ response.keys.member?(c).should == true
66
+ %w[format location created_at updated_at].each do |ck|
67
+ response[c].keys.member?(ck).should == true
68
+ end
69
+ end
70
+ response.each {|k,v| v['location'].should =~ /^http:\/\/.*\/configurations\/#{k}/}
71
+ end
72
+
44
73
  it "named configuration should work as JSON" do
45
74
  header "Accept", "application/json"
46
75
  get '/configurations/redis_url'
@@ -22,13 +22,13 @@ describe "Using the Service API", :reset_redis => false, :populate_sample_data =
22
22
  get "/services/#{@sample_service[:name]}"
23
23
  last_response.should be_ok
24
24
  response = last_response.should return_json
25
- response.is_a?(Hash).should == true
26
- response.has_key?(@s.name).should == true
27
- response[@s.name].is_a?(Hash).should == true
28
- response[@s.name].has_key?(@h.name).should == true
29
- response[@s.name][@h.name].is_a?(Hash).should == true
30
- response[@s.name][@h.name]["id"].should == @s.id
31
- response[@s.name][@h.name]["status"].should == @s.status
25
+ response.class.to_s.should == "Hash"
26
+ response.has_key?(@s.name.to_s).should == true
27
+ response["#{@s.name}"].class.to_s.should == "Hash"
28
+ response["#{@s.name}"].has_key?(@h.name.to_s).should == true
29
+ response["#{@s.name}"]["#{@h.name}"].class.to_s.should == "Hash"
30
+ response["#{@s.name}"]["#{@h.name}"]["id"].should == @s.id
31
+ response["#{@s.name}"]["#{@h.name}"]["status"].should == @s.status
32
32
  end
33
33
  it "named service for host should work" do
34
34
  get "/services/#{@sample_service[:name]}/#{@sample_host[:name]}"
@@ -2,16 +2,27 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Noah App Basics", :reset_redis => true do
4
4
 
5
- it "should show the index page" do
5
+ it "should show the index page as html" do
6
+ header "Accept", "text/html"
6
7
  get '/'
7
8
  last_response.should be_ok
8
9
  last_response.body.include?("Noah Start Page").should == true
9
10
  end
10
11
 
12
+ it "should show the index page as json" do
13
+ header "Accept", "application/json"
14
+ get '/'
15
+ last_response.should return_json
16
+ response = JSON.parse(last_response.body)
17
+ response.has_key?("redis_version").should == true
18
+ response.has_key?("noah_version").should == true
19
+ response.has_key?("resources").should == true
20
+ end
21
+
11
22
  it "should test the 404 message" do
12
23
  get '/foo'
13
24
  last_response.status.should == 404
14
- last_response.headers["Content-Type"].should == "application/json"
25
+ last_response.should return_json
15
26
  response = JSON.parse(last_response.body)
16
27
  response["result"].should == "failure"
17
28
  response["error_message"].should == "Resource not found"
@@ -72,7 +72,7 @@ end
72
72
 
73
73
  RSpec::Matchers.define :return_json do
74
74
  match do |last_response|
75
- last_response.headers["Content-Type"].should == "application/json"
75
+ last_response.headers["Content-Type"].should =~ /^application\/json;.*/
76
76
  response = JSON.parse(last_response.body)
77
77
  end
78
78
 
@@ -83,7 +83,7 @@ end
83
83
 
84
84
  RSpec::Matchers.define :be_missing do
85
85
  match do |last_response|
86
- last_response.headers["Content-Type"].should == "application/json"
86
+ last_response.headers["Content-Type"].should =~ /^application\/json;.*/
87
87
  last_response.status.should == 404
88
88
  response = JSON.parse(last_response.body)
89
89
  response["result"].should == "failure"
@@ -93,7 +93,7 @@ end
93
93
 
94
94
  RSpec::Matchers.define :be_invalid do
95
95
  match do |last_response|
96
- last_response.headers["Content-Type"].should == "application/json"
96
+ last_response.headers["Content-Type"].should =~ /^application\/json;.*/
97
97
  response = JSON.parse(last_response.body)
98
98
  response["result"].should == "failure"
99
99
  response["error_message"].should == "Missing Parameters"
@@ -0,0 +1,10 @@
1
+ {
2
+ "redis_version":"<%= locals[:redis_version] %>",
3
+ "noah_version":"<%= locals[:noah_version] %>",
4
+ "resources":{
5
+ "hosts":{"link":"<%= request.url %>hosts"},
6
+ "services":{"link":"<%= request.url %>services"},
7
+ "applications":{"link":"<%= request.url %>applications"},
8
+ "configurations":{"link":"<%= request.url %>configurations"}
9
+ }
10
+ }
metadata CHANGED
@@ -1,263 +1,413 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: noah
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.7
4
5
  prerelease:
5
- version: 0.8.5
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - John E. Vincent
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-08-05 00:00:00 -04:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2012-05-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: eventmachine
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
22
- - - "="
23
- - !ruby/object:Gem::Version
24
- version: 1.0.0.beta.3
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0.beta.4
25
22
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0.beta.4
30
+ - !ruby/object:Gem::Dependency
28
31
  name: em-http-request
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.0.0.beta.4
38
+ type: :runtime
29
39
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
31
41
  none: false
32
- requirements:
33
- - - "="
34
- - !ruby/object:Gem::Version
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
35
45
  version: 1.0.0.beta.4
46
+ - !ruby/object:Gem::Dependency
47
+ name: cookiejar
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
36
54
  type: :runtime
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: redis
40
55
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: redis
64
+ requirement: !ruby/object:Gem::Requirement
42
65
  none: false
43
- requirements:
44
- - - "="
45
- - !ruby/object:Gem::Version
46
- version: 2.2.0
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.2'
47
70
  type: :runtime
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: nest
51
71
  prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
72
+ version_requirements: !ruby/object:Gem::Requirement
53
73
  none: false
54
- requirements:
55
- - - "="
56
- - !ruby/object:Gem::Version
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2.2'
78
+ - !ruby/object:Gem::Dependency
79
+ name: nest
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - '='
84
+ - !ruby/object:Gem::Version
57
85
  version: 1.1.0
58
86
  type: :runtime
59
- version_requirements: *id004
60
- - !ruby/object:Gem::Dependency
61
- name: rack
62
87
  prerelease: false
63
- requirement: &id005 !ruby/object:Gem::Requirement
88
+ version_requirements: !ruby/object:Gem::Requirement
64
89
  none: false
65
- requirements:
66
- - - "="
67
- - !ruby/object:Gem::Version
68
- version: 1.2.2
90
+ requirements:
91
+ - - '='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.1.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: rack
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '1.4'
69
102
  type: :runtime
70
- version_requirements: *id005
71
- - !ruby/object:Gem::Dependency
72
- name: tilt
73
103
  prerelease: false
74
- requirement: &id006 !ruby/object:Gem::Requirement
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '1.4'
110
+ - !ruby/object:Gem::Dependency
111
+ name: tilt
112
+ requirement: !ruby/object:Gem::Requirement
75
113
  none: false
76
- requirements:
77
- - - "="
78
- - !ruby/object:Gem::Version
79
- version: 1.2.2
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '1.3'
80
118
  type: :runtime
81
- version_requirements: *id006
82
- - !ruby/object:Gem::Dependency
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '1.3'
126
+ - !ruby/object:Gem::Dependency
83
127
  name: sinatra
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '1.3'
134
+ type: :runtime
84
135
  prerelease: false
85
- requirement: &id007 !ruby/object:Gem::Requirement
136
+ version_requirements: !ruby/object:Gem::Requirement
86
137
  none: false
87
- requirements:
88
- - - "="
89
- - !ruby/object:Gem::Version
90
- version: 1.2.3
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '1.3'
142
+ - !ruby/object:Gem::Dependency
143
+ name: rack-protection
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: '1.2'
91
150
  type: :runtime
92
- version_requirements: *id007
93
- - !ruby/object:Gem::Dependency
94
- name: ohm
95
151
  prerelease: false
96
- requirement: &id008 !ruby/object:Gem::Requirement
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '1.2'
158
+ - !ruby/object:Gem::Dependency
159
+ name: ohm
160
+ requirement: !ruby/object:Gem::Requirement
97
161
  none: false
98
- requirements:
99
- - - "="
100
- - !ruby/object:Gem::Version
162
+ requirements:
163
+ - - '='
164
+ - !ruby/object:Gem::Version
101
165
  version: 0.1.3
102
166
  type: :runtime
103
- version_requirements: *id008
104
- - !ruby/object:Gem::Dependency
105
- name: ohm-contrib
106
167
  prerelease: false
107
- requirement: &id009 !ruby/object:Gem::Requirement
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - '='
172
+ - !ruby/object:Gem::Version
173
+ version: 0.1.3
174
+ - !ruby/object:Gem::Dependency
175
+ name: ohm-contrib
176
+ requirement: !ruby/object:Gem::Requirement
108
177
  none: false
109
- requirements:
110
- - - "="
111
- - !ruby/object:Gem::Version
178
+ requirements:
179
+ - - '='
180
+ - !ruby/object:Gem::Version
112
181
  version: 0.1.1
113
182
  type: :runtime
114
- version_requirements: *id009
115
- - !ruby/object:Gem::Dependency
116
- name: haml
117
183
  prerelease: false
118
- requirement: &id010 !ruby/object:Gem::Requirement
184
+ version_requirements: !ruby/object:Gem::Requirement
119
185
  none: false
120
- requirements:
121
- - - "="
122
- - !ruby/object:Gem::Version
186
+ requirements:
187
+ - - '='
188
+ - !ruby/object:Gem::Version
189
+ version: 0.1.1
190
+ - !ruby/object:Gem::Dependency
191
+ name: haml
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - '='
196
+ - !ruby/object:Gem::Version
123
197
  version: 3.0.25
124
198
  type: :runtime
125
- version_requirements: *id010
126
- - !ruby/object:Gem::Dependency
127
- name: vegas
128
199
  prerelease: false
129
- requirement: &id011 !ruby/object:Gem::Requirement
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - '='
204
+ - !ruby/object:Gem::Version
205
+ version: 3.0.25
206
+ - !ruby/object:Gem::Dependency
207
+ name: vegas
208
+ requirement: !ruby/object:Gem::Requirement
130
209
  none: false
131
- requirements:
132
- - - "="
133
- - !ruby/object:Gem::Version
210
+ requirements:
211
+ - - '='
212
+ - !ruby/object:Gem::Version
134
213
  version: 0.1.8
135
214
  type: :runtime
136
- version_requirements: *id011
137
- - !ruby/object:Gem::Dependency
138
- name: guid
139
215
  prerelease: false
140
- requirement: &id012 !ruby/object:Gem::Requirement
216
+ version_requirements: !ruby/object:Gem::Requirement
141
217
  none: false
142
- requirements:
143
- - - "="
144
- - !ruby/object:Gem::Version
218
+ requirements:
219
+ - - '='
220
+ - !ruby/object:Gem::Version
221
+ version: 0.1.8
222
+ - !ruby/object:Gem::Dependency
223
+ name: guid
224
+ requirement: !ruby/object:Gem::Requirement
225
+ none: false
226
+ requirements:
227
+ - - '='
228
+ - !ruby/object:Gem::Version
145
229
  version: 0.1.1
146
230
  type: :runtime
147
- version_requirements: *id012
148
- - !ruby/object:Gem::Dependency
149
- name: slop
150
231
  prerelease: false
151
- requirement: &id013 !ruby/object:Gem::Requirement
232
+ version_requirements: !ruby/object:Gem::Requirement
152
233
  none: false
153
- requirements:
154
- - - "="
155
- - !ruby/object:Gem::Version
234
+ requirements:
235
+ - - '='
236
+ - !ruby/object:Gem::Version
237
+ version: 0.1.1
238
+ - !ruby/object:Gem::Dependency
239
+ name: slop
240
+ requirement: !ruby/object:Gem::Requirement
241
+ none: false
242
+ requirements:
243
+ - - '='
244
+ - !ruby/object:Gem::Version
156
245
  version: 2.1.0
157
246
  type: :runtime
158
- version_requirements: *id013
159
- - !ruby/object:Gem::Dependency
247
+ prerelease: false
248
+ version_requirements: !ruby/object:Gem::Requirement
249
+ none: false
250
+ requirements:
251
+ - - '='
252
+ - !ruby/object:Gem::Version
253
+ version: 2.1.0
254
+ - !ruby/object:Gem::Dependency
160
255
  name: hiredis
256
+ requirement: !ruby/object:Gem::Requirement
257
+ none: false
258
+ requirements:
259
+ - - '='
260
+ - !ruby/object:Gem::Version
261
+ version: 0.4.5
262
+ type: :runtime
161
263
  prerelease: false
162
- requirement: &id014 !ruby/object:Gem::Requirement
264
+ version_requirements: !ruby/object:Gem::Requirement
265
+ none: false
266
+ requirements:
267
+ - - '='
268
+ - !ruby/object:Gem::Version
269
+ version: 0.4.5
270
+ - !ruby/object:Gem::Dependency
271
+ name: cs-em-hiredis
272
+ requirement: !ruby/object:Gem::Requirement
163
273
  none: false
164
- requirements:
165
- - - "="
166
- - !ruby/object:Gem::Version
167
- version: 0.3.1
274
+ requirements:
275
+ - - '='
276
+ - !ruby/object:Gem::Version
277
+ version: 0.1.2
168
278
  type: :runtime
169
- version_requirements: *id014
170
- - !ruby/object:Gem::Dependency
171
- name: yajl-ruby
172
279
  prerelease: false
173
- requirement: &id015 !ruby/object:Gem::Requirement
280
+ version_requirements: !ruby/object:Gem::Requirement
174
281
  none: false
175
- requirements:
176
- - - ">="
177
- - !ruby/object:Gem::Version
178
- version: "0"
282
+ requirements:
283
+ - - '='
284
+ - !ruby/object:Gem::Version
285
+ version: 0.1.2
286
+ - !ruby/object:Gem::Dependency
287
+ name: yajl-ruby
288
+ requirement: !ruby/object:Gem::Requirement
289
+ none: false
290
+ requirements:
291
+ - - ! '>='
292
+ - !ruby/object:Gem::Version
293
+ version: '0'
179
294
  type: :runtime
180
- version_requirements: *id015
181
- - !ruby/object:Gem::Dependency
182
- name: thin
183
295
  prerelease: false
184
- requirement: &id016 !ruby/object:Gem::Requirement
296
+ version_requirements: !ruby/object:Gem::Requirement
297
+ none: false
298
+ requirements:
299
+ - - ! '>='
300
+ - !ruby/object:Gem::Version
301
+ version: '0'
302
+ - !ruby/object:Gem::Dependency
303
+ name: thin
304
+ requirement: !ruby/object:Gem::Requirement
185
305
  none: false
186
- requirements:
187
- - - ">="
188
- - !ruby/object:Gem::Version
189
- version: "0"
306
+ requirements:
307
+ - - ! '>='
308
+ - !ruby/object:Gem::Version
309
+ version: '0'
190
310
  type: :runtime
191
- version_requirements: *id016
192
- - !ruby/object:Gem::Dependency
193
- name: diff-lcs
194
311
  prerelease: false
195
- requirement: &id017 !ruby/object:Gem::Requirement
312
+ version_requirements: !ruby/object:Gem::Requirement
313
+ none: false
314
+ requirements:
315
+ - - ! '>='
316
+ - !ruby/object:Gem::Version
317
+ version: '0'
318
+ - !ruby/object:Gem::Dependency
319
+ name: diff-lcs
320
+ requirement: !ruby/object:Gem::Requirement
196
321
  none: false
197
- requirements:
198
- - - "="
199
- - !ruby/object:Gem::Version
322
+ requirements:
323
+ - - '='
324
+ - !ruby/object:Gem::Version
200
325
  version: 1.1.2
201
326
  type: :development
202
- version_requirements: *id017
203
- - !ruby/object:Gem::Dependency
204
- name: sinatra-reloader
205
327
  prerelease: false
206
- requirement: &id018 !ruby/object:Gem::Requirement
328
+ version_requirements: !ruby/object:Gem::Requirement
329
+ none: false
330
+ requirements:
331
+ - - '='
332
+ - !ruby/object:Gem::Version
333
+ version: 1.1.2
334
+ - !ruby/object:Gem::Dependency
335
+ name: sinatra-reloader
336
+ requirement: !ruby/object:Gem::Requirement
207
337
  none: false
208
- requirements:
209
- - - "="
210
- - !ruby/object:Gem::Version
338
+ requirements:
339
+ - - '='
340
+ - !ruby/object:Gem::Version
211
341
  version: 0.5.0
212
342
  type: :development
213
- version_requirements: *id018
214
- - !ruby/object:Gem::Dependency
215
- name: rspec
216
343
  prerelease: false
217
- requirement: &id019 !ruby/object:Gem::Requirement
344
+ version_requirements: !ruby/object:Gem::Requirement
218
345
  none: false
219
- requirements:
346
+ requirements:
347
+ - - '='
348
+ - !ruby/object:Gem::Version
349
+ version: 0.5.0
350
+ - !ruby/object:Gem::Dependency
351
+ name: rspec
352
+ requirement: !ruby/object:Gem::Requirement
353
+ none: false
354
+ requirements:
220
355
  - - ~>
221
- - !ruby/object:Gem::Version
222
- version: "2.5"
356
+ - !ruby/object:Gem::Version
357
+ version: '2.5'
223
358
  type: :development
224
- version_requirements: *id019
225
- - !ruby/object:Gem::Dependency
226
- name: rack-test
227
359
  prerelease: false
228
- requirement: &id020 !ruby/object:Gem::Requirement
360
+ version_requirements: !ruby/object:Gem::Requirement
361
+ none: false
362
+ requirements:
363
+ - - ~>
364
+ - !ruby/object:Gem::Version
365
+ version: '2.5'
366
+ - !ruby/object:Gem::Dependency
367
+ name: rack-test
368
+ requirement: !ruby/object:Gem::Requirement
229
369
  none: false
230
- requirements:
231
- - - "="
232
- - !ruby/object:Gem::Version
233
- version: 0.5.7
370
+ requirements:
371
+ - - '='
372
+ - !ruby/object:Gem::Version
373
+ version: 0.6.1
234
374
  type: :development
235
- version_requirements: *id020
236
- - !ruby/object:Gem::Dependency
237
- name: rake
238
375
  prerelease: false
239
- requirement: &id021 !ruby/object:Gem::Requirement
376
+ version_requirements: !ruby/object:Gem::Requirement
240
377
  none: false
241
- requirements:
242
- - - "="
243
- - !ruby/object:Gem::Version
378
+ requirements:
379
+ - - '='
380
+ - !ruby/object:Gem::Version
381
+ version: 0.6.1
382
+ - !ruby/object:Gem::Dependency
383
+ name: rake
384
+ requirement: !ruby/object:Gem::Requirement
385
+ none: false
386
+ requirements:
387
+ - - '='
388
+ - !ruby/object:Gem::Version
244
389
  version: 0.8.7
245
390
  type: :development
246
- version_requirements: *id021
391
+ prerelease: false
392
+ version_requirements: !ruby/object:Gem::Requirement
393
+ none: false
394
+ requirements:
395
+ - - '='
396
+ - !ruby/object:Gem::Version
397
+ version: 0.8.7
247
398
  description: Application registry inspired by Apache Zookeeper
248
- email:
399
+ email:
249
400
  - lusis.org+rubygems.org@gmail.com
250
- executables:
401
+ executables:
251
402
  - noah
252
- - noah-watcher.rb
403
+ - noah-watcher
253
404
  extensions: []
254
-
255
405
  extra_rdoc_files: []
256
-
257
- files:
406
+ files:
258
407
  - .autotest
259
408
  - .gemtest
260
409
  - .gitignore
410
+ - CHANGELOG.md
261
411
  - Gemfile
262
412
  - LICENSE
263
413
  - README.md
@@ -265,7 +415,7 @@ files:
265
415
  - TODO.md
266
416
  - autotest/discover.rb
267
417
  - bin/noah
268
- - bin/noah-watcher.rb
418
+ - bin/noah-watcher
269
419
  - config.ru
270
420
  - config/warble.rb
271
421
  - examples/Kirkfile
@@ -354,33 +504,50 @@ files:
354
504
  - views/404.erb
355
505
  - views/500.erb
356
506
  - views/index.haml
357
- has_rdoc: true
507
+ - views/index.json.erb
358
508
  homepage: https://github.com/lusis/noah
359
509
  licenses: []
360
-
361
- post_install_message: This release has backwards incompatible changes to the API. Please watch http://goo.gl/jYqp2 for details
510
+ post_install_message: This release has backwards incompatible changes to the API.
511
+ Please watch http://goo.gl/jYqp2 for details
362
512
  rdoc_options: []
363
-
364
- require_paths:
513
+ require_paths:
365
514
  - lib
366
- required_ruby_version: !ruby/object:Gem::Requirement
515
+ required_ruby_version: !ruby/object:Gem::Requirement
367
516
  none: false
368
- requirements:
369
- - - ">="
370
- - !ruby/object:Gem::Version
371
- version: "0"
372
- required_rubygems_version: !ruby/object:Gem::Requirement
517
+ requirements:
518
+ - - ! '>='
519
+ - !ruby/object:Gem::Version
520
+ version: '0'
521
+ required_rubygems_version: !ruby/object:Gem::Requirement
373
522
  none: false
374
- requirements:
375
- - - ">="
376
- - !ruby/object:Gem::Version
377
- version: "0"
523
+ requirements:
524
+ - - ! '>='
525
+ - !ruby/object:Gem::Version
526
+ version: '0'
378
527
  requirements: []
379
-
380
528
  rubyforge_project: noah
381
- rubygems_version: 1.6.2
529
+ rubygems_version: 1.8.24
382
530
  signing_key:
383
531
  specification_version: 3
384
532
  summary: Application registry inspired by Apache Zookeeper
385
- test_files: []
386
-
533
+ test_files:
534
+ - spec/application_spec.rb
535
+ - spec/configuration_spec.rb
536
+ - spec/ephemeral_spec.rb
537
+ - spec/host_spec.rb
538
+ - spec/link_spec.rb
539
+ - spec/noahapp_application_spec.rb
540
+ - spec/noahapp_configuration_spec.rb
541
+ - spec/noahapp_ephemeral_spec.rb
542
+ - spec/noahapp_host_spec.rb
543
+ - spec/noahapp_service_spec.rb
544
+ - spec/noahapp_spec.rb
545
+ - spec/noahapp_tag_spec.rb
546
+ - spec/noahapp_watcher_spec.rb
547
+ - spec/service_spec.rb
548
+ - spec/spec_helper.rb
549
+ - spec/support/db/.keep
550
+ - spec/support/sample_data.rb
551
+ - spec/support/test-redis.conf
552
+ - spec/tag_spec.rb
553
+ - spec/watcher_spec.rb