engineyard 1.3.22 → 1.3.25

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 CHANGED
@@ -171,3 +171,13 @@ Command:
171
171
  Note: this command is a bit picky about its ordering. To run a command with arguments on all servers, like "rm -f /some/file", you need to order it like so:
172
172
 
173
173
  $ ey ssh "rm -f /some/file" -e my-environment --all
174
+
175
+ Command:
176
+ ey launch
177
+
178
+ Options:
179
+ -e, [--environment=ENVIRONMENT] # Environment to ssh into
180
+ -c, [--account=ACCOUNT] # Name of the account in which the environment can be found
181
+
182
+ Description:
183
+ Open the application in a browser.
@@ -0,0 +1,135 @@
1
+ require 'engineyard/model'
2
+
3
+ module EngineYard
4
+ class APIClient
5
+ attr_reader :token
6
+
7
+ USER_AGENT_STRING = "EngineYardAPIClient/#{VERSION}"
8
+
9
+ def initialize(token = nil)
10
+ @token ||= token
11
+ @token ||= self.class.read_token
12
+ raise ArgumentError, "EY Cloud API token required" unless @token
13
+ end
14
+
15
+ def ==(other)
16
+ raise ArgumentError unless other.is_a?(self.class)
17
+ self.token == other.token
18
+ end
19
+
20
+ def request(url, opts={})
21
+ opts[:headers] ||= {}
22
+ opts[:headers]["X-EY-Cloud-Token"] = token
23
+ EY.ui.debug("Token", token)
24
+ self.class.request(url, opts)
25
+ end
26
+
27
+ def environments
28
+ @environments ||= Environment.from_array(request('/environments')["environments"], :api => self)
29
+ end
30
+
31
+ def apps
32
+ @apps ||= App.from_array(request('/apps')["apps"], :api => self)
33
+ end
34
+
35
+ def resolver
36
+ @resolver ||= Resolver.new(self)
37
+ end
38
+
39
+ def apps_for_repo(repo)
40
+ repo.fail_on_no_remotes!
41
+ apps.find_all {|a| repo.has_remote?(a.repository_uri) }
42
+ end
43
+
44
+ class InvalidCredentials < EY::AppCloudClient::Error; end
45
+ class RequestFailed < EY::AppCloudClient::Error; end
46
+
47
+ def self.request(path, opts={})
48
+ require 'rest_client'
49
+ require 'json'
50
+
51
+ url = EY.config.endpoint + "api/v2#{path}"
52
+ method = (opts.delete(:method) || 'get').to_s.downcase.to_sym
53
+ params = opts.delete(:params) || {}
54
+ headers = opts.delete(:headers) || {}
55
+ headers["Accept"] ||= "application/json"
56
+ headers["User-Agent"] = USER_AGENT_STRING
57
+
58
+ begin
59
+ EY.ui.debug("Request", "#{method.to_s.upcase} #{url}")
60
+ case method
61
+ when :get, :delete, :head
62
+ url.query = RestClient::Payload::UrlEncoded.new(params).to_s
63
+ resp = RestClient.send(method, url.to_s, headers)
64
+ else
65
+ resp = RestClient.send(method, url.to_s, params, headers)
66
+ end
67
+ rescue RestClient::Unauthorized
68
+ raise InvalidCredentials
69
+ rescue Errno::ECONNREFUSED
70
+ raise RequestFailed, "Could not reach the cloud API"
71
+ rescue RestClient::ResourceNotFound
72
+ raise RequestFailed, "The requested resource could not be found"
73
+ rescue RestClient::BadGateway
74
+ raise RequestFailed, "AppCloud API is temporarily unavailable. Please try again soon."
75
+ rescue RestClient::RequestFailed => e
76
+ raise RequestFailed, "#{e.message} #{e.response}"
77
+ rescue OpenSSL::SSL::SSLError
78
+ raise RequestFailed, "SSL is misconfigured on your cloud"
79
+ end
80
+
81
+ if resp.body.empty?
82
+ data = ''
83
+ elsif resp.headers[:content_type] =~ /application\/json/
84
+ begin
85
+ data = JSON.parse(resp.body)
86
+ EY.ui.debug("Response", data)
87
+ rescue JSON::ParserError
88
+ EY.ui.debug("Raw response", resp.body)
89
+ raise RequestFailed, "Response was not valid JSON."
90
+ end
91
+ else
92
+ data = resp.body
93
+ end
94
+
95
+ data
96
+ end
97
+
98
+ def self.fetch_token(email, password)
99
+ api_token = request("/authenticate", :method => "post",
100
+ :params => { :email => email, :password => password })["api_token"]
101
+ save_token(api_token)
102
+ api_token
103
+ end
104
+
105
+ def self.read_token(file = nil)
106
+ file ||= ENV['EYRC'] || File.expand_path("~/.eyrc")
107
+ return false unless File.exists?(file)
108
+
109
+ require 'yaml'
110
+
111
+ data = YAML.load_file(file)
112
+ if EY.config.default_endpoint?
113
+ data["api_token"]
114
+ else
115
+ (data[EY.config.endpoint.to_s] || {})["api_token"]
116
+ end
117
+ end
118
+
119
+ def self.save_token(token, file = nil)
120
+ file ||= ENV['EYRC'] || File.expand_path("~/.eyrc")
121
+ require 'yaml'
122
+
123
+ data = File.exists?(file) ? YAML.load_file(file) : {}
124
+ if EY.config.default_endpoint?
125
+ data.merge!("api_token" => token)
126
+ else
127
+ data.merge!(EY.config.endpoint.to_s => {"api_token" => token})
128
+ end
129
+
130
+ File.open(file, "w"){|f| YAML.dump(data, f) }
131
+ true
132
+ end
133
+
134
+ end # API
135
+ end # EY
@@ -68,6 +68,7 @@ module EY
68
68
 
