noah 0.8.4 → 0.8.5

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
@@ -15,3 +15,4 @@ doc
15
15
  .yardoc/*
16
16
  examples/log/*
17
17
  examples/tmp/*
18
+ *.rbc
@@ -1,25 +1,67 @@
1
1
  #!/usr/bin/env ruby
2
2
  $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
3
+ CONNERRHELP = <<EOC
4
+
5
+ ---------------------------------------------------------------------------
6
+ Apparently we could not connect to the redis instance.
7
+
8
+ By default the watcher will attempt to connect to "redis://localhost:6379/0"
9
+ If your redis instance is listening elsewhere, please start like so:
10
+
11
+ REDIS_URL="redis://hostname:port/dbnum" noah-watcher.rb
12
+
13
+ This will be rectified in a future release. Sorry about that.
14
+ ----------------------------------------------------------------------------
15
+ EOC
16
+
3
17
  HELP = <<-EOH
18
+ ---------------------------------------------------------------------------------------
4
19
  Unfortunately, the agent script has some difficult requirements right now.
5
- Please see https://github.com/lusis/Noah/Watcher-Agent for details.
20
+ Please rerun with the '--depinstall' option to have them installed for you and try again
21
+ ---------------------------------------------------------------------------------------
6
22
  EOH
23
+ require 'rubygems'
24
+ require 'slop'
25
+ require 'logger'
26
+ require 'json'
27
+
28
+ opts = Slop.parse do
29
+ banner "Usage: noah-watcher.rb [options]"
30
+ on '--depinstall', "Installs additional dependencies" do
31
+ puts "Installing dependencies"
32
+ puts "em-hiredis..."
33
+ `gem install em-hiredis`
34
+ puts "em-http-request prerelease..."
35
+ `gem install em-http-request --pre`
36
+ puts "cookiejar...."
37
+ `gem install cookiejar`
38
+ exit
39
+ end
40
+ on :h, :help, 'Print help', :tail => true do
41
+ puts help
42
+ exit
43
+ end
44
+ end
45
+
7
46
  begin
8
- require 'rubygems'
9
- require 'logger'
10
- require 'optparse'
11
47
  require 'em-hiredis'
12
48
  require 'eventmachine'
13
49
  require 'em-http-request'
14
- require 'noah'
15
- require 'noah/agent'
16
- require 'json'
50
+ require 'cookiejar'
17
51
  rescue LoadError => e
18
52
  puts e.message
19
53
  puts HELP
20
54
  exit
21
55
  end
22
56
 
57
+ begin
58
+ require 'noah'
59
+ require 'noah/agent'
60
+ rescue Errno::ECONNREFUSED
61
+ puts CONNERRHELP
62
+ exit
63
+ end
64
+
23
65
  Noah::Log.logger = Logger.new(STDOUT)
24
66
  LOGGER = Noah::Log.logger
25
67
  LOGGER.progname = __FILE__
@@ -32,21 +74,14 @@ EventMachine.run do
32
74
  noah = Noah::Agent.new
33
75
  noah.errback{|x| LOGGER.error("Errback: #{x}")}
34
76
  noah.callback{|y| LOGGER.info("Callback: #{y}")}
35
- # Passing messages...like a boss
36
- #master_channel = EventMachine::Channel.new
37
77
 
38
- r = EventMachine::Hiredis::Client.connect
78
+ r = EventMachine::Hiredis.connect(ENV["REDIS_URL"])
39
79
  r.errback{|x| LOGGER.error("Unable to connect to redis: #{x}")}
40
80
  LOGGER.info("Attaching to Redis Pubsub")
41
81
  r.psubscribe("*")
42
82
  r.on(:pmessage) do |pattern, event, message|
43
83
  noah.reread_watchers if event =~ /^\/\/noah\/watchers\/.*/
44
84
  noah.broker("#{event}|#{message}") unless noah.watchers == 0
45
- #master_channel.push "#{event}|#{message}"
46
85
  end
47
86
 
48
- #sub = master_channel.subscribe {|msg|
49
- # We short circuit if we have no watchers
50
- # noah.broker(msg) unless noah.watchers == 0
51
- #}
52
87
  end
@@ -5,6 +5,7 @@ require File.join(File.dirname(__FILE__), 'models')
5
5
  module Noah
6
6
  class App < Sinatra::Base
7
7
  helpers Noah::SinatraBaseHelpers
8
+ helpers Noah::SinatraTagHelpers
8
9
 
