discotheque 0.0.1
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 +9 -0
- data/README.md +55 -0
- data/Rakefile +8 -0
- data/discotheque.gemspec +19 -0
- data/lib/discotheque/discover.rb +54 -0
- data/lib/discotheque/discoverable.rb +5 -0
- data/lib/discotheque/metadata.rb +33 -0
- data/lib/discotheque/poll.rb +0 -0
- data/lib/discotheque/version.rb +3 -0
- data/lib/discotheque.rb +5 -0
- data/test/.keep +0 -0
- data/test/test_ec2.rb +0 -0
- data/test/test_rules.rb +0 -0
- metadata +88 -0
data/.gitignore
ADDED
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Discotheque
|
2
|
+
|
3
|
+
>> "This disco used to be a cute cathedrale" -- Steve Taylor
|
4
|
+
|
5
|
+
Discotheque is aiming to be a general purpose node discovery tool.
|
6
|
+
|
7
|
+
It was inspired by the ZenDiscovery functionality of ElasticSearch, originally the [EC2 discovery code](https://github.com/elasticsearch/elasticsearch/blob/master/plugins/cloud/aws/src/main/java/org/elasticsearch/discovery/ec2/AwsEc2UnicastHostsProvider.java)
|
8
|
+
|
9
|
+
When initially setting up our ElasticSearch clusters, I was amazed at how "magical" it was at finding other ES nodes on EC2. Curiosity got the better of me...
|
10
|
+
Originally this was going to be just a single hack for porting that logic but I've decided to go a bit further.
|
11
|
+
|
12
|
+
## The plan
|
13
|
+
Right now this is a really ghetto MVP. Given a list of any combination of these filters:
|
14
|
+
|
15
|
+
- "sg" security group
|
16
|
+
- "ami" ami id
|
17
|
+
- "az" availability zone
|
18
|
+
- "arch" architecture
|
19
|
+
|
20
|
+
You'll get back a list of matching nodes. It's up to you to decide what to do with them.
|
21
|
+
|
22
|
+
The way it currently works is by getting information about the node it's currently running on via EC2 metadata calls. From there, it uses that information to populate the filters.
|
23
|
+
|
24
|
+
So if your node is in us-east-1a, running `Discotheque::Discover` with an `az` filter, will give you all the nodes in your availability zone.
|
25
|
+
|
26
|
+
Long term, there will be mutliple different discovery methods - unicast, multicast, ec2..you name it. Additionally, you'll be able to specify a "test" criteria to further pare down the list. Also the plan is to provide a mixin when you can make your application "discoverable" - say responding to a given port request with a fingerprint.
|
27
|
+
|
28
|
+
## Example usage (kind of pointless at this early of a stage)
|
29
|
+
__Again, you'll need to be on an EC2 node. I'll resolve this in the future__
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
c = Discotheque::Discover.new
|
33
|
+
c.get_nodes :access_key_id => "YYYYYYYYYYYYYYYYYYYY", :secret_access_key => "XXXXXXXXXXXXXXXXXXXXXXXXXX"
|
34
|
+
# pretty much returns all nodes since there are no filters
|
35
|
+
# ["1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4"]
|
36
|
+
c.filters << "sg"
|
37
|
+
c.get_nodes :access_key_id => "YYYYYYYYYYYYYYYYYYYY", :secret_access_key => "XXXXXXXXXXXXXXXXXXXXXXXXXX"
|
38
|
+
# ["1.1.1.1", "2.2.2.2", "3.3.3.3"]
|
39
|
+
c.filters << "ami"
|
40
|
+
# ["2.2.2.2", "3.3.3.3"]
|
41
|
+
c.filters
|
42
|
+
# ["ami", "sg"]
|
43
|
+
c.clear_filters
|
44
|
+
# []
|
45
|
+
# If you want to see what Discotheque knows about the node it's running on
|
46
|
+
m = Discotheque::Metadata.new
|
47
|
+
#<Discotheque::Metadata:0x00000000fb1008
|
48
|
+
# @availability_zone="us-east-1a",
|
49
|
+
# @group_name="default",
|
50
|
+
# @image_id="ami-221fec4b">
|
51
|
+
```
|
52
|
+
|
53
|
+
If you pass in `true` to the constructor you'll get the mock data above
|
54
|
+
|
55
|
+
|
data/Rakefile
ADDED
data/discotheque.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'discotheque/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "discotheque"
|
6
|
+
s.version = Discotheque::VERSION
|
7
|
+
s.authors = ["John E. Vincent"]
|
8
|
+
s.email = ["lusis.org+github.com@gmail.com"]
|
9
|
+
|
10
|
+
s.summary = "Framework for node discovery"
|
11
|
+
s.description = "Adds functionality to your application for node discovery using Amazon EC2"
|
12
|
+
s.homepage = "https://github.com/lusis/discotheque"
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
|
16
|
+
s.add_dependency("aws-sdk", "= 1.1.2")
|
17
|
+
s.add_dependency("rake", "= 0.9.2")
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Discotheque
|
2
|
+
class Discover
|
3
|
+
# NOTE
|
4
|
+
# tags are not available via metadata calls
|
5
|
+
# therefore tag will need to be an explcit value passed in
|
6
|
+
# This actually makes sense if you want to discover a tag that isn't yours
|
7
|
+
# Take the use case of a master/slave setup:
|
8
|
+
# You would tag the master node with "foo_slave"
|
9
|
+
# but you might need to find all slaves
|
10
|
+
#
|
11
|
+
VALID_FILTERS = %w[az sg tag ami arch]
|
12
|
+
FILTER_MAP = {"az" => "availability-zone",
|
13
|
+
"sg" => "group-name",
|
14
|
+
"ami" => "image-id",
|
15
|
+
"arch" => "architecture"}
|
16
|
+
|
17
|
+
attr_accessor :filters
|
18
|
+
|
19
|
+
def initialize(filters=[])
|
20
|
+
@filters = filters
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_nodes(creds={})
|
24
|
+
# creds is a hash like so
|
25
|
+
# creds = {:access_key_id => "YYYYYYYYYYYYYYYYYYYYYYYYYY", :secret_access_key => "XXXXXXXXXXXXX"}
|
26
|
+
@filters.empty? ? f="ec2.instances" : f="ec2.instances.#{build_filter}"
|
27
|
+
require 'aws-sdk'
|
28
|
+
AWS.config creds
|
29
|
+
ec2 = AWS::EC2.new
|
30
|
+
candidates = AWS.memoize do
|
31
|
+
ci = eval(f)
|
32
|
+
ci.to_a.sort_by(&:ip_address).map {|i| i.ip_address}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def clear_filters
|
37
|
+
@filters = []
|
38
|
+
end
|
39
|
+
private
|
40
|
+
def build_filter
|
41
|
+
whoami = Metadata.new
|
42
|
+
f = {}
|
43
|
+
method_text = []
|
44
|
+
@filters.each do |filter|
|
45
|
+
next if (VALID_FILTERS.member?(filter) == false)
|
46
|
+
f.merge!({"#{FILTER_MAP[filter]}" => whoami.instance_variable_get("@#{FILTER_MAP[filter].gsub(/-/,"_")}")})
|
47
|
+
end
|
48
|
+
f.each do |k,v|
|
49
|
+
method_text << "filter('#{k}','#{v}')"
|
50
|
+
end
|
51
|
+
method_text.join('.')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Discotheque
|
2
|
+
class Metadata
|
3
|
+
|
4
|
+
attr_reader :instance_id, :image_id, :group_name, :availability_zone
|
5
|
+
|
6
|
+
def initialize(mock=false)
|
7
|
+
if mock == true
|
8
|
+
@image_id = "ami-221fec4b" # amazon linux ami
|
9
|
+
@group_name = "default"
|
10
|
+
@availability_zone = "us-east-1a"
|
11
|
+
return
|
12
|
+
else
|
13
|
+
base_url = "http://169.254.169.254/latest/meta-data/"
|
14
|
+
begin
|
15
|
+
%w[instance-id ami-id security-groups availability-zone].each do |datum|
|
16
|
+
datum == "availability-zone" ? url="#{base_url}/placement/#{datum}" : url="#{base_url}#{datum}"
|
17
|
+
d = HTTParty.get("#{url}").parsed_response
|
18
|
+
if datum == "security-groups"
|
19
|
+
instance_variable_set "@group_name", d
|
20
|
+
elsif datum == "ami-id"
|
21
|
+
instance_variable_set "@image_id", d
|
22
|
+
else
|
23
|
+
instance_variable_set "@#{datum.gsub(/-/,"_")}", d
|
24
|
+
end
|
25
|
+
end
|
26
|
+
rescue Errno::EHOSTUNREACH
|
27
|
+
puts "This only makes sense on EC2 hosts"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
File without changes
|
data/lib/discotheque.rb
ADDED
data/test/.keep
ADDED
File without changes
|
data/test/test_ec2.rb
ADDED
File without changes
|
data/test/test_rules.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: discotheque
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- John E. Vincent
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-08-26 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: aws-sdk
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - "="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.1.2
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rake
|
28
|
+
prerelease: false
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - "="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 0.9.2
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id002
|
37
|
+
description: Adds functionality to your application for node discovery using Amazon EC2
|
38
|
+
email:
|
39
|
+
- lusis.org+github.com@gmail.com
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files: []
|
45
|
+
|
46
|
+
files:
|
47
|
+
- .gitignore
|
48
|
+
- README.md
|
49
|
+
- Rakefile
|
50
|
+
- discotheque.gemspec
|
51
|
+
- lib/discotheque.rb
|
52
|
+
- lib/discotheque/discover.rb
|
53
|
+
- lib/discotheque/discoverable.rb
|
54
|
+
- lib/discotheque/metadata.rb
|
55
|
+
- lib/discotheque/poll.rb
|
56
|
+
- lib/discotheque/version.rb
|
57
|
+
- test/.keep
|
58
|
+
- test/test_ec2.rb
|
59
|
+
- test/test_rules.rb
|
60
|
+
homepage: https://github.com/lusis/discotheque
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.8.6
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: Framework for node discovery
|
87
|
+
test_files: []
|
88
|
+
|