69
69
  if environment.deploy(app, deploy_ref, deploy_options)
70
70
  EY.ui.info "Deploy complete"
71
+ EY.ui.info "Now you can run `ey launch' to open the application in a browser."
71
72
  else
72
73
  raise EY::Error, "Deploy failed"
73
74
  end
@@ -331,5 +332,15 @@ module EY
331
332
  end
332
333
  end
333
334
 
335
+ desc "launch [--environment ENVIRONMENT] [--account ACCOUNT]", "Open application in browser."
336
+ method_option :environment, :type => :string, :aliases => %w(-e),
337
+ :desc => "Environment with the interesting logs"
338
+ method_option :account, :type => :string, :aliases => %w(-c),
339
+ :desc => "Name of the account in which the environment can be found"
340
+ def launch
341
+ environment = fetch_environment(options[:environment], options[:account])
342
+ environment.launch
343
+ end
344
+
334
345
  end # CLI
335
346
  end # EY
@@ -7,8 +7,8 @@ module EY
7
7
  def initialize(file = nil)
8
8
  require 'yaml'
9
9
  @file = file || CONFIG_FILES.find{|f| File.exists?(f) }
10
- @config = @file ? YAML.load_file(@file) : {}
11
- @config.merge!("environments" => {}) unless @config["environments"]
10
+ @config = (@file ? YAML.load_file(@file) : {}) || {} # load_file returns `false' when the file is empty
11
+ @config["environments"] = {} unless @config["environments"]
12
12
  end
13
13
 
14
14
  def method_missing(meth, *args, &blk)
@@ -1,6 +1,7 @@
1
1
  module EY
2
2
  module Model
3
3
  class Environment < ApiStruct.new(:id, :account, :name, :framework_env, :instances, :instances_count, :apps, :app_master, :username, :app_server_stack_name, :load_balancer_ip_address, :api)
4
+ require 'launchy'
4
5
 
5
6
  attr_accessor :ignore_bad_master
6
7
 