9
10
  configure do
10
11
  set :app_file, __FILE__
@@ -0,0 +1,46 @@
1
+ module Noah
2
+ module SinatraTagHelpers
3
+ # TODO DRY this sumbitch up
4
+ # TODO add status in json response
5
+
6
+ def tag(primitive, name, tags)
7
+ case primitive
8
+ when "services"
9
+ servicename, hostname = name.split('/')
10
+ obj = host_service(hostname, servicename)
11
+ when "hosts"
12
+ obj = Noah::Host.find(:name=>name).first
13
+ when "configurations"
14
+ obj = Noah::Configuration.find(:name=>name).first
15
+ when "applications"
16
+ obj = Noah::Application.find(:name=>name).first
17
+ when "ephemerals"
18
+ obj = Noah::Ephemeral.find(:path=>"/#{name}").first
19
+ else
20
+ halt 404
21
+ end
22
+ obj.nil? ? (halt 404) : (obj.tag!(tags))
23
+ obj.to_json
24
+ end
25
+
26
+ def untag(primitive, name, tags)
27
+ case primitive
28
+ when "services"
29
+ servicename, hostname = name.split('/')
30
+ obj = host_service(hostname, servicename)
31
+ when "hosts"
32
+ obj = Noah::Host.find(:name=>name).first
33
+ when "configurations"
34
+ obj = Noah::Configuration.find(:name=>name).first
35
+ when "applications"
36
+ obj = Noah::Application.find(:name=>name).first
37
+ when "ephemerals"
38
+ obj = Noah::Ephemeral.find(:path=>"/#{name}").first
39
+ else
40
+ halt 404
41
+ end
42
+ obj.to_json
43
+ end
44
+
45
+ end
46
+ end
@@ -129,3 +129,4 @@ require File.join(File.dirname(__FILE__), 'models','applications')
129
129
  require File.join(File.dirname(__FILE__), 'models','configurations')
130
130
  require File.join(File.dirname(__FILE__), 'models','watchers')
131
131
  require File.join(File.dirname(__FILE__), 'models','ephemerals')
132
+ require File.join(File.dirname(__FILE__), 'models','tokens')
@@ -0,0 +1,41 @@
1
+ module Noah
2
+ class Token < Model
3
+ include Taggable
4
+ include Linkable
5
+ attribute :name
6
+ attribute :token
7
+ attribute :lifetime
8
+
9
+ index :name
10
+ index :token
11
+ index :lifetime
12
+
13
+ before :save, :generate_api_token
14
+
15
+ def validate
16
+ super
17
+ assert_present :name
18
+ assert_unique :name
19
+ assert_unique :token
20
+ end
21
+
22
+ def to_hash
23
+ h = {:token => token, :lifetime => lifetime, :created_at => created_at, :updated_at => updated_at}
24
+ super.merge(h)
25
+ end
26
+
27
+ protected
28
+ def generate_api_token
29
+ # Wicked hot logic to generate an API token
30
+ random_string = (0...50).map{ ('a'..'z').to_a[rand(26)] }.join
31
+ self.token.nil? ? self.token = OpenSSL::Digest::SHA256.hexdigest(random_string << self.name << Time.now.to_s) : self.token
32
+ end
33
+
34
+ def save_hook
35
+ # called after any create,update,delete
36
+ # logic needed to expire any orphaned ephemerals
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -13,22 +13,6 @@ class Noah::App
13
13
  app.to_json
14
14
  end
15
15
 
16
- put '/applications/:appname/tag' do |appname|
17
- required_params = ["tags"]
18
- data = JSON.parse(request.body.read)
19
- (data.keys.sort == required_params.sort) ? (a=Noah::Application.find(:name=>appname).first) : (raise "Missing Parameters")
20
- a.nil? ? (halt 404) : (a.tag!(data['tags']))
21
- a.to_json
22
- end
23
-
24
- delete '/applications/:appname/tag' do |appname|
25
- required_params = ["tags"]
26
- data = JSON.parse(request.body.read)
27
- (data.keys.sort == required_params.sort) ? (a=Noah::Application.find(:name=>appname).first) : (raise "Missing Parameters")
28
- a.nil? ? (halt 404) : (a.untag!(data['tags']))
29
- a.to_json
30
- end
31
-
32
16
  put '/applications/:appname/watch' do |appname|
33
17
  required_params = ["endpoint"]
34
18
  data = JSON.parse(request.body.read)
