cloud_info 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2009 Tung Nguyen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,79 @@
1
+ CloudInfo
2
+ =======
3
+
4
+ Summary
5
+ -------
6
+ Assumes you're using engineyard's amazon could. Allows you to use capistrano deployments to engineyard's amazon cloud without having to update your capistrano deploy.rb every time you add in instances in their gui.
7
+
8
+ Install
9
+ -------
10
+
11
+ <pre>
12
+ sudo gem install cloud_info --source http://gemcutter.org
13
+ </pre>
14
+
15
+ Set up your ~/.ey-cloud.yml file.
16
+ Set up your ~/.ssh/id-rsa-flex-key private key.
17
+
18
+ Usage
19
+ -------
20
+
21
+ in your deploy.rb
22
+
23
+ <pre>
24
+ require 'cloud_info'
25
+
26
+ task :production do
27
+ ey_env_name = "prod1" # this is the environment name in EY's gui interface
28
+ cloud_info = CloudInfo.new(ey_env_name, :private_key => "~/.ssh/id-rsa-flex-key")
29
+
30
+ role :db, cloud_info.app_master, :primary => true
31
+ # web and app slices
32
+ cloud_info.apps.each do |info|
33
+ role :web, info[1]
34
+ role :app, info[1], :sphinx => true
35
+ end
36
+
37
+ # utility slices
38
+ cloud_info.utils.each do |info|
39
+ role :app, info[1], :sphinx => true
40
+ end
41
+
42
+ set :environment_database, Proc.new { production_database }
43
+ set :user, 'deploy'
44
+ set :runner, 'deploy'
45
+ set :rails_env, 'production'
46
+ end
47
+ </pre>
48
+
49
+ To look at what the hosts contain use script/console. cloud_info.apps, cloud_info.utils just holds a hash of keys and dns_names.
50
+
51
+ <pre>
52
+ ./script/console
53
+
54
+ require "cloud_info"
55
+ cloud_info = CloudInfo.new("prod1")
56
+ pp cloud_info.apps
57
+ {
58
+ "prod1_app0" => '123.456.789.123',
59
+ "prod1_app1" => 'ec-123.456.789.123.whatever'
60
+ }
61
+
62
+ pp cloud_info.hosts # shows all hosts
63
+ {
64
+ "prod1_app0" => '123.456.789.123', # app_master
65
+ "prod1_app1" => 'ec-123.456.789.123.whatever', # app
66
+ "prod1_db0" => 'ec-123.456.789.123.whatever', # db_master
67
+ "prod1_db1" => 'ec-123.456.789.123.whatever', # db_slave
68
+ "prod1_util0" => 'ec-123.456.789.123.whatever', # util instance, name util0
69
+ }
70
+ </pre>
71
+
72
+
73
+ Compatibility
74
+ -------------
75
+
76
+ Tested with Ruby 1.8.6.
77
+
78
+ Thanks
79
+ ------
data/Rakefile ADDED
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/gempackagetask'
4
+ require 'spec/rake/spectask'
5
+ require 'gemspec'
6
+
7
+ desc "Generate gemspec"
8
+ task :gemspec do
9
+ File.open("#{Dir.pwd}/#{GEM_NAME}.gemspec", 'w') do |f|
10
+ f.write(GEM_SPEC.to_ruby)
11
+ end
12
+ end
13
+
14
+ desc "Install gem"
15
+ task :install do
16
+ Rake::Task['gem'].invoke
17
+ $stdout.puts "Use sudo?"
18
+ sudo = ($stdin.gets.downcase[0..0] == 'y') ? 'sudo ' : ''
19
+ $stdout.puts "Installing gem..."
20
+ `#{sudo} gem uninstall #{GEM_NAME} -x`
21
+ `#{sudo} gem install pkg/#{GEM_NAME}*.gem`
22
+ `rm -Rf pkg`
23
+ end
24
+
25
+ desc "Package gem"
26
+ Rake::GemPackageTask.new(GEM_SPEC) do |pkg|
27
+ pkg.gem_spec = GEM_SPEC
28
+ end
29
+
30
+ desc "Run specs"
31
+ Spec::Rake::SpecTask.new do |t|
32
+ t.spec_opts = ["--format", "specdoc", "--colour"]
33
+ t.spec_files = FileList["spec/**/*_spec.rb"]
34
+ end
35
+
36
+ task :default => :spec do
37
+ end
38
+
39
+ # You can delete this after you use it
40
+ desc "Rename project"
41
+ task :rename do
42
+ name = ENV['NAME'] || File.basename(Dir.pwd)
43
+ class_name = name.split('_').collect{|x| x.capitalize}.join("")
44
+ begin
45
+ dir = Dir['**/gem_template*']
46
+ from = dir.pop
47
+ if from
48
+ rb = from.include?('.rb')
49
+ to = File.dirname(from) + "/#{name}#{'.rb' if rb}"
50
+ FileUtils.mv(from, to)
51
+ end
52
+ end while dir.length > 0
53
+ Dir["**/*"].each do |path|
54
+ next if path.include?('Rakefile')
55
+ if File.file?(path)
56
+ `sed -i "" 's/gem_template/#{name}/g' #{path}`
57
+ `sed -i "" 's/GemTemplate/#{class_name}/g' #{path}`
58
+ end
59
+ end
60
+ end
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ * clean up the messy code
2
+ * write real specs
data/bin/cloud_info ADDED
File without changes
@@ -0,0 +1,12 @@
1
+ ---
2
+ prod_br:
3
+ prod_br_app0: 184.73.240.218
4
+ prod_br_util0: ec2-174-129-69-169.compute-1.amazonaws.com
5
+ prod_br_memcached0: ec2-204-236-244-26.compute-1.amazonaws.com
6
+ prod_br_util1: ec2-174-129-111-60.compute-1.amazonaws.com
7
+ prod_br_memcached1: ec2-184-73-18-219.compute-1.amazonaws.com
8
+ prod_br_app1: ec2-75-101-183-44.compute-1.amazonaws.com
9
+ prod_br_app2: ec2-174-129-55-203.compute-1.amazonaws.com
10
+ prod_br_app3: ec2-184-73-5-255.compute-1.amazonaws.com
11
+ prod_br_db0: ec2-174-129-47-164.compute-1.amazonaws.com
12
+ prod_br_db1: ec2-72-44-44-156.compute-1.amazonaws.com
data/gemspec.rb ADDED
@@ -0,0 +1,20 @@
1
+ GEM_NAME = 'cloud_info'
2
+ GEM_FILES = FileList['**/*'] - FileList['coverage', 'coverage/**/*', 'pkg', 'pkg/**/*']
3
+ GEM_SPEC = Gem::Specification.new do |s|
4
+ # == CONFIGURE ==
5
+ s.author = "Tung Nguyen"
6
+ s.email = "tongueroo@gmail.com"
7
+ s.homepage = "http://github.com/tongueroo/#{GEM_NAME}"
8
+ s.summary = "cloud_info summary"
9
+ # == CONFIGURE ==
10
+ s.add_dependency('ey-flex', '>=0.5.1')
11
+ s.add_dependency('right_aws', '>=1.10.0')
12
+ s.add_dependency('json', '>=1.0.0')
13
+ s.extra_rdoc_files = [ "README.markdown" ]
14
+ s.files = GEM_FILES.to_a
15
+ s.has_rdoc = false
16
+ s.name = GEM_NAME
17
+ s.platform = Gem::Platform::RUBY
18
+ s.require_path = "lib"
19
+ s.version = "0.1.0"
20
+ end
@@ -0,0 +1,170 @@
1
+ require 'right_aws'
2
+ require 'net/ssh'
3
+ require 'yaml'
4
+ require 'json'
5
+
6
+ class CloudInfo
7
+ class Instances
8
+ attr_accessor :user, :private_key, :servers, :sessions
9
+
10
+ def initialize(cloud_info, options = {})
11
+ @cloud_info = cloud_info
12
+ @home_dir = ENV['HOME']
13
+ @user = "root" # TODO: move out
14
+ @private_key = options[:private_key] # TODO: move out
15
+
16
+ @ey_cloud = "#{@home_dir}/.ey-cloud.yml"
17
+ unless File.exist?(@ey_cloud)
18
+ warn("You need to have an ~/.ey-cloud.yml file")
19
+ exit(1)
20
+ end
21
+ @config = YAML.load(IO.read(@ey_cloud))
22
+
23
+ @servers = {}
24
+ @sessions = []
25
+ @ec2 = setup_ec2
26
+ end
27
+
28
+ def setup_ec2
29
+ RightAws::Ec2.new(@config[:aws_secret_id], @config[:aws_secret_key])
30
+ end
31
+
32
+ def instances_in_group(group_id)
33
+ aws_instances.select {|x| x[:aws_groups].include?(group_id) }
34
+ end
35
+
36
+ # only the instances for the env
37
+ def instances
38
+ instance_ids = ey_instances(@cloud_info.env_name)
39
+ group_id = aws_group_for_instance_id(instance_ids.first)
40
+ instances = instances_in_group(group_id)
41
+ instances
42
+ end
43
+
44
+ def connect_to_servers
45
+ thread = Thread.current
46
+ hosts = instances.collect {|i| i[:dns_name]}
47
+ threads = hosts.collect do |host|
48
+ Thread.new {
49
+ @sessions << Net::SSH.start(host, @user, {:keys => @private_key})
50
+ }
51
+ end
52
+ threads.collect {|t| t.join}
53
+ end
54
+
55
+ def build_server_infos
56
+ return if @built
57
+ execute_on_servers do |ssh|
58
+ @servers[ssh.host] ||= {}
59
+ dna_json = ssh.exec!("cat /etc/chef/dna.json")
60
+ @servers[ssh.host]["dna"] = JSON.parse(dna_json)
61
+ end
62
+ @built = true
63
+ end
64
+
65
+ def execute_on_servers
66
+ connect_to_servers
67
+ sessions.each do |ssh|
68
+ yield(ssh)
69
+ end
70
+ end
71
+
72
+ # builds up the hosts hash
73
+ # TODO: move out
74
+ # looks like this:
75
+ # {"prod_br_app0"=>"123.456.789.123",
76
+ # "prod_br_util0"=>"ec2-123.456.789.123.compute-1.amazonaws.com",
77
+ # "prod_br_memcached0"=>"ec2-123.456.789.123.compute-1.amazonaws.com",
78
+ # "prod_br_util1"=>"ec2-123.456.789.123.compute-1.amazonaws.com",
79
+ # "prod_br_memcached1"=>"ec2-123.456.789.123.compute-1.amazonaws.com",
80
+ # "prod_br_app1"=>"ec2-123.456.789.123.compute-1.amazonaws.com",
81
+ # "prod_br_app2"=>"ec2-123.456.789.123.compute-1.amazonaws.com",
82
+ # "prod_br_app3"=>"ec2-123.456.789.123.compute-1.amazonaws.com",
83
+ # "prod_br_db0"=>"ec2-123.456.789.123.compute-1.amazonaws.com",
84
+ # "prod_br_db1"=>"ec2-123.456.789.123.compute-1.amazonaws.com"}
85
+ def hosts
86
+ build_server_infos
87
+ h = {}
88
+ counters = Hash.new(0)
89
+ servers.each do |host, v|
90
+ node = v["dna"]
91
+ instance_role = node["instance_role"]
92
+ env_name = @cloud_info.env_name
93
+
94
+ case instance_role
95
+ when "app_master"
96
+ h["#{env_name}_app0"] = node["master_app_server"]["public_ip"]
97
+ when "solo"
98
+ h["#{env_name}_app0"] = host
99
+ when "app"
100
+ h["#{env_name}_app#{counters[:app] += 1}"] = host
101
+ when "util"
102
+ if node["name"] =~ /util/
103
+ h["#{env_name}_util#{counters[:util]}"] = host
104
+ counters[:util] += 1
105
+ elsif
106
+ h["#{env_name}_memcached#{counters[:memcached]}"] = host
107
+ counters[:memcached] += 1
108
+ end
109
+ when "db_master"
110
+ h["#{env_name}_db0"] = host
111
+ when "db_slave"
112
+ h["#{env_name}_db#{counters[:db] += 1}"] = host
113
+ end
114
+ end
115
+ h
116
+ end
117
+
118
+ module Aws
119
+ def aws_instances
120
+ @@aws_instances ||= @ec2.describe_instances
121
+ end
122
+
123
+ def aws_groups
124
+ @@aws_groups ||= aws_instances.collect{|x| x[:aws_groups]}.flatten.uniq
125
+ end
126
+
127
+ def aws_group_for_instance_id(instance_id)
128
+ instance = aws_instances.find{|x| x[:aws_instance_id] == instance_id}
129
+ aws_group = instance[:aws_groups].first
130
+ end
131
+ end
132
+ include Aws
133
+
134
+ def self.ey_recipes
135
+ @@ey_recipes ||= `ey-recipes`
136
+ end
137
+ def ey_recipes
138
+ self.class.ey_recipes
139
+ end
140
+
141
+ def self.ey_environments
142
+ out = ey_recipes
143
+ environments = out.split("\n").grep(/env/).collect {|x| x =~ /env\: (\w+) / ; $1 }
144
+ end
145
+ def ey_environments
146
+ self.class.ey_environments
147
+ end
148
+
149
+ def ey_instances(env_name = nil)
150
+ instance_ids = []
151
+ out = ey_recipes
152
+ lines = out.split("\n")
153
+ line_with_instances = false
154
+ lines.each do |line|
155
+ if line_with_instances
156
+ md = line.match(/\[(.*)\]/)
157
+ list = md[1]
158
+ instance_ids = list.split(",").collect{|x| x.gsub('"','').strip}
159
+ break
160
+ end
161
+ if line =~ Regexp.new(env_name)
162
+ line_with_instances = true # next line will have the instances info on it
163
+ end
164
+ end
165
+ instance_ids
166
+ end
167
+
168
+ end
169
+ end
170
+
data/lib/cloud_info.rb ADDED
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+ require 'pp'
4
+ require File.join(%W/#{File.dirname(__FILE__)} cloud_info instances/)
5
+
6
+ class CloudInfo
7
+ attr_reader :env_name
8
+ def initialize(env_name, options = {})
9
+ @env_name = env_name
10
+ @options = options
11
+ @cache_path = options[:cache_path] || 'config/cloud_info.yml'
12
+ end
13
+
14
+ # if a cache exist it uses it instead of finding the servers
15
+ def hosts(use_cache = true)
16
+ # check yaml file first
17
+ puts "tung : #{@cache_path.inspect}"
18
+ if use_cache and File.exist?(@cache_path)
19
+ @hosts = (CloudInfo.read_yaml(@cache_path) || {})[env_name]
20
+ end
21
+
22
+ unless @hosts
23
+ @instances = Instances.new(self, @options)
24
+ @hosts = @instances.hosts
25
+
26
+ if File.exist?(@cache_path)
27
+ all_hosts = (CloudInfo.read_yaml(@cache_path) || {})
28
+ else
29
+ all_hosts = {}
30
+ end
31
+ all_hosts[env_name] = @hosts
32
+ CloudInfo.write_yaml(@cache_path, all_hosts)
33
+ end
34
+ pp @hosts
35
+ @hosts
36
+ end
37
+
38
+ def apps
39
+ apps = hosts.select{|k,v| k =~ Regexp.new("#{@env_name}_app")}.sort {|a,b| a[0] <=> b[0] }
40
+ end
41
+ def app_master
42
+ apps[0][1]
43
+ end
44
+ def utils
45
+ utils = hosts.select{|k,v| k =~ Regexp.new("#{@env_name}_util")}.sort {|a,b| a[0] <=> b[0] }
46
+ end
47
+
48
+ def self.all_hosts(options = {})
49
+ all_hosts = {}
50
+ environments = Instances.ey_environments
51
+ environments.each do |env|
52
+ info = CloudInfo.new(env, options)
53
+ hosts = info.hosts
54
+ pp env
55
+ pp hosts
56
+ all_hosts.merge!(hosts)
57
+ end
58
+ all_hosts
59
+ end
60
+
61
+ def self.write_yaml(path, hosts)
62
+ File.open(path, 'w') do |out|
63
+ out.write(hosts.to_yaml)
64
+ end
65
+ end
66
+ def self.read_yaml(path)
67
+ YAML.load(IO.read(path))
68
+ end
69
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/spec_helper")
2
+
3
+ describe CloudInfo::Instances do
4
+ describe "with-cache" do
5
+ before(:each) do
6
+ end
7
+
8
+ it "standard usage" do
9
+ @info = CloudInfo.new("prod_br", :private_key => "~/.ssh/id_rsa-flex-br")
10
+ @info.hosts.class.should == Hash
11
+ # pp @info.hosts
12
+ end
13
+
14
+ # it "standard usage" do
15
+ # @info = CloudInfo.new("beta", :private_key => "~/.ssh/id_rsa-flex-br")
16
+ # @info.hosts.class.should == Hash
17
+ # # pp @info.hosts
18
+ # end
19
+ end
20
+
21
+ # describe "no-cache" do
22
+ # before(:each) do
23
+ # File.delete("config/cloud_info.yml") if File.exist?("config/cloud_info.yml")
24
+ # end
25
+ #
26
+ # it "standard usage" do
27
+ # @info = CloudInfo.new("prod_br", :private_key => "~/.ssh/id_rsa-flex-br")
28
+ # @info.hosts.class.should == Hash
29
+ # # pp @info.hosts
30
+ # end
31
+ # #
32
+ # # it "tung" do
33
+ # # pp CloudInfo::Instances.new(@info).aws_instances.first
34
+ # # end
35
+ #
36
+ # # it "ey_environments" do
37
+ # # pp CloudInfo::Instances.ey_environments
38
+ # # end
39
+ # #
40
+ # # it "all_hosts" do
41
+ # # all_hosts = CloudInfo.all_hosts(:private_key => "~/.ssh/id_rsa-flex-br")
42
+ # # pp all_hosts
43
+ # # end
44
+ #
45
+ # it "write and read yaml" do
46
+ # hosts = {"whatever" => "test"}
47
+ # path = File.join(File.dirname(__FILE__),"fixtures","cloud_info.yml")
48
+ # CloudInfo.write_yaml(path, hosts)
49
+ # yaml = CloudInfo.read_yaml(path)
50
+ # yaml["whatever"].should == "test"
51
+ # end
52
+ # end
53
+
54
+ end
@@ -0,0 +1,2 @@
1
+ ---
2
+ whatever: test
@@ -0,0 +1,125 @@
1
+ {
2
+ "db_slaves": [
3
+ "db-slave0.compute-1.internal"
4
+ ],
5
+ "aws_secret_key": "verysecretkey",
6
+ "admin_ssh_key": "ssh-rsa WHATEVER\/Pvw== ey-cloud-production\n",
7
+ "backup_interval": 24,
8
+ "user_ssh_key": [
9
+ "ssh-rsa FOO br"
10
+ ],
11
+ "utility_instances": [
12
+ {
13
+ "name": "util0",
14
+ "hostname": "util0.compute-1.internal"
15
+ },
16
+ {
17
+ "name": "util1",
18
+ "hostname": "util1.compute-1.internal"
19
+ },
20
+ {
21
+ "name": "memcached0",
22
+ "hostname": "memcached0.compute-1.internal"
23
+ }
24
+ ],
25
+ "mailserver": "smtp.engineyard.com",
26
+ "instance_role": "app_master",
27
+ "crons": [
28
+
29
+ ],
30
+ "removed_applications": [
31
+
32
+ ],
33
+ "backup_window": 0,
34
+ "members": [
35
+ "app0.compute-1.internal",
36
+ "app1.compute-1.internal"
37
+ ],
38
+ "applications": {
39
+ "bleacherreport": {
40
+ "auth": {
41
+ "active": false
42
+ },
43
+ "https_bind_port": 443,
44
+ "migration_command": "rake db:migrate",
45
+ "type": "rails",
46
+ "repository_name": "git@github.com:tongueroo\/cloud_info.git",
47
+ "http_bind_port": 80,
48
+ "run_deploy": false,
49
+ "revision": "",
50
+ "branch": "HEAD",
51
+ "run_migrations": false,
52
+ "deploy_action": "deploy",
53
+ "deploy_key": "-----BEGIN RSA PRIVATE KEY-----\nBAR==\n-----END RSA PRIVATE KEY-----\n",
54
+ "services": [
55
+ {
56
+ "resource": "mongrel",
57
+ "mongrel_base_port": 5000,
58
+ "mongrel_mem_limit": 150,
59
+ "mongrel_instance_count": 3
60
+ },
61
+ {
62
+ "resource": "memcached",
63
+ "base_port": 11211,
64
+ "mem_limit": 128
65
+ }
66
+ ],
67
+ "recipes": [
68
+ "memcached",
69
+ "monit",
70
+ "nginx",
71
+ "nginx-passenger"
72
+ ],
73
+ "vhosts": [
74
+ {
75
+ "name": "cloud-info.local",
76
+ "role": "env-name"
77
+ }
78
+ ]
79
+ }
80
+ },
81
+ "alert_email": "tongueroo@gmail.com",
82
+ "gems_to_install": [
83
+ {
84
+ "name": "aws-s3",
85
+ "version": "0.6.2"
86
+ },
87
+ {
88
+ "name": "httparty",
89
+ "version": "0.5.0"
90
+ }
91
+ ],
92
+ "users": [
93
+ {
94
+ "gid": "1000",
95
+ "username": "deploy",
96
+ "uid": "1000",
97
+ "comment": "",
98
+ "password": "foobar"
99
+ }
100
+ ],
101
+ "reporting_url": "https:\/\/cloud.engineyard.com\/reporting\/f9b54f62d474ff7b3193a46accd14014",
102
+ "aws_secret_id": "verysecretkey",
103
+ "master_app_server": {
104
+ "private_dns_name": "app0.compute-1.internal",
105
+ "public_ip": "123.457.789.123"
106
+ },
107
+ "environment": {
108
+ "name": "env-name",
109
+ "stack": "nginx_passenger",
110
+ "framework_env": "staging"
111
+ },
112
+ "packages_to_install": [
113
+ {
114
+ "name": "media-gfx\/imagemagick"
115
+ },
116
+ {
117
+ "name": "net-misc\/telnet-bsd"
118
+ }
119
+ ],
120
+ "db_host": "db0.compute-1.amazonaws.com",
121
+ "haproxy": {
122
+ "username": "deploy",
123
+ "password": "foobar"
124
+ }
125
+ }
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --backtrace
@@ -0,0 +1,20 @@
1
+ $testing = true
2
+ SPEC = File.dirname(__FILE__)
3
+ $:.unshift File.expand_path("#{SPEC}/../lib")
4
+
5
+ require 'cloud_info'
6
+ require 'pp'
7
+ require 'rubygems'
8
+ require 'mocha'
9
+
10
+ Spec::Runner.configure do |config|
11
+ # config.mock_with :mocha
12
+ end
13
+
14
+ # For use with rspec textmate bundle
15
+ def debug(object)
16
+ puts "<pre>"
17
+ puts object.pretty_inspect.gsub('<', '&lt;').gsub('>', '&gt;')
18
+ puts "</pre>"
19
+ end
20
+
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloud_info
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Tung Nguyen
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-04 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: ey-flex
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 5
30
+ - 1
31
+ version: 0.5.1
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: right_aws
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 10
44
+ - 0
45
+ version: 1.10.0
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: json
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 0
58
+ - 0
59
+ version: 1.0.0
60
+ type: :runtime
61
+ version_requirements: *id003
62
+ description:
63
+ email: tongueroo@gmail.com
64
+ executables: []
65
+
66
+ extensions: []
67
+
68
+ extra_rdoc_files:
69
+ - README.markdown
70
+ files:
71
+ - bin/cloud_info
72
+ - config/cloud_info.yml
73
+ - gemspec.rb
74
+ - lib/cloud_info/instances.rb
75
+ - lib/cloud_info.rb
76
+ - MIT-LICENSE
77
+ - Rakefile
78
+ - README.markdown
79
+ - spec/cloud_info_spec.rb
80
+ - spec/fixtures/cloud_info.yml
81
+ - spec/fixtures/dna.json
82
+ - spec/spec.opts
83
+ - spec/spec_helper.rb
84
+ - TODO
85
+ has_rdoc: true
86
+ homepage: http://github.com/tongueroo/cloud_info
87
+ licenses: []
88
+
89
+ post_install_message:
90
+ rdoc_options: []
91
+
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ requirements: []
109
+
110
+ rubyforge_project:
111
+ rubygems_version: 1.3.6
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: cloud_info summary
115
+ test_files: []
116
+