@@ -132,6 +133,10 @@ module EY
132
133
  name.gsub(/^#{Regexp.quote(app.name)}_/, '')
133
134
  end
134
135
 
136
+ def launch
137
+ Launchy.open(app_master!.hostname_url)
138
+ end
139
+
135
140
  private
136
141
 
137
142
  def migration_command(deploy_options)
@@ -44,7 +44,6 @@ module EY
44
44
  invoke rollback
45
45
  end
46
46
 
47
-
48
47
  def put_up_maintenance_page(app, verbose=false)
49
48
  invoke adapter(app, verbose).enable_maintenance_page
50
49
  end
@@ -57,6 +56,10 @@ module EY
57
56
  !["db_master", "db_slave"].include?(role.to_s)
58
57
  end
59
58
 
59
+ def hostname_url
60
+ "http://#{hostname}" if hostname
61
+ end
62
+
60
63
  protected
61
64
 
62
65
  def engineyard_serverside_hostname
@@ -1,3 +1,3 @@
1
1
  module EY
2
- VERSION = '1.3.22'
2
+ VERSION = '1.3.25'
3
3
  end
@@ -4,6 +4,7 @@ describe EY::Repo do
4
4
  before(:all) do
5
5
  FakeFS.deactivate!
6
6
  @path = Pathname.new("/tmp/ey-test/.git/")
7
+ @path.mkpath
7
8
  @r = EY::Repo.new("/tmp/ey-test")
8
9
  end
9
10
  after(:all) { FakeFS.activate! }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: engineyard
3
3
  version: !ruby/object:Gem::Version
4
- hash: 55
4
+ hash: 41
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 22
10
- version: 1.3.22
9
+ - 25
10
+ version: 1.3.25
11
11
  platform: ruby
12
12
  authors:
13
13
  - EY Cloud Team
@@ -15,11 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-09 00:00:00 -07:00
18
+ date: 2011-09-12 00:00:00 -07:00
19
19
  default_executable: ey
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- version_requirements: &id001 !ruby/object:Gem::Requirement
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
23
  none: false
24
24
  requirements:
25
25
  - - ~>
@@ -30,12 +30,12 @@ dependencies:
30
30
  - 14
31
31
  - 6
32
32
  version: 0.14.6
33
- type: :runtime
34
- requirement: *id001
35
33
  name: thor
36
34
  prerelease: false
35
+ type: :runtime
36
+ version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
38
- version_requirements: &id002 !ruby/object:Gem::Requirement
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -46,12 +46,12 @@ dependencies:
46
46
  - 6
47
47
  - 0
48
48
  version: 1.6.0
49
- type: :runtime
50
- requirement: *id002
51
49
  name: rest-client
52
50
  prerelease: false
51
+ type: :runtime
52
+ version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
54
- version_requirements: &id003 !ruby/object:Gem::Requirement
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
55
  none: false
56
56
  requirements:
57
57
  - - ~>
@@ -62,12 +62,12 @@ dependencies:
62
62
  - 6
63
63
  - 1
64
64
  version: 1.6.1
65
- type: :runtime
66
- requirement: *id003
67
65
  name: highline
68
66
  prerelease: false
67
+ type: :runtime
68
+ version_requirements: *id003
69
69
  - !ruby/object:Gem::Dependency
70
- version_requirements: &id004 !ruby/object:Gem::Requirement
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
71
  none: false
72
72
  requirements:
73
73
  - - ">="
@@ -76,12 +76,12 @@ dependencies:
76
76
  segments:
77
77
  - 0
78
78
  version: "0"
79
- type: :runtime
80
- requirement: *id004
81
79
  name: json_pure
82
80
  prerelease: false
81
+ type: :runtime
82
+ version_requirements: *id004
83
83
  - !ruby/object:Gem::Dependency
84
- version_requirements: &id005 !ruby/object:Gem::Requirement
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ~>
@@ -92,28 +92,28 @@ dependencies:
92
92
  - 0
93
93
  - 4
94
94
  version: 0.0.4
95
- type: :runtime
96
- requirement: *id005
97
95
  name: escape
98
96
  prerelease: false
97
+ type: :runtime
98
+ version_requirements: *id005
99
99
  - !ruby/object:Gem::Dependency
100
- version_requirements: &id006 !ruby/object:Gem::Requirement
100
+ requirement: &id006 !ruby/object:Gem::Requirement
101
101
  none: false
102
102
  requirements:
103
103
  - - "="
104
104
  - !ruby/object:Gem::Version
105
- hash: 3
105
+ hash: 5
106
106
  segments:
107
107
  - 1
108
108
  - 4
109
- - 2
110
- version: 1.4.2
111
- type: :runtime
112
- requirement: *id006
109
+ - 1
110
+ version: 1.4.1
113
111
  name: engineyard-serverside-adapter
114
112
  prerelease: false
113
+ type: :runtime
114
+ version_requirements: *id006
115
115
  - !ruby/object:Gem::Dependency
116
- version_requirements: &id007 !ruby/object:Gem::Requirement
116
+ requirement: &id007 !ruby/object:Gem::Requirement
117
117
  none: false
118
118
  requirements:
119
119
  - - ~>
@@ -124,12 +124,28 @@ dependencies:
124
124
  - 1
125
125
  - 0
126
126
  version: 2.1.0
127
- type: :runtime
128
- requirement: *id007
129
127
  name: net-ssh
130
128
  prerelease: false
129
+ type: :runtime
130
+ version_requirements: *id007
131
131
  - !ruby/object:Gem::Dependency
132
- version_requirements: &id008 !ruby/object:Gem::Requirement
132
+ requirement: &id008 !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - "="
136
+ - !ruby/object:Gem::Version
137
+ hash: 5
138
+ segments:
139
+ - 2
140
+ - 0
141
+ - 5
142
+ version: 2.0.5
143
+ name: launchy
144
+ prerelease: false
145
+ type: :runtime
146
+ version_requirements: *id008
147
+ - !ruby/object:Gem::Dependency
148
+ requirement: &id009 !ruby/object:Gem::Requirement
133
149
  none: false
134
150
  requirements:
135
151
  - - "="
@@ -140,12 +156,12 @@ dependencies:
140
156
  - 3
141
157
  - 0
142
158
  version: 1.3.0
143
- type: :development
144
- requirement: *id008
145
159
  name: rspec
146
160
  prerelease: false
161
+ type: :development
162
+ version_requirements: *id009
147
163
  - !ruby/object:Gem::Dependency
148
- version_requirements: &id009 !ruby/object:Gem::Requirement
164
+ requirement: &id010 !ruby/object:Gem::Requirement
149
165
  none: false
150
166
  requirements:
151
167
  - - ">="
@@ -154,12 +170,12 @@ dependencies:
154
170
  segments:
155
171
  - 0
156
172
  version: "0"
157
- type: :development
158
- requirement: *id009
159
173
  name: rake
160
174
  prerelease: false
175
+ type: :development
176
+ version_requirements: *id010
161
177
  - !ruby/object:Gem::Dependency
162
- version_requirements: &id010 !ruby/object:Gem::Requirement
178
+ requirement: &id011 !ruby/object:Gem::Requirement
163
179
  none: false
164
180
  requirements:
165
181
  - - ">="
@@ -168,12 +184,12 @@ dependencies:
168
184
  segments:
169
185
  - 0
170
186
  version: "0"
171
- type: :development
172
- requirement: *id010
173
187
  name: fakeweb
174
188
  prerelease: false
189
+ type: :development
190
+ version_requirements: *id011
175
191
  - !ruby/object:Gem::Dependency
176
- version_requirements: &id011 !ruby/object:Gem::Requirement
192
+ requirement: &id012 !ruby/object:Gem::Requirement
177
193
  none: false
178
194
  requirements:
179
195
  - - ">="
@@ -182,12 +198,12 @@ dependencies:
182
198
  segments:
183
199
  - 0
184
200
  version: "0"
185
- type: :development
186
- requirement: *id011
187
201
  name: fakeweb-matcher
188
202
  prerelease: false
203
+ type: :development
204
+ version_requirements: *id012
189
205
  - !ruby/object:Gem::Dependency
190
- version_requirements: &id012 !ruby/object:Gem::Requirement
206
+ requirement: &id013 !ruby/object:Gem::Requirement
191
207
  none: false
192
208
  requirements:
193
209
  - - ">="
@@ -196,12 +212,12 @@ dependencies:
196
212
  segments:
197
213
  - 0
198
214
  version: "0"
199
- type: :development
200
- requirement: *id012
201
215
  name: fakefs
202
216
  prerelease: false
217
+ type: :development
218
+ version_requirements: *id013
203
219
  - !ruby/object:Gem::Dependency
204
- version_requirements: &id013 !ruby/object:Gem::Requirement
220
+ requirement: &id014 !ruby/object:Gem::Requirement
205
221
  none: false
206
222
  requirements:
207
223
  - - ">="
@@ -210,12 +226,12 @@ dependencies:
210
226
  segments:
211
227
  - 0
212
228
  version: "0"
213
- type: :development
214
- requirement: *id013
215
229
  name: sinatra
216
230
  prerelease: false
231
+ type: :development
232
+ version_requirements: *id014
217
233
  - !ruby/object:Gem::Dependency
218
- version_requirements: &id014 !ruby/object:Gem::Requirement
234
+ requirement: &id015 !ruby/object:Gem::Requirement
219
235
  none: false
220
236
  requirements:
221
237
  - - ~>
@@ -226,12 +242,12 @@ dependencies:
226
242
  - 1
227
243
  - 6
228
244
  version: 0.1.6
229
- type: :development
230
- requirement: *id014
231
245
  name: realweb
232
246
  prerelease: false
247
+ type: :development
248
+ version_requirements: *id015
233
249
  - !ruby/object:Gem::Dependency
234
- version_requirements: &id015 !ruby/object:Gem::Requirement
250
+ requirement: &id016 !ruby/object:Gem::Requirement
235
251
  none: false
236
252
  requirements:
237
253
  - - ~>
@@ -242,10 +258,10 @@ dependencies:
242
258
  - 0
243
259
  - 1
244
260
  version: 1.0.1
245
- type: :development
246
- requirement: *id015
247
261
  name: open4
248
262
  prerelease: false
263
+ type: :development
264
+ version_requirements: *id016
249
265
  description: This gem allows you to deploy your rails application to the Engine Yard cloud directly from the command line.
250
266
  email: cloud@engineyard.com
251
267
  executables:
@@ -282,6 +298,7 @@ files:
282
298
  - lib/engineyard/ruby_ext.rb
283
299
  - lib/engineyard/thor.rb
284
300
  - lib/engineyard/version.rb
301
+ - lib/engineyard-api-client.rb
285
302
  - lib/engineyard.rb
286
303
  - LICENSE
287
304
  - README.rdoc
@@ -361,7 +378,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
361
378
  requirements: []
362
379
 
363
380
  rubyforge_project:
364
- rubygems_version: 1.4.2
381
+ rubygems_version: 1.5.0
365
382
  signing_key:
366
383
  specification_version: 3
367
384
  summary: Command-line deployment for the Engine Yard cloud