@@ -31,22 +31,7 @@ class Noah::App
31
31
  a.nil? ? (halt 404) : (a.link! data["link_name"])
32
32
  a.to_json
33
33
  end
34
- # Add a tag to a configuration object
35
- put '/configurations/:configname/tag' do |configname|
36
- required_params = ["tags"]
37
- data = JSON.parse(request.body.read)
38
- (data.keys.sort == required_params.sort) ? (c=Noah::Configuration.find(:name=>configname).first) : (raise "Missing Parameters")
39
- c.nil? ? (halt 404) : (c.tag!(data['tags']))
40
- c.to_json
41
- end
42
- # Delete a tag[s] from a configuration object
43
- delete '/configurations/:configname/tag' do |configname|
44
- required_params = ["tags"]
45
- data = JSON.parse(request.body.read)
46
- (data.keys.sort == required_params.sort) ? (c=Noah::Configuration.find(:name=>configname).first) : (raise "Missing Parameters")
47
- c.nil? ? (halt 404) : (c.untag!(data['tags']))
48
- c.to_json
49
- end
34
+
50
35
  # Add a watch to a configuration object
51
36
  put '/configurations/:configname/watch' do |configname|
52
37
  required_params = ["endpoint"]
@@ -32,24 +32,6 @@ class Noah::App
32
32
  end
33
33
  end
34
34
 
35
- put '/hosts/:hostname/tag' do |hostname|
36
- required_params = ["tags"]
37
- data = JSON.parse(request.body.read)
38
- raise "Missing parameters" if data.nil?
39
- (data.keys.sort == required_params.sort) ? (a=Noah::Host.find(:name=>hostname).first) : (raise "Missing Parameters")
40
- a.nil? ? (halt 404) : (a.tag!(data['tags']))
41
- a.to_json
42
- end
43
-
44
- delete '/hosts/:hostname/tag' do |hostname|
45
- required_params = ["tags"]
46
- data = JSON.parse(request.body.read)
47
- raise "Missing parameters" if data.nil?
48
- (data.keys.sort == required_params.sort) ? (a=Noah::Host.find(:name=>hostname).first) : (raise "Missing Parameters")
49
- a.nil? ? (halt 404) : (a.untag!(data['tags']))
50
- a.to_json
51
- end
52
-
53
35
  put '/hosts/:hostname/watch' do |hostname|
54
36
  required_params = ["endpoint"]
55
37
  data = JSON.parse(request.body.read)
@@ -38,22 +38,6 @@ class Noah::App
38
38
  a.to_json
39
39
  end
40
40
 
41
- put '/services/:servicename/:hostname/tag' do |servicename, hostname|
42
- required_params = ["tags"]
43
- data = JSON.parse(request.body.read)
44
- (data.keys.sort == required_params.sort) ? (a=host_service(hostname, servicename)) : (raise "Missing Parameters")
45
- a.nil? ? (halt 404) : (a.tag!(data['tags']))
46
- a.to_json
47
- end
48
-
49
- delete '/services/:servicename/:hostname/tag' do |servicename, hostname|
50
- required_params = ["tags"]
51
- data = JSON.parse(request.body.read)
52
- (data.keys.sort == required_params.sort) ? (a=host_service(hostname, servicename)) : (raise "Missing Parameters")
53
- a.nil? ? (halt 404) : (a.untag!(data['tags']))
54
- a.to_json
55
- end
56
-
57
41
  put '/services/:servicename/watch' do |servicename|
58
42
  required_params = ["endpoint"]
59
43
  data = JSON.parse(request.body.read)
@@ -1,5 +1,17 @@
1
1
  class Noah::App
2
2
 
3
+ put '/:primitive/*/tag' do |primitive, name|
4
+ required_params = ["tags"]
5
+ data = JSON.parse(request.body.read)
6
+ (data.keys.sort == required_params.sort) ? (tag(primitive, name, data["tags"])) : (raise "Missing Parameters")
7
+ end
8
+
9
+ delete '/:primitive/*/tag' do |primitive, name|
10
+ required_params = ["tags"]
11
+ data = JSON.parse(request.body.read)
12
+ (data.keys.sort == required_params.sort) ? (untag(primitive, name, data["tags"])) : (raise "Missing Parameters")
13
+ end
14
+
3
15
  get '/tags/:tagname/?' do |tagname|
4
16
  tags = Noah::Tags.all(:name => tagname).to_hash
5
17
  (halt 404) if tags.size == 0
