noah 0.8.4 → 0.8.5

Sign up to get free protection for your applications and to get access to all the features.
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