engineyard-metadata 0.0.4 → 0.0.5
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/README.rdoc +16 -7
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/engineyard-metadata.gemspec +10 -3
- data/lib/engineyard-metadata/amazon_ec2_api.rb +1 -0
- data/lib/engineyard-metadata/chef_dna.rb +33 -25
- data/lib/engineyard-metadata/engine_yard_cloud_api.rb +151 -0
- data/lib/engineyard-metadata/insider.rb +35 -0
- data/lib/engineyard-metadata/metadata.rb +17 -24
- data/lib/engineyard-metadata/outsider.rb +35 -0
- data/spec/metadata_spec.rb +138 -54
- data/spec/spec_helper.rb +39 -26
- data/spec/support/dna.json +13 -13
- data/spec/support/engine_yard_cloud_api_response.json +28 -0
- metadata +29 -10
data/README.rdoc
CHANGED
@@ -1,23 +1,34 @@
|
|
1
1
|
= engineyard-metadata
|
2
2
|
|
3
|
-
|
3
|
+
Presents a simple, unchanging interface to get metadata about your EngineYard AppCloud instances running on Amazon EC2.
|
4
4
|
|
5
5
|
== Purpose
|
6
6
|
|
7
|
-
To define an unchanging interface to useful metadata (passwords, IP addresses, etc.) that is otherwise buried deep inside EngineYard's chef config files and
|
7
|
+
To define an unchanging interface to useful metadata (passwords, IP addresses, etc.) that is otherwise buried deep inside EngineYard's chef config files and various API calls.
|
8
8
|
|
9
9
|
== Examples
|
10
10
|
|
11
11
|
* Get a dynamically updated list of all running app servers so that you can pool memcached over all of them. (<tt>EY::Metadata.app_servers</tt>)
|
12
12
|
* Get the current database password so that you can write a script that connects to it. (<tt>EY::Metadata.database_password</tt>)
|
13
13
|
|
14
|
+
Get the full method list in {the engineyard-metadata rdoc}[http://rdoc.info/github/seamusabshere/engineyard-metadata].
|
15
|
+
|
14
16
|
== Use
|
15
17
|
|
16
|
-
|
18
|
+
=== From the inside
|
19
|
+
|
20
|
+
When you're executing the gem from your instances, you don't have to configure anything. Just require the gem.
|
21
|
+
|
22
|
+
=== From the outside
|
23
|
+
|
24
|
+
You need to provide...
|
25
|
+
|
26
|
+
* <tt>ENV['EY_CLOUD_TOKEN']</tt> or have <tt>~/.eyrc</tt>
|
27
|
+
* <tt>ENV['REPOSITORY_URI']</tt> or execute the gem from the local copy of your application's repo.
|
17
28
|
|
18
|
-
|
29
|
+
=== Where the methods are defined
|
19
30
|
|
20
|
-
|
31
|
+
Metadata getters are defined directly on <tt>EY::Metadata</tt> (which in turn delegates out to various adapters). Even if EngineYard changes the structure of the config files or Amazon EC2's API changes, these methods will stay the same.
|
21
32
|
|
22
33
|
[...]
|
23
34
|
>> require 'rubygems'
|
@@ -26,8 +37,6 @@ This only runs on EngineYard AppCloud instances (running on Amazon EC2).
|
|
26
37
|
[...]
|
27
38
|
>> EY::Metadata.database_host
|
28
39
|
=> "external_db_master.compute-1.amazonaws.com"
|
29
|
-
>> EY::Metadata.database_password
|
30
|
-
=> "foobarfoo"
|
31
40
|
>> EY::Metadata.app_servers
|
32
41
|
=> [ 'app_1.compute-1.amazonaws.com' , 'app_master.compute-1.amazonaws.com' ]
|
33
42
|
>> EY::Metadata.db_servers
|
data/Rakefile
CHANGED
@@ -11,6 +11,7 @@ begin
|
|
11
11
|
gem.homepage = "http://github.com/seamusabshere/engineyard-metadata"
|
12
12
|
gem.authors = ["Seamus Abshere"]
|
13
13
|
gem.add_dependency 'activesupport', '>=2.3.4'
|
14
|
+
gem.add_dependency 'nap', '>=0.4'
|
14
15
|
gem.add_development_dependency "fakeweb"
|
15
16
|
gem.add_development_dependency "fakefs"
|
16
17
|
gem.add_development_dependency "rspec", "~>1"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.5
|
data/engineyard-metadata.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{engineyard-metadata}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Seamus Abshere"]
|
12
|
-
s.date = %q{2010-10-
|
12
|
+
s.date = %q{2010-10-14}
|
13
13
|
s.description = %q{Pulls metadata from EC2 and EngineYard so that your EngineYard AppCloud (Amazon EC2) instances know about each other.}
|
14
14
|
s.email = %q{seamus@abshere.net}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,10 +27,14 @@ Gem::Specification.new do |s|
|
|
27
27
|
"lib/engineyard-metadata.rb",
|
28
28
|
"lib/engineyard-metadata/amazon_ec2_api.rb",
|
29
29
|
"lib/engineyard-metadata/chef_dna.rb",
|
30
|
+
"lib/engineyard-metadata/engine_yard_cloud_api.rb",
|
31
|
+
"lib/engineyard-metadata/insider.rb",
|
30
32
|
"lib/engineyard-metadata/metadata.rb",
|
33
|
+
"lib/engineyard-metadata/outsider.rb",
|
31
34
|
"spec/metadata_spec.rb",
|
32
35
|
"spec/spec_helper.rb",
|
33
|
-
"spec/support/dna.json"
|
36
|
+
"spec/support/dna.json",
|
37
|
+
"spec/support/engine_yard_cloud_api_response.json"
|
34
38
|
]
|
35
39
|
s.homepage = %q{http://github.com/seamusabshere/engineyard-metadata}
|
36
40
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -48,17 +52,20 @@ Gem::Specification.new do |s|
|
|
48
52
|
|
49
53
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
50
54
|
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.4"])
|
55
|
+
s.add_runtime_dependency(%q<nap>, [">= 0.4"])
|
51
56
|
s.add_development_dependency(%q<fakeweb>, [">= 0"])
|
52
57
|
s.add_development_dependency(%q<fakefs>, [">= 0"])
|
53
58
|
s.add_development_dependency(%q<rspec>, ["~> 1"])
|
54
59
|
else
|
55
60
|
s.add_dependency(%q<activesupport>, [">= 2.3.4"])
|
61
|
+
s.add_dependency(%q<nap>, [">= 0.4"])
|
56
62
|
s.add_dependency(%q<fakeweb>, [">= 0"])
|
57
63
|
s.add_dependency(%q<fakefs>, [">= 0"])
|
58
64
|
s.add_dependency(%q<rspec>, ["~> 1"])
|
59
65
|
end
|
60
66
|
else
|
61
67
|
s.add_dependency(%q<activesupport>, [">= 2.3.4"])
|
68
|
+
s.add_dependency(%q<nap>, [">= 0.4"])
|
62
69
|
s.add_dependency(%q<fakeweb>, [">= 0"])
|
63
70
|
s.add_dependency(%q<fakefs>, [">= 0"])
|
64
71
|
s.add_dependency(%q<rspec>, ["~> 1"])
|
@@ -8,89 +8,90 @@ end if ActiveSupport::VERSION::MAJOR == 3
|
|
8
8
|
|
9
9
|
module EY
|
10
10
|
module Metadata
|
11
|
+
# An adapter that reads from /etc/chef/dna.json, which is only available on cloud instances.
|
11
12
|
class ChefDna
|
12
13
|
PATH = '/etc/chef/dna.json'
|
13
|
-
|
14
|
-
MYSQLDUMP_BIN = '/usr/bin/mysqldump'
|
15
|
-
|
14
|
+
|
16
15
|
def data # :nodoc:
|
17
16
|
@data ||= ActiveSupport::JSON.decode File.read(PATH)
|
18
17
|
end
|
19
|
-
|
18
|
+
|
20
19
|
# The present instance's role
|
21
20
|
def present_instance_role
|
22
21
|
data['instance_role']
|
23
22
|
end
|
24
|
-
|
23
|
+
|
25
24
|
# The present instance's public hostname.
|
26
25
|
def present_public_hostname
|
27
26
|
data['engineyard']['environment']['instances'].detect { |i| i['id'] == EY::Metadata.present_instance_id }['public_hostname']
|
28
27
|
end
|
29
|
-
|
28
|
+
|
30
29
|
# Currently the same as the SSH password.
|
31
30
|
def database_password
|
32
31
|
data['users'][0]['password']
|
33
32
|
end
|
34
|
-
|
33
|
+
|
35
34
|
# Currently the same as the SSH username.
|
36
35
|
def database_username
|
37
36
|
data['users'][0]['username']
|
38
37
|
end
|
39
|
-
|
38
|
+
|
40
39
|
# For newly deployed applications, equal to the application name.
|
41
40
|
def database_name
|
42
41
|
data['engineyard']['environment']['apps'][0]['database_name']
|
43
42
|
end
|
44
|
-
|
43
|
+
|
45
44
|
# Public hostname where you should connect to the database.
|
46
45
|
#
|
47
46
|
# Currently the db master public hostname.
|
48
47
|
def database_host
|
49
|
-
|
48
|
+
db_master
|
50
49
|
end
|
51
|
-
|
50
|
+
|
52
51
|
# SSH username.
|
53
52
|
def ssh_username
|
54
53
|
data['engineyard']['environment']['ssh_username']
|
55
54
|
end
|
56
|
-
|
55
|
+
|
57
56
|
# SSH password.
|
58
57
|
def ssh_password
|
59
58
|
data['engineyard']['environment']['ssh_password']
|
60
59
|
end
|
61
|
-
|
60
|
+
|
62
61
|
# The public hostnames of all the app servers.
|
63
62
|
#
|
64
63
|
# If you're on a solo app, it counts the solo as an app server.
|
65
64
|
def app_servers
|
66
65
|
data['engineyard']['environment']['instances'].select { |i| %w{ app_master app solo }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
67
66
|
end
|
68
|
-
|
67
|
+
|
69
68
|
# The public hostnames of all the app slaves.
|
70
69
|
def app_slaves
|
71
70
|
data['engineyard']['environment']['instances'].select { |i| %w{ app }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
72
71
|
end
|
73
|
-
|
72
|
+
|
74
73
|
# The public hostnames of all the db servers.
|
75
74
|
#
|
76
75
|
# If you're on a solo app, it counts the solo as a db server.
|
77
76
|
def db_servers
|
78
77
|
data['engineyard']['environment']['instances'].select { |i| %w{ db_master db_slave solo }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
79
78
|
end
|
80
|
-
|
79
|
+
|
81
80
|
# The public hostnames of all the db slaves.
|
82
81
|
def db_slaves
|
83
82
|
data['engineyard']['environment']['instances'].select { |i| %w{ db_slave }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
84
83
|
end
|
85
|
-
|
84
|
+
|
86
85
|
# The public hostnames of all the utility servers.
|
87
86
|
#
|
88
87
|
# If you're on a solo app, it counts the solo as a utility.
|
89
88
|
def utilities
|
90
89
|
data['engineyard']['environment']['instances'].select { |i| %w{ util solo }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
91
90
|
end
|
92
|
-
|
91
|
+
|
93
92
|
# The public hostname of the app_master.
|
93
|
+
#
|
94
|
+
# If you're on a solo app, it counts the solo as the app_master.
|
94
95
|
def app_master
|
95
96
|
if x = data['engineyard']['environment']['instances'].detect { |i| i['role'] == 'app_master' }
|
96
97
|
x['public_hostname']
|
@@ -98,8 +99,10 @@ module EY
|
|
98
99
|
solo
|
99
100
|
end
|
100
101
|
end
|
101
|
-
|
102
|
-
# The public hostname of the db_master
|
102
|
+
|
103
|
+
# The public hostname of the db_master.
|
104
|
+
#
|
105
|
+
# If you're on a solo app, it counts the solo as the app_master.
|
103
106
|
def db_master
|
104
107
|
if x = data['engineyard']['environment']['instances'].detect { |i| i['role'] == 'db_master' }
|
105
108
|
x['public_hostname']
|
@@ -107,28 +110,33 @@ module EY
|
|
107
110
|
solo
|
108
111
|
end
|
109
112
|
end
|
110
|
-
|
113
|
+
|
111
114
|
# The public hostname of the solo.
|
112
115
|
def solo
|
113
116
|
if x = data['engineyard']['environment']['instances'].detect { |i| i['role'] == 'solo' }
|
114
117
|
x['public_hostname']
|
115
118
|
end
|
116
119
|
end
|
117
|
-
|
120
|
+
|
118
121
|
# The shell command for mysql, including username, password, hostname and database
|
119
122
|
def mysql_command
|
120
|
-
"
|
123
|
+
"/usr/bin/mysql -h #{database_host} -u #{database_username} -p#{database_password} #{database_name}"
|
121
124
|
end
|
122
125
|
|
123
126
|
# The shell command for mysql, including username, password, hostname and database
|
124
127
|
def mysqldump_command
|
125
|
-
"
|
128
|
+
"/usr/bin/mysqldump -h #{database_host} -u #{database_username} -p#{database_password} #{database_name}"
|
126
129
|
end
|
127
|
-
|
130
|
+
|
128
131
|
# The name of the EngineYard AppCloud environment.
|
129
132
|
def environment_name
|
130
133
|
data['environment']['name']
|
131
134
|
end
|
135
|
+
|
136
|
+
# The stack in use, like nginx_passenger.
|
137
|
+
def stack_name
|
138
|
+
data['engineyard']['environment']['stack_name']
|
139
|
+
end
|
132
140
|
end
|
133
141
|
end
|
134
142
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'etc'
|
2
|
+
require 'yaml'
|
3
|
+
require 'rest' # from nap gem
|
4
|
+
require 'active_support'
|
5
|
+
require 'active_support/version'
|
6
|
+
%w{
|
7
|
+
active_support/json
|
8
|
+
}.each do |active_support_3_requirement|
|
9
|
+
require active_support_3_requirement
|
10
|
+
end if ActiveSupport::VERSION::MAJOR == 3
|
11
|
+
|
12
|
+
module EY
|
13
|
+
module Metadata
|
14
|
+
# An adapter that reads from the public EngineYard Cloud API (https://cloud.engineyard.com). Available from anywhere.
|
15
|
+
#
|
16
|
+
# See README for what environment variables and/or files you need to have in place for this to work.
|
17
|
+
class EngineYardCloudApi
|
18
|
+
URL = 'https://cloud.engineyard.com/api/v2/environments'
|
19
|
+
|
20
|
+
# Currently the same as the SSH username.
|
21
|
+
def database_username
|
22
|
+
data['ssh_username']
|
23
|
+
end
|
24
|
+
|
25
|
+
# The username for connecting by SSH.
|
26
|
+
def ssh_username
|
27
|
+
data['ssh_username']
|
28
|
+
end
|
29
|
+
|
30
|
+
# Currently the same as the app name, at least for recently-created environments.
|
31
|
+
#
|
32
|
+
# It used to be named after the environment.
|
33
|
+
def database_name
|
34
|
+
data['apps'][0]['name']
|
35
|
+
end
|
36
|
+
|
37
|
+
# The hostname of the database host.
|
38
|
+
def database_host
|
39
|
+
db_master
|
40
|
+
end
|
41
|
+
|
42
|
+
# The public hostname of the db_master.
|
43
|
+
#
|
44
|
+
# If you're on a solo app, it counts the solo as the app_master.
|
45
|
+
def db_master
|
46
|
+
if x = data['instances'].detect { |i| i['role'] == 'db_master' }
|
47
|
+
x['public_hostname']
|
48
|
+
else
|
49
|
+
solo
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# The public hostnames of all the app servers.
|
54
|
+
#
|
55
|
+
# If you're on a solo app, it counts the solo as an app server.
|
56
|
+
def app_servers
|
57
|
+
data['instances'].select { |i| %w{ app_master app solo }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
58
|
+
end
|
59
|
+
|
60
|
+
# The public hostnames of all the db servers.
|
61
|
+
#
|
62
|
+
# If you're on a solo app, it counts the solo as a db server.
|
63
|
+
def db_servers
|
64
|
+
data['instances'].select { |i| %w{ db_master db_slave solo }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
65
|
+
end
|
66
|
+
|
67
|
+
# The public hostnames of all the utility servers.
|
68
|
+
#
|
69
|
+
# If you're on a solo app, it counts the solo as a utility.
|
70
|
+
def utilities
|
71
|
+
data['instances'].select { |i| %w{ util solo }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
72
|
+
end
|
73
|
+
|
74
|
+
# The public hostnames of all the app slaves.
|
75
|
+
def app_slaves
|
76
|
+
data['instances'].select { |i| %w{ app }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
77
|
+
end
|
78
|
+
|
79
|
+
# The public hostnames of all the db slaves.
|
80
|
+
def db_slaves
|
81
|
+
data['instances'].select { |i| %w{ db_slave }.include? i['role'] }.map { |i| i['public_hostname'] }.sort
|
82
|
+
end
|
83
|
+
|
84
|
+
# The public hostname of the app_master.
|
85
|
+
#
|
86
|
+
# If you're on a solo app, it counts the solo as the app_master.
|
87
|
+
def app_master
|
88
|
+
if x = data['instances'].detect { |i| i['role'] == 'app_master' }
|
89
|
+
x['public_hostname']
|
90
|
+
else
|
91
|
+
solo
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# The public hostname of the solo.
|
96
|
+
def solo
|
97
|
+
if x = data['instances'].detect { |i| i['role'] == 'solo' }
|
98
|
+
x['public_hostname']
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# The name of the EngineYard AppCloud environment.
|
103
|
+
def environment_name
|
104
|
+
data['name']
|
105
|
+
end
|
106
|
+
|
107
|
+
# The stack in use, like nginx_passenger.
|
108
|
+
def stack_name
|
109
|
+
data['stack_name']
|
110
|
+
end
|
111
|
+
|
112
|
+
# The secret API token to access https://cloud.engineyard.com
|
113
|
+
def ey_cloud_token
|
114
|
+
@ey_cloud_token ||= if ENV['EY_CLOUD_TOKEN'].to_s.strip.length > 0
|
115
|
+
ENV['EY_CLOUD_TOKEN']
|
116
|
+
elsif File.exist? EY::Metadata.eyrc_path
|
117
|
+
YAML.load(File.read(EY::Metadata.eyrc_path))['api_token']
|
118
|
+
else
|
119
|
+
raise RuntimeError, "[engineyard-metadata gem] You need to download #{eyrc_path} or set ENV['EY_CLOUD_TOKEN']"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# The URL that EngineYard has on file for your application.
|
124
|
+
def repository_uri
|
125
|
+
@repository_uri ||= if ENV['REPOSITORY_URI'].to_s.strip.length > 0
|
126
|
+
ENV['REPOSITORY_URI']
|
127
|
+
elsif File.exist? EY::Metadata.git_config_path
|
128
|
+
`git config --get remote.origin.url`
|
129
|
+
else
|
130
|
+
raise RuntimeError, "[engineyard-metadata gem] You need to be inside a app's git repo or set ENV['REPOSITORY_URI']"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def data
|
135
|
+
return @data if @data.is_a? Hash
|
136
|
+
raw_json = REST.get(URL, 'X-EY-Cloud-Token' => ey_cloud_token).body
|
137
|
+
raw_data = ActiveSupport::JSON.decode raw_json
|
138
|
+
catch :found_environment_by_repository_uri do
|
139
|
+
raw_data['environments'].each do |environment_hsh|
|
140
|
+
if environment_hsh['apps'].any? { |app_hsh| app_hsh['repository_uri'] == repository_uri }
|
141
|
+
@data = environment_hsh
|
142
|
+
throw :found_environment_by_repository_uri
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
raise RuntimeError, "[engineyard-metadata gem] Couldn't find an EngineYard environment with the repository uri #{repository_uri}" unless @data.is_a? Hash
|
147
|
+
@data
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module EY
|
2
|
+
module Metadata
|
3
|
+
# This gets pulled in when you're running directly on a cloud instance.
|
4
|
+
module Insider
|
5
|
+
DELEGATED_TO_AMAZON_EC2_API = %w{
|
6
|
+
present_instance_id
|
7
|
+
present_security_group
|
8
|
+
}
|
9
|
+
|
10
|
+
DELEGATED_TO_CHEF_DNA = KEYS - DELEGATED_TO_AMAZON_EC2_API
|
11
|
+
|
12
|
+
DELEGATED_TO_AMAZON_EC2_API.each do |name|
|
13
|
+
define_method name do
|
14
|
+
amazon_ec2_api.send name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
DELEGATED_TO_CHEF_DNA.each do |name|
|
19
|
+
define_method name do
|
20
|
+
chef_dna.send name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# An adapter that reads from the EngineYard AppCloud /etc/chef/dna.json file.
|
25
|
+
def chef_dna
|
26
|
+
@chef_dna ||= ChefDna.new
|
27
|
+
end
|
28
|
+
|
29
|
+
# An adapter that reads from Amazon's EC2 API.
|
30
|
+
def amazon_ec2_api
|
31
|
+
@amazon_ec2_api ||= AmazonEc2Api.new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module EY
|
2
|
+
# All methods are defined on this module. For example, you're supposed to say
|
3
|
+
#
|
4
|
+
# EY::Metadata.database_username
|
5
|
+
#
|
6
|
+
# instead of trying to call it from a particular adapter.
|
2
7
|
module Metadata
|
3
|
-
|
8
|
+
KEYS = %w{
|
4
9
|
present_instance_id
|
5
10
|
present_security_group
|
6
|
-
}
|
7
|
-
|
8
|
-
DELEGATED_TO_CHEF_DNA = %w{
|
9
11
|
present_instance_role
|
10
12
|
present_public_hostname
|
11
13
|
database_password
|
@@ -25,33 +27,24 @@ module EY
|
|
25
27
|
db_slaves
|
26
28
|
solo
|
27
29
|
environment_name
|
30
|
+
stack_name
|
28
31
|
}
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
amazon_ec2_api.send name
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
DELEGATED_TO_CHEF_DNA.each do |name|
|
37
|
-
EY::Metadata.send :define_method, name do
|
38
|
-
chef_dna.send name
|
39
|
-
end
|
33
|
+
# This gets raised when you can't get a particular piece of metadata from the execution environment you're in.
|
34
|
+
class CannotGetFromHere < RuntimeError
|
40
35
|
end
|
41
|
-
|
42
|
-
extend self
|
43
36
|
|
37
|
+
autoload :Insider, 'engineyard-metadata/insider'
|
38
|
+
autoload :Outsider, 'engineyard-metadata/outsider'
|
44
39
|
autoload :ChefDna, 'engineyard-metadata/chef_dna'
|
45
40
|
autoload :AmazonEc2Api, 'engineyard-metadata/amazon_ec2_api'
|
41
|
+
autoload :EngineYardCloudApi, 'engineyard-metadata/engine_yard_cloud_api'
|
46
42
|
|
47
|
-
#
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# An adapter that reads from Amazon's EC2 API.
|
53
|
-
def amazon_ec2_api
|
54
|
-
@amazon_ec2_api ||= EY::Metadata::AmazonEc2Api.new
|
43
|
+
# this is a pretty sloppy way of detecting whether we're on ec2
|
44
|
+
if File.exist? '/etc/chef/dna.json'
|
45
|
+
extend Insider
|
46
|
+
else
|
47
|
+
extend Outsider
|
55
48
|
end
|
56
49
|
end
|
57
50
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module EY
|
2
|
+
module Metadata
|
3
|
+
# This gets pulled in when you're running from your developer machine (i.e., not on a cloud instance).
|
4
|
+
module Outsider
|
5
|
+
IMPOSSIBLE = KEYS.grep(/present/) + KEYS.grep(/password/) + KEYS.grep(/mysql/)
|
6
|
+
|
7
|
+
POSSIBLE = KEYS - IMPOSSIBLE
|
8
|
+
|
9
|
+
IMPOSSIBLE.each do |name|
|
10
|
+
define_method name do
|
11
|
+
raise CannotGetFromHere
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
POSSIBLE.each do |name|
|
16
|
+
define_method name do
|
17
|
+
engine_yard_cloud_api.send name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def eyrc_path
|
22
|
+
File.join File.expand_path("~#{Etc.getpwuid.name}"), '.eyrc'
|
23
|
+
end
|
24
|
+
|
25
|
+
def git_config_path
|
26
|
+
File.join Dir.pwd, '.git', 'config'
|
27
|
+
end
|
28
|
+
|
29
|
+
# An adapter that reads from the public EngineYard Cloud API (https://cloud.engineyard.com)
|
30
|
+
def engine_yard_cloud_api
|
31
|
+
@engine_yard_cloud_api ||= EngineYardCloudApi.new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/metadata_spec.rb
CHANGED
@@ -1,80 +1,42 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
it 'has a FakeFS dna.json' do
|
5
|
-
File.exist?('/etc/chef/dna.json').should == true
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
describe EY::Metadata do
|
10
|
-
it 'gets the present instance ID' do
|
11
|
-
EY::Metadata.present_instance_id.should == PRESENT_INSTANCE_ID
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'gets the present instance role (as a string)' do
|
15
|
-
EY::Metadata.present_instance_role.should == 'app_master'
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'gets the present public hostname' do
|
19
|
-
EY::Metadata.present_public_hostname.should == PRESENT_PUBLIC_HOSTNAME
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'gets the present security group' do
|
23
|
-
EY::Metadata.present_security_group.should == PRESENT_SECURITY_GROUP
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'gets the database password' do
|
27
|
-
EY::Metadata.database_password.should == 'USERS-0-PASSWORD'
|
28
|
-
end
|
29
|
-
|
3
|
+
shared_examples_for "all execution environments" do
|
30
4
|
it 'gets the database username' do
|
31
|
-
EY::Metadata.database_username.should == '
|
5
|
+
EY::Metadata.database_username.should == 'FAKE_SSH_USERNAME'
|
32
6
|
end
|
33
7
|
|
34
8
|
it 'gets the database name' do
|
35
|
-
EY::Metadata.database_name.should == '
|
9
|
+
EY::Metadata.database_name.should == 'FAKE_APP_NAME'
|
36
10
|
end
|
37
11
|
|
38
12
|
it 'gets the database host' do
|
39
|
-
EY::Metadata.database_host.should == '
|
13
|
+
EY::Metadata.database_host.should == 'FAKE_DB_MASTER_PUBLIC_HOSTNAME'
|
40
14
|
end
|
41
|
-
|
15
|
+
|
42
16
|
it 'gets the ssh username' do
|
43
|
-
EY::Metadata.ssh_username.should == '
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'gets the ssh password' do
|
47
|
-
EY::Metadata.ssh_password.should == 'SSH-PASSWORD'
|
17
|
+
EY::Metadata.ssh_username.should == 'FAKE_SSH_USERNAME'
|
48
18
|
end
|
49
19
|
|
50
20
|
it 'gets the app server hostnames' do
|
51
21
|
EY::Metadata.app_servers.should == [ 'app_1.compute-1.amazonaws.com' , 'app_master.compute-1.amazonaws.com' ]
|
52
22
|
end
|
53
|
-
|
23
|
+
|
54
24
|
it 'gets the db server hostnames' do
|
55
|
-
EY::Metadata.db_servers.should == [ '
|
25
|
+
EY::Metadata.db_servers.should == [ 'FAKE_DB_MASTER_PUBLIC_HOSTNAME', 'db_slave_1.compute-1.amazonaws.com' ]
|
56
26
|
end
|
57
|
-
|
27
|
+
|
58
28
|
it 'gets the utilities hostnames' do
|
59
|
-
EY::Metadata.utilities.should == [ '
|
29
|
+
EY::Metadata.utilities.should == [ 'FAKE_UTIL_1_PUBLIC_HOSTNAME' ]
|
60
30
|
end
|
61
31
|
|
62
32
|
it 'gets the app master hostname' do
|
63
33
|
EY::Metadata.app_master.should == 'app_master.compute-1.amazonaws.com'
|
64
34
|
end
|
65
|
-
|
35
|
+
|
66
36
|
it 'gets the db master hostname' do
|
67
|
-
EY::Metadata.db_master.should == '
|
37
|
+
EY::Metadata.db_master.should == 'FAKE_DB_MASTER_PUBLIC_HOSTNAME'
|
68
38
|
end
|
69
|
-
|
70
|
-
it 'gets the mysql command' do
|
71
|
-
EY::Metadata.mysql_command.should == '/usr/bin/mysql -h external_db_master.compute-1.amazonaws.com -u USERS-0-USERNAME -pUSERS-0-PASSWORD APPS-0-DATABASE_NAME'
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'gets the mysqldump command' do
|
75
|
-
EY::Metadata.mysqldump_command.should == '/usr/bin/mysqldump -h external_db_master.compute-1.amazonaws.com -u USERS-0-USERNAME -pUSERS-0-PASSWORD APPS-0-DATABASE_NAME'
|
76
|
-
end
|
77
|
-
|
39
|
+
|
78
40
|
it 'gets the db slave hostnames' do
|
79
41
|
EY::Metadata.db_slaves.should == [ 'db_slave_1.compute-1.amazonaws.com' ]
|
80
42
|
end
|
@@ -82,12 +44,134 @@ describe EY::Metadata do
|
|
82
44
|
it 'gets the app slave hostnames' do
|
83
45
|
EY::Metadata.app_slaves.should == [ 'app_1.compute-1.amazonaws.com' ]
|
84
46
|
end
|
85
|
-
|
47
|
+
|
86
48
|
it 'gets the solo hostname' do
|
87
49
|
EY::Metadata.solo.should == nil
|
88
50
|
end
|
89
|
-
|
51
|
+
|
90
52
|
it 'gets the environment name' do
|
91
|
-
EY::Metadata.environment_name.should == '
|
53
|
+
EY::Metadata.environment_name.should == 'FAKE_ENVIRONMENT_NAME'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'gets the stack name' do
|
57
|
+
EY::Metadata.stack_name.should == 'FAKE_STACK_NAME'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'EY::Metadata' do
|
62
|
+
describe "being executed from a developer/administrator's local machine" do
|
63
|
+
before(:all) do
|
64
|
+
pretend_we_are_on_a_developer_machine
|
65
|
+
# forcibly reload metadata.rb, so that it can extend itself based on its execution environment
|
66
|
+
load File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'engineyard-metadata', 'metadata.rb'))
|
67
|
+
end
|
68
|
+
|
69
|
+
after(:all) do
|
70
|
+
stop_pretending
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'cannot get the present instance ID' do
|
74
|
+
lambda {
|
75
|
+
EY::Metadata.present_instance_id
|
76
|
+
}.should raise_error(EY::Metadata::CannotGetFromHere)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'cannot get the present instance role (as a string)' do
|
80
|
+
lambda {
|
81
|
+
EY::Metadata.present_instance_role
|
82
|
+
}.should raise_error(EY::Metadata::CannotGetFromHere)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'cannot get the present public hostname' do
|
86
|
+
lambda {
|
87
|
+
EY::Metadata.present_public_hostname
|
88
|
+
}.should raise_error(EY::Metadata::CannotGetFromHere)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'cannot get the present security group' do
|
92
|
+
lambda {
|
93
|
+
EY::Metadata.present_security_group
|
94
|
+
}.should raise_error(EY::Metadata::CannotGetFromHere)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'cannot get the database password' do
|
98
|
+
lambda {
|
99
|
+
EY::Metadata.database_password
|
100
|
+
}.should raise_error(EY::Metadata::CannotGetFromHere)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'cannot get the ssh password' do
|
104
|
+
lambda {
|
105
|
+
EY::Metadata.ssh_password
|
106
|
+
}.should raise_error(EY::Metadata::CannotGetFromHere)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'cannot get the mysql command' do
|
110
|
+
lambda {
|
111
|
+
EY::Metadata.mysql_command
|
112
|
+
}.should raise_error(EY::Metadata::CannotGetFromHere)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'cannot get the mysqldump command' do
|
116
|
+
lambda {
|
117
|
+
EY::Metadata.mysqldump_command
|
118
|
+
}.should raise_error(EY::Metadata::CannotGetFromHere)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'gets the raw EngineYard Cloud API data' do
|
122
|
+
EY::Metadata.engine_yard_cloud_api.data.should be_a(Hash)
|
123
|
+
end
|
124
|
+
|
125
|
+
it_should_behave_like "all execution environments"
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "being executed on an EngineYard AppCloud (i.e. Amazon EC2) instance" do
|
129
|
+
before(:all) do
|
130
|
+
pretend_we_are_on_an_engineyard_appcloud_ec2_instance
|
131
|
+
# forcibly reload metadata.rb, so that it can extend itself based on its execution environment
|
132
|
+
load File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'engineyard-metadata', 'metadata.rb'))
|
133
|
+
end
|
134
|
+
|
135
|
+
after(:all) do
|
136
|
+
stop_pretending
|
137
|
+
end
|
138
|
+
|
139
|
+
it_should_behave_like "all execution environments"
|
140
|
+
|
141
|
+
it 'has a FakeFS dna.json' do
|
142
|
+
File.exist?('/etc/chef/dna.json').should == true
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'gets the present instance ID' do
|
146
|
+
EY::Metadata.present_instance_id.should == PRESENT_INSTANCE_ID
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'gets the present instance role (as a string)' do
|
150
|
+
EY::Metadata.present_instance_role.should == 'app_master'
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'gets the present public hostname' do
|
154
|
+
EY::Metadata.present_public_hostname.should == PRESENT_PUBLIC_HOSTNAME
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'gets the present security group' do
|
158
|
+
EY::Metadata.present_security_group.should == PRESENT_SECURITY_GROUP
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'gets the database password' do
|
162
|
+
EY::Metadata.database_password.should == 'USERS-0-PASSWORD'
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'gets the ssh password' do
|
166
|
+
EY::Metadata.ssh_password.should == 'SSH-PASSWORD'
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'gets the mysql command' do
|
170
|
+
EY::Metadata.mysql_command.should =~ %r{mysql -h FAKE_DB_MASTER_PUBLIC_HOSTNAME -u FAKE_SSH_USERNAME -pUSERS-0-PASSWORD FAKE_APP_NAME}
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'gets the mysqldump command' do
|
174
|
+
EY::Metadata.mysqldump_command.should =~ %r{mysqldump -h FAKE_DB_MASTER_PUBLIC_HOSTNAME -u FAKE_SSH_USERNAME -pUSERS-0-PASSWORD FAKE_APP_NAME}
|
175
|
+
end
|
92
176
|
end
|
93
177
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,38 +3,51 @@ require 'spec'
|
|
3
3
|
# require 'ruby-debug'
|
4
4
|
# assumes active-support 3
|
5
5
|
require 'active_support/json/encoding'
|
6
|
+
require 'fakeweb'
|
7
|
+
require 'fakefs/safe'
|
6
8
|
|
7
9
|
PRESENT_PUBLIC_HOSTNAME = 'app_master.compute-1.amazonaws.com'
|
8
10
|
PRESENT_SECURITY_GROUP = 'ey-data1_production-1-2-3'
|
9
11
|
PRESENT_INSTANCE_ID = 'i-deadbeef'
|
12
|
+
REPOSITORY_URI = 'FAKE_REPOSITORY_URI'
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
FakeWeb.register_uri :get,
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def pretend_we_are_on_a_developer_machine
|
15
|
+
ENV['REPOSITORY_URI'] = REPOSITORY_URI
|
16
|
+
FakeWeb.allow_net_connect = false
|
17
|
+
FakeWeb.register_uri :get,
|
18
|
+
"https://cloud.engineyard.com/api/v2/environments",
|
19
|
+
:status => ["200", "OK"],
|
20
|
+
:body => File.read(File.join(File.dirname(__FILE__), 'support', 'engine_yard_cloud_api_response.json'))
|
21
|
+
# FakeFS.activate!
|
22
|
+
end
|
18
23
|
|
19
|
-
# fake call to amazon ec2 api to get present instance id
|
20
|
-
FakeWeb.register_uri :get,
|
21
|
-
"http://169.254.169.254/latest/meta-data/instance-id",
|
22
|
-
:status => ["200", "OK"],
|
23
|
-
:body => PRESENT_INSTANCE_ID
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
def pretend_we_are_on_an_engineyard_appcloud_ec2_instance
|
26
|
+
FakeWeb.allow_net_connect = false
|
27
|
+
# fake call to amazon ec2 api to get present security group
|
28
|
+
FakeWeb.register_uri :get,
|
29
|
+
"http://169.254.169.254/latest/meta-data/security-groups",
|
30
|
+
:status => ["200", "OK"],
|
31
|
+
:body => PRESENT_SECURITY_GROUP
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
# fake call to amazon ec2 api to get present instance id
|
34
|
+
FakeWeb.register_uri :get,
|
35
|
+
"http://169.254.169.254/latest/meta-data/instance-id",
|
36
|
+
:status => ["200", "OK"],
|
37
|
+
:body => PRESENT_INSTANCE_ID
|
35
38
|
|
36
|
-
#
|
37
|
-
|
38
|
-
#
|
39
|
-
|
40
|
-
|
39
|
+
# first read a file from the real file system...
|
40
|
+
dna_json = File.read File.join(File.dirname(__FILE__), 'support', 'dna.json')
|
41
|
+
# ... then turn on the fakefs
|
42
|
+
FakeFS.activate!
|
43
|
+
FileUtils.mkdir_p '/etc/chef'
|
44
|
+
File.open '/etc/chef/dna.json', 'w' do |f|
|
45
|
+
f.write dna_json
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def stop_pretending
|
50
|
+
FakeFS.deactivate!
|
51
|
+
FakeWeb.clean_registry
|
52
|
+
FakeWeb.allow_net_connect = true
|
53
|
+
end
|
data/spec/support/dna.json
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
"internal_ssh_private_key": "-----BEGIN RSA PRIVATE KEY-----\nPRIVATE-KEY\n-----END RSA PRIVATE KEY-----\n",
|
16
16
|
"utility_instances": [
|
17
17
|
{
|
18
|
-
"name": "
|
18
|
+
"name": "FAKE_ENVIRONMENT_NAME_util_1",
|
19
19
|
"hostname": "internal_util_1.compute-1.internal"
|
20
20
|
}
|
21
21
|
],
|
@@ -77,7 +77,7 @@
|
|
77
77
|
"vhosts": [
|
78
78
|
{
|
79
79
|
"name": "_",
|
80
|
-
"role": "
|
80
|
+
"role": "FAKE_ENVIRONMENT_NAME"
|
81
81
|
}
|
82
82
|
]
|
83
83
|
}
|
@@ -86,15 +86,15 @@
|
|
86
86
|
"users": [
|
87
87
|
{
|
88
88
|
"gid": "1000",
|
89
|
-
"username": "
|
89
|
+
"username": "FAKE_SSH_USERNAME",
|
90
90
|
"uid": "1000",
|
91
91
|
"comment": "",
|
92
92
|
"password": "USERS-0-PASSWORD"
|
93
93
|
}
|
94
94
|
],
|
95
95
|
"environment": {
|
96
|
-
"name": "
|
97
|
-
"stack": "
|
96
|
+
"name": "FAKE_ENVIRONMENT_NAME",
|
97
|
+
"stack": "FAKE_STACK_NAME",
|
98
98
|
"framework_env": "production"
|
99
99
|
},
|
100
100
|
"master_app_server": {
|
@@ -107,7 +107,7 @@
|
|
107
107
|
"name": "dev-libs/oniguruma"
|
108
108
|
}
|
109
109
|
],
|
110
|
-
"db_host": "
|
110
|
+
"db_host": "FAKE_DB_HOST",
|
111
111
|
"haproxy": {
|
112
112
|
"username": "HAPROXY-USERNAME",
|
113
113
|
"password": "HAPROXY-PASSWORD"
|
@@ -116,12 +116,12 @@
|
|
116
116
|
"environment": {
|
117
117
|
"apps": [
|
118
118
|
{
|
119
|
-
"name": "
|
119
|
+
"name": "FAKE_APP_NAME",
|
120
120
|
"newrelic": false,
|
121
121
|
"components": [
|
122
122
|
|
123
123
|
],
|
124
|
-
"database_name": "
|
124
|
+
"database_name": "FAKE_APP_NAME",
|
125
125
|
"migration_command": "rake db:migrate",
|
126
126
|
"type": "rack",
|
127
127
|
"repository_name": "APPS-0-REPOSITORY_NAME",
|
@@ -153,7 +153,7 @@
|
|
153
153
|
}
|
154
154
|
],
|
155
155
|
"aws_secret_key": "AWS-SECRET-KEY",
|
156
|
-
"name": "
|
156
|
+
"name": "FAKE_ENVIRONMENT_NAME",
|
157
157
|
"ssh_keys": [
|
158
158
|
"ssh-rsa AAAAB3NzaC1yc2EAAAAB key-a",
|
159
159
|
"ssh-rsa AAAAB3NzaC1yc2EAAAAB key-b",
|
@@ -192,7 +192,7 @@
|
|
192
192
|
},
|
193
193
|
{
|
194
194
|
"name": null,
|
195
|
-
"public_hostname": "
|
195
|
+
"public_hostname": "FAKE_DB_MASTER_PUBLIC_HOSTNAME",
|
196
196
|
"components": [
|
197
197
|
{
|
198
198
|
"key": "ssmtp"
|
@@ -222,7 +222,7 @@
|
|
222
222
|
},
|
223
223
|
{
|
224
224
|
"name": "foobarfoo",
|
225
|
-
"public_hostname": "
|
225
|
+
"public_hostname": "FAKE_UTIL_1_PUBLIC_HOSTNAME",
|
226
226
|
"components": [
|
227
227
|
{
|
228
228
|
"key": "ssmtp"
|
@@ -242,7 +242,7 @@
|
|
242
242
|
"backup_interval": 24,
|
243
243
|
"admin_ssh_key": "ssh-rsa AAAAB3NzaC1 ey-cloud-production\n",
|
244
244
|
"internal_ssh_public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAAB \n",
|
245
|
-
"ssh_username": "
|
245
|
+
"ssh_username": "FAKE_SSH_USERNAME",
|
246
246
|
"internal_ssh_private_key": "-----BEGIN RSA PRIVATE KEY-----\nINTERNAL-SSH-PRIVATE-KEY\n-----END RSA PRIVATE KEY-----\n",
|
247
247
|
"mailserver": "smtp.engineyard.com",
|
248
248
|
"components": [
|
@@ -255,7 +255,7 @@
|
|
255
255
|
|
256
256
|
],
|
257
257
|
"backup_window": 10,
|
258
|
-
"stack_name": "
|
258
|
+
"stack_name": "FAKE_STACK_NAME",
|
259
259
|
"alert_email": "ALERT-EMAIL",
|
260
260
|
"ssh_password": "SSH-PASSWORD",
|
261
261
|
"db_stack_name": "mysql",
|
@@ -0,0 +1,28 @@
|
|
1
|
+
{"environments":
|
2
|
+
[
|
3
|
+
{"app_master":
|
4
|
+
{"public_hostname":"app_master.compute-1.amazonaws.com","name":null,"status":"running","amazon_id":"i-aaaaaaaa","role":"app_master","id":11111
|
5
|
+
},"ssh_username":"FAKE_SSH_USERNAME","stack_name":"FAKE_STACK_NAME","framework_env":"production","name":"FAKE_ENVIRONMENT_NAME","account":
|
6
|
+
{"name":"FAKE_ACCOUNT_NAME","id":12345
|
7
|
+
},"instances_count":5,"apps":
|
8
|
+
[
|
9
|
+
{"repository_uri":"FAKE_REPOSITORY_URI","name":"FAKE_APP_NAME","account":
|
10
|
+
{"name":"FAKE_ACCOUNT_NAME","id":12345
|
11
|
+
},"id":292301
|
12
|
+
}
|
13
|
+
],"id":382918,"instances":
|
14
|
+
[
|
15
|
+
{"public_hostname":"app_master.compute-1.amazonaws.com","name":null,"status":"running","amazon_id":"i-aaaaaaaa","role":"app_master","id":11111
|
16
|
+
},
|
17
|
+
{"public_hostname":"app_1.compute-1.amazonaws.com","name":null,"status":"running","amazon_id":"i-bbbbbbbb","role":"app","id":22222
|
18
|
+
},
|
19
|
+
{"public_hostname":"FAKE_DB_MASTER_PUBLIC_HOSTNAME","name":null,"status":"running","amazon_id":"i-cccccccc","role":"db_master","id":33333
|
20
|
+
},
|
21
|
+
{"public_hostname":"db_slave_1.compute-1.amazonaws.com","name":null,"status":"running","amazon_id":"i-cccccccc","role":"db_slave","id":44444
|
22
|
+
},
|
23
|
+
{"public_hostname":"FAKE_UTIL_1_PUBLIC_HOSTNAME","name":"data1_production_util1","status":"running","amazon_id":"i-dddddddd","role":"util","id":55555
|
24
|
+
}
|
25
|
+
]
|
26
|
+
}
|
27
|
+
]
|
28
|
+
}
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: engineyard-metadata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Seamus Abshere
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-10-
|
18
|
+
date: 2010-10-14 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
38
|
+
name: nap
|
39
39
|
prerelease: false
|
40
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
@@ -45,11 +45,12 @@ dependencies:
|
|
45
45
|
hash: 3
|
46
46
|
segments:
|
47
47
|
- 0
|
48
|
-
|
49
|
-
|
48
|
+
- 4
|
49
|
+
version: "0.4"
|
50
|
+
type: :runtime
|
50
51
|
version_requirements: *id002
|
51
52
|
- !ruby/object:Gem::Dependency
|
52
|
-
name:
|
53
|
+
name: fakeweb
|
53
54
|
prerelease: false
|
54
55
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
56
|
none: false
|
@@ -63,9 +64,23 @@ dependencies:
|
|
63
64
|
type: :development
|
64
65
|
version_requirements: *id003
|
65
66
|
- !ruby/object:Gem::Dependency
|
66
|
-
name:
|
67
|
+
name: fakefs
|
67
68
|
prerelease: false
|
68
69
|
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rspec
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
69
84
|
none: false
|
70
85
|
requirements:
|
71
86
|
- - ~>
|
@@ -75,7 +90,7 @@ dependencies:
|
|
75
90
|
- 1
|
76
91
|
version: "1"
|
77
92
|
type: :development
|
78
|
-
version_requirements: *
|
93
|
+
version_requirements: *id005
|
79
94
|
description: Pulls metadata from EC2 and EngineYard so that your EngineYard AppCloud (Amazon EC2) instances know about each other.
|
80
95
|
email: seamus@abshere.net
|
81
96
|
executables: []
|
@@ -96,10 +111,14 @@ files:
|
|
96
111
|
- lib/engineyard-metadata.rb
|
97
112
|
- lib/engineyard-metadata/amazon_ec2_api.rb
|
98
113
|
- lib/engineyard-metadata/chef_dna.rb
|
114
|
+
- lib/engineyard-metadata/engine_yard_cloud_api.rb
|
115
|
+
- lib/engineyard-metadata/insider.rb
|
99
116
|
- lib/engineyard-metadata/metadata.rb
|
117
|
+
- lib/engineyard-metadata/outsider.rb
|
100
118
|
- spec/metadata_spec.rb
|
101
119
|
- spec/spec_helper.rb
|
102
120
|
- spec/support/dna.json
|
121
|
+
- spec/support/engine_yard_cloud_api_response.json
|
103
122
|
has_rdoc: true
|
104
123
|
homepage: http://github.com/seamusabshere/engineyard-metadata
|
105
124
|
licenses: []
|