@@ -1,3 +1,3 @@
1
1
  module Noah
2
- VERSION = "0.8.4"
2
+ VERSION = "0.8.5"
3
3
  end
@@ -11,8 +11,8 @@ Gem::Specification.new do |s|
11
11
  s.authors = ["John E. Vincent"]
12
12
  s.email = ["lusis.org+rubygems.org@gmail.com"]
13
13
  s.homepage = "https://github.com/lusis/noah"
14
- s.summary = %q{Application registry based on Apache Zookeeper}
15
- s.description = %q{Application registry based on Apache Zookeeper}
14
+ s.summary = %q{Application registry inspired by Apache Zookeeper}
15
+ s.description = %q{Application registry inspired by Apache Zookeeper}
16
16
 
17
17
  s.rubyforge_project = "noah"
18
18
 
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_dependency("haml", ["= 3.0.25"])
34
34
  s.add_dependency("vegas", ["= 0.1.8"])
35
35
  s.add_dependency("guid", ["= 0.1.1"])
36
+ s.add_dependency("slop", ["= 2.1.0"])
36
37
 
37
38
 
38
39
  if RUBY_PLATFORM =~ /java/
@@ -49,6 +50,7 @@ Gem::Specification.new do |s|
49
50
  s.add_development_dependency("diff-lcs", ["= 1.1.2"])
50
51
  s.add_development_dependency("sinatra-reloader", ["= 0.5.0"])
51
52
  s.add_development_dependency("rspec", ["~> 2.5"])
52
- s.add_development_dependency("rcov", ["= 0.9.9"])
53
+ # s.add_development_dependency("rcov", ["= 0.9.9"])
53
54
  s.add_development_dependency("rack-test", ["= 0.5.7"])
55
+ s.add_development_dependency("rake", ["= 0.8.7"])
54
56
  end
@@ -59,15 +59,16 @@ describe "Using the Link Model", :reset_redis => true do
59
59
  h[:updated_at].should == l.updated_at
60
60
  h[:created_at].should == l.created_at
61
61
  h[:hosts].has_key?(@host.name).should == true
62
- h[:hosts][@host.name].keys.sort.should == [:id, :status, :tags, :services].sort
62
+ h[:hosts][@host.name].keys.map {|k| k.to_s}.sort.should == [:id, :status, :tags, :services].map {|k| k.to_s}.sort
63
63
  h[:services].has_key?(@service.name).should == true
64
- h[:services][@service.name][@host.name].keys.sort.should == [:id, :status, :tags].sort
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
65
  h[:applications].has_key?(@application.name).should == true
66
- h[:applications][@application.name].keys.sort.should == [:id, :tags, :configurations].sort
66
+ h[:applications][@application.name].keys.map {|k| k.to_s}.sort.should == [:id, :tags, :configurations].map {|k| k.to_s}.sort
67
67
  h[:configurations].has_key?(@configuration.name).should == true
68
- h[:configurations][@configuration.name].keys.sort.should == [:id, :tags, :format, :body].sort
68
+ h[:configurations][@configuration.name].keys.map {|k| k.to_s }.sort.should == [:id, :tags, :format, :body].map {|k| k.to_s}.sort
69
69
  h[:ephemerals].has_key?(@ephemeral.name).should == true
70
- h[:ephemerals][@ephemeral.name].keys.sort.should == [:id, :tags, :path, :data].sort
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
  end
72
73
  end
73
74
  describe "should not" do
@@ -84,5 +85,3 @@ describe "Using the Link Model", :reset_redis => true do
84
85
  end
85
86
  end
86
87
  end
