ec2_userdata 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,80 @@
1
+ require 'net/http'
2
+ require 'json/pure'
3
+
4
+ module EC2
5
+ class UserData
6
+ def self.[](key)
7
+ if @userdata.nil?
8
+ if EC2.ec2?
9
+ logger.info "Running on EC2. Reading user data from http://169.254.169.254/1.0/user-data" if logger
10
+ @userdata = get_ec2_userdata
11
+ else
12
+ logger.info "Not running on EC2. Reading user data from #{app_root}/config/ec2_userdata.yml." if logger
13
+ @userdata = get_local_userdata
14
+ end
15
+ end
16
+
17
+ @userdata[key]
18
+ end
19
+
20
+ private
21
+ def self.get_ec2_userdata
22
+ JSON.parse(Net::HTTP.get(URI.parse("http://169.254.169.254/1.0/user-data")))
23
+ end
24
+
25
+ def self.get_local_userdata
26
+ if app_root
27
+ YAML.load_file("#{app_root}/config/ec2_userdata.yml")
28
+ else
29
+ raise "Cannot find app_root. Don't know what to do!"
30
+ end
31
+ end
32
+
33
+ def self.logger
34
+ if defined?(Rails)
35
+ Rails.logger
36
+ elsif defined?(Merb)
37
+ Merb.logger
38
+ elsif defined?(LOGGER)
39
+ LOGGER
40
+ else
41
+ nil
42
+ end
43
+ end
44
+
45
+ def self.app_root
46
+ if defined?(Rails)
47
+ RAILS_ROOT
48
+ elsif defined?(Merb)
49
+ Merb.root
50
+ elsif defined?(APP_ROOT)
51
+ APP_ROOT
52
+ else
53
+ nil
54
+ end
55
+ end
56
+ end
57
+
58
+ # Returns true if the current instance is running on the EC2 cloud
59
+ def self.ec2?
60
+ return @running_on_ec2 if @running_on_ec2
61
+ raise("nslookup must be in the path") if cmd_exec("which nslookup").blank?
62
+ @running_on_ec2 = (cmd_exec("nslookup 169.254.169.254").match(/NXDOMAIN/) || []).size < 1
63
+ end
64
+
65
+ private
66
+ def self.cmd_exec(cmd)
67
+ `#{cmd}`
68
+ end
69
+ end
70
+
71
+ ### Active Support ###
72
+ class String
73
+ def blank?
74
+ self.strip.length == 0
75
+ end
76
+ end
77
+
78
+ class NilClass
79
+ def blank?; true; end
80
+ end
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ require 'redgreen'
3
+ require 'test/unit'
4
+ require 'mocha'
5
+ require File.dirname(__FILE__) + '/../../lib/ec2_userdata'
6
+
7
+ APP_ROOT = "File.dirname(__FILE__) + '/../.."
8
+
9
+ class Ec2UserDataTest < Test::Unit::TestCase
10
+ def setup
11
+ EC2::UserData.class_eval("@userdata = nil")
12
+ EC2::module_eval("@running_on_ec2 = nil")
13
+
14
+ end
15
+
16
+ def test_get_on_ec2
17
+ EC2.expects(:ec2?).once.returns(true)
18
+ Net::HTTP.expects(:get).with(URI.parse("http://169.254.169.254/1.0/user-data")).returns(ec2_json_userdata)
19
+
20
+ assert_equal "lisa", EC2::UserData["cluster"]
21
+ assert_equal 11300, EC2::UserData["queue_port"]
22
+ end
23
+
24
+ def test_get_on_local
25
+ EC2.expects(:ec2?).once.returns(false)
26
+ YAML.expects(:load_file).with("#{APP_ROOT}/config/ec2_userdata.yml").returns(YAML.load(local_yaml_userdata))
27
+ assert_equal "lisa", EC2::UserData["cluster"]
28
+ assert_equal 11300, EC2::UserData["queue_port"]
29
+ end
30
+
31
+ def test_ec2_true
32
+ # Yes, on EC2
33
+ EC2.expects(:cmd_exec).with("which nslookup").returns("/usr/bin/nslookup")
34
+ EC2.expects(:cmd_exec).with("nslookup 169.254.169.254").returns(nslookup_on_ec2)
35
+ assert EC2.ec2?
36
+ end
37
+
38
+ def test_ec2_false
39
+ # No, not on EC2
40
+ EC2.expects(:cmd_exec).with("which nslookup").returns("/usr/bin/nslookup")
41
+ EC2.expects(:cmd_exec).with("nslookup 169.254.169.254").returns(nslookup_on_local)
42
+ assert_equal false, EC2.ec2?
43
+ end
44
+
45
+ def test_ec2_ns_lookup_not_found
46
+ # nslookup not found
47
+ EC2.expects(:cmd_exec).with("which nslookup").returns("")
48
+ assert_raises(RuntimeError) { EC2.ec2? }
49
+ end
50
+
51
+
52
+ ## Helpers ##
53
+ def ec2_json_userdata
54
+ '{"queue_host":"lisa-queue.defensio.net","cluster":"lisa","queue_port":11300}'
55
+ end
56
+
57
+ def local_yaml_userdata
58
+ "--- \nqueue_host: lisa-queue.defensio.net\nqueue_port: 11300\ncluster: lisa\n"
59
+ end
60
+
61
+ def nslookup_on_ec2
62
+ "Server: 172.16.0.23\nAddress: 172.16.0.23#53\n\nNon-authoritative answer:\n254.169.254.169.in-addr.arpa name = instance-data.ec2.internal.\n\nAuthoritative answers can be found from:\n"
63
+ end
64
+
65
+ def nslookup_on_local
66
+ "Server: 192.168.1.1\nAddress: 192.168.1.1#53\n\n** server can't find 254.169.254.169.in-addr.arpa.: NXDOMAIN\n"
67
+ end
68
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ec2_userdata
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ version: "1.0"
9
+ platform: ruby
10
+ authors:
11
+ - Carl Mercier
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2010-04-26 00:00:00 -04:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: A simple Ruby library that reads UserData on EC2 with graceful fallback when not running on EC2
21
+ email: carl@carlmercier.com
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files: []
27
+
28
+ files:
29
+ - lib/ec2_userdata.rb
30
+ - test/unit/ec2_userdata_test.rb
31
+ has_rdoc: true
32
+ homepage: http://carlmercier.com
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options: []
37
+
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.3.6
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: A simple Ruby library that reads UserData on EC2 with graceful fallback when not running on EC2
61
+ test_files: []
62
+