ec2_userdata 1.0

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.
@@ -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
+