87
-
88
-
@@ -0,0 +1,94 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Using the Tag API", :reset_redis => true do
4
+ before(:each) do
5
+ Ohm.redis.flushdb
6
+ @multi_tags = {"tags"=>["production", "databases", "in-service"]}
7
+ @single_tag = {"tags"=>"out-of-service"}
8
+ @host = Noah::Host.create(:name => 'tagged_host', :status => 'up')
9
+ @service = Noah::Service.create(:name => 'tagged_service', :status => 'down', :host_id => @host.id)
10
+ @application = Noah::Application.create(:name => 'tagged_application')
11
+ @configuration = Noah::Configuration.create(:name => 'tagged_configuration', :format => 'string', :body => 'some_string')
12
+ @ephemeral = Noah::Ephemeral.create(:path => '/tagged/ephemeral')
13
+ end
14
+ after(:each) do
15
+ Ohm.redis.flushdb
16
+ end
17
+
18
+ describe "calling" do
19
+
20
+ describe "PUT" do
21
+ ['host', 'service', 'application', 'configuration', 'ephemeral'].each do |primitive|
22
+ it "multiple tags to #{primitive} should work" do
23
+ obj = instance_variable_get("@#{primitive}")
24
+ case primitive
25
+ when "ephemeral"
26
+ put "/#{primitive}s#{obj.path}/tag", @multi_tags.to_json
27
+ when "service"
28
+ put "/#{primitive}s/#{obj.name}/#{@host.name}/tag", @multi_tags.to_json
29
+ else
30
+ put "/#{primitive}s/#{obj.name}/tag", @multi_tags.to_json
31
+ end
32
+ last_response.should be_ok
33
+ response = last_response.should return_json
34
+ response['tags'].sort.should == @multi_tags["tags"].sort
35
+ end
36
+ end
37
+
38
+ ['host', 'service', 'application', 'configuration', 'ephemeral'].each do |primitive|
39
+ it "single tag to #{primitive} should work" do
40
+ obj = instance_variable_get("@#{primitive}")
41
+ case primitive
42
+ when "ephemeral"
43
+ put "/#{primitive}s#{obj.path}/tag", @single_tag.to_json
44
+ when "service"
45
+ put "/#{primitive}s/#{obj.name}/#{@host.name}/tag", @single_tag.to_json
46
+ else
47
+ put "/#{primitive}s/#{obj.name}/tag", @single_tag.to_json
48
+ end
49
+ last_response.should be_ok
50
+ response = last_response.should return_json
51
+ response['tags'].should == [@single_tag["tags"]]
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "DELETE" do
57
+ ['host', 'service', 'application', 'configuration', 'ephemeral'].each do |primitive|
58
+ it "multiple tags from #{primitive} should work" do
59
+ obj = instance_variable_get("@#{primitive}")
60
+ case primitive
61
+ when "ephemeral"
62
+ delete "/#{primitive}s#{obj.path}/tag", @multi_tags.to_json
63
+ when "service"
64
+ delete "/#{primitive}s/#{obj.name}/#{@host.name}/tag", @multi_tags.to_json
65
+ else
66
+ delete "/#{primitive}s/#{obj.name}/tag", @multi_tags.to_json
67
+ end
68
+ last_response.should be_ok
69
+ response = last_response.should return_json
70
+ response['tags'].sort.should_not == @multi_tags["tags"].sort
71
+ response['tags'].size.should == 0
72
+ end
73
+ end
74
+
75
+ ['host', 'service', 'application', 'configuration', 'ephemeral'].each do |primitive|
76
+ it "single tag from #{primitive} should work" do
77
+ obj = instance_variable_get("@#{primitive}")
78
+ case primitive
79
+ when "ephemeral"
80
+ delete "/#{primitive}s#{obj.path}/tag", @single_tag.to_json
81
+ when "service"
82
+ delete "/#{primitive}s/#{obj.name}/#{@host.name}/tag", @single_tag.to_json
83
+ else
84
+ delete "/#{primitive}s/#{obj.name}/tag", @single_tag.to_json
85
+ end
86
+ last_response.should be_ok
87
+ response = last_response.should return_json
88
+ response['tags'].should_not == [@single_tag["tags"]]
89
+ response['tags'].size.should == 0
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: noah
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.8.4
5
+ version: 0.8.5
6
6
  platform: ruby
7
7
  authors:
8
8
  - John E. Vincent
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-08 00:00:00 -04:00
13
+ date: 2011-08-05 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -146,29 +146,29 @@ dependencies:
146
146
  type: :runtime
147
147
  version_requirements: *id012
148
148
  - !ruby/object:Gem::Dependency
149
- name: hiredis
149
+ name: slop
150
150
  prerelease: false
151
151
  requirement: &id013 !ruby/object:Gem::Requirement
152
152
  none: false
153
153
  requirements:
154
154
  - - "="
155
155
  - !ruby/object:Gem::Version
156
- version: 0.3.1
156
+ version: 2.1.0
157
157
  type: :runtime
158
158
  version_requirements: *id013
159
159
  - !ruby/object:Gem::Dependency
160
- name: yajl-ruby
160
+ name: hiredis
161
161
  prerelease: false
162
162
  requirement: &id014 !ruby/object:Gem::Requirement
163
163
  none: false
164
164
  requirements:
165
- - - ">="
165
+ - - "="
166
166
  - !ruby/object:Gem::Version
167
- version: "0"
167
+ version: 0.3.1
168
168
  type: :runtime
169
169
  version_requirements: *id014
170
170
  - !ruby/object:Gem::Dependency
171
- name: thin
171
+ name: yajl-ruby
172
172
  prerelease: false
173
173
  requirement: &id015 !ruby/object:Gem::Requirement
174
174
  none: false
@@ -179,47 +179,47 @@ dependencies:
179
179
  type: :runtime
180
180
  version_requirements: *id015
181
181
  - !ruby/object:Gem::Dependency
182
- name: diff-lcs
182
+ name: thin
183
183
  prerelease: false
184
184
  requirement: &id016 !ruby/object:Gem::Requirement
185
185
  none: false
186
186
  requirements:
187
- - - "="
187
+ - - ">="
188
188
  - !ruby/object:Gem::Version
189
- version: 1.1.2
190
- type: :development
189
+ version: "0"
190
+ type: :runtime
191
191
  version_requirements: *id016
192
192
  - !ruby/object:Gem::Dependency
193
- name: sinatra-reloader
193
+ name: diff-lcs
194
194
  prerelease: false
195
195
  requirement: &id017 !ruby/object:Gem::Requirement
196
196
  none: false
197
197
  requirements:
198
198
  - - "="
199
199
  - !ruby/object:Gem::Version
200
- version: 0.5.0
200
+ version: 1.1.2
201
201
  type: :development
202
202
  version_requirements: *id017
203
203
  - !ruby/object:Gem::Dependency
204
- name: rspec
204
+ name: sinatra-reloader
205
205
  prerelease: false
206
206
  requirement: &id018 !ruby/object:Gem::Requirement
207
207
  none: false
208
208
  requirements:
209
- - - ~>
209
+ - - "="
210
210
  - !ruby/object:Gem::Version
211
- version: "2.5"
211
+ version: 0.5.0
212
212
  type: :development
213
213
  version_requirements: *id018
214
214
  - !ruby/object:Gem::Dependency
215
- name: rcov
215
+ name: rspec
216
216
  prerelease: false
217
217
  requirement: &id019 !ruby/object:Gem::Requirement
218
218
  none: false
219
219
  requirements:
220
- - - "="
220
+ - - ~>
221
221
  - !ruby/object:Gem::Version
222
- version: 0.9.9
222
+ version: "2.5"
223
223
  type: :development
224
224
  version_requirements: *id019
225
225
  - !ruby/object:Gem::Dependency
@@ -233,7 +233,18 @@ dependencies:
233
233
  version: 0.5.7
234
234
  type: :development
235
235
  version_requirements: *id020
236
- description: Application registry based on Apache Zookeeper
236
+ - !ruby/object:Gem::Dependency
237
+ name: rake
238
+ prerelease: false
239
+ requirement: &id021 !ruby/object:Gem::Requirement
240
+ none: false
241
+ requirements:
242
+ - - "="
243
+ - !ruby/object:Gem::Version
244
+ version: 0.8.7
245
+ type: :development
246
+ version_requirements: *id021
247
+ description: Application registry inspired by Apache Zookeeper
237
248
  email:
238
249
  - lusis.org+rubygems.org@gmail.com
239
250
  executables:
@@ -302,6 +313,7 @@ files:
302
313
  - lib/noah/models/link.rb
303
314
  - lib/noah/models/services.rb
304
315
  - lib/noah/models/tags.rb
316
+ - lib/noah/models/tokens.rb
305
317
  - lib/noah/models/watchers.rb
306
318
  - lib/noah/passthrough.rb
307
319
  - lib/noah/routes/applications.rb
@@ -329,6 +341,7 @@ files:
329
341
  - spec/noahapp_host_spec.rb
330
342
  - spec/noahapp_service_spec.rb
331
343
  - spec/noahapp_spec.rb
344
+ - spec/noahapp_tag_spec.rb
332
345
  - spec/noahapp_watcher_spec.rb
333
346
  - spec/service_spec.rb
334
347
  - spec/spec_helper.rb
@@ -368,6 +381,6 @@ rubyforge_project: noah
368
381
  rubygems_version: 1.6.2
369
382
  signing_key:
370
383
  specification_version: 3
371
- summary: Application registry based on Apache Zookeeper
384
+ summary: Application registry inspired by Apache Zookeeper
372
385
  test_files: []
373
386