noah 0.8.5 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.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