engineyard 1.3.14 → 1.3.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -68,7 +68,7 @@ module EY
68
68
  rescue RestClient::ResourceNotFound
69
69
  raise RequestFailed, "The requested resource could not be found"
70
70
  rescue RestClient::RequestFailed => e
71
- raise RequestFailed, "#{e.message}"
71
+ raise RequestFailed, "#{e.message} #{e.response}"
72
72
  rescue OpenSSL::SSL::SSLError
73
73
  raise RequestFailed, "SSL is misconfigured on your cloud"
74
74
  end
@@ -0,0 +1,32 @@
1
+ module EY
2
+ class CLI
3
+ class Recipes < EY::Thor
4
+ X1gx1GGG desc "recipes apply [ENVIRONMENT]", <<-DESC
5
+ Run uploaded chef recipes on specified environment.
6
+
7
+ This is similar to '#{banner_base} rebuild' except Engine Yard's main
8
+ configuration step is skipped.
9
+ DESC
10
+
11
+ def apply(name = nil)
12
+ environment = fetch_environment(name)
13
+ environment.run_custom_recipes
14
+ EY.ui.say "Uploaded recipes started for #{environment.name}"
15
+ end
16
+
17
+ desc "recipes upload [ENVIRONMENT]", <<-DESC
18
+ Upload custom chef recipes to specified environment.
19
+
20
+ The current directory should contain a subdirectory named "cookbooks" to be
21
+ uploaded.
22
+ DESC
23
+
24
+ def upload(name = nil)
25
+ environment = fetch_environment(name)
26
+ environment.upload_recipes
27
+ EY.ui.say "Recipes uploaded successfully for #{environment.name}"
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -2,6 +2,31 @@ module EY
2
2
  class CLI
3
3
  class UI < Thor::Base.shell
4
4
 
5
+ class Prompter
6
+ class Mock
7
+ def next_answer=(arg)
8
+ @answers ||= []
9
+ @answers << arg
10
+ end
11
+ def ask(*args, &block)
12
+ @questions ||= []
13
+ @questions << args.first
14
+ @answers.pop
15
+ end
16
+ attr_reader :questions
17
+ end
18
+ def self.enable_mock!
19
+ @backend = Mock.new
20
+ end
21
+ def self.backend
22
+ require 'highline'
23
+ @backend ||= HighLine.new($stdin)
24
+ end
25
+ def self.ask(*args, &block)
26
+ backend.ask(*args, &block)
27
+ end
28
+ end
29
+
5
30
  def error(name, message = nil)
6
31
  begin
7
32
  orig_out, $stdout = $stdout, $stderr
@@ -45,14 +70,12 @@ module EY
45
70
 
46
71
  def ask(message, password = false)
47
72
  begin
48
- require 'highline'
49
- @hl ||= HighLine.new($stdin)
50
73
  if not $stdin.tty?
51
- @hl.ask(message)
74
+ Prompter.ask(message)
52
75
  elsif password
53
- @hl.ask(message) {|q| q.echo = "*" }
76
+ Prompter.ask(message) {|q| q.echo = "*" }
54
77
  else
55
- @hl.ask(message) {|q| q.readline = true }
78
+ Prompter.ask(message) {|q| q.readline = true }
56
79
  end
57
80
  rescue EOFError
58
81
  return ''
@@ -1,3 +1,3 @@
1
1
  module EY
2
- VERSION = '1.3.14'
2
+ VERSION = '1.3.15'
3
3
  end
@@ -22,14 +22,15 @@ describe EY::CLI::API do
22
22
  before(:each) do
23
23
  FakeWeb.register_uri(:post, "https://cloud.engineyard.com/api/v2/authenticate", :body => %|{"api_token": "asdf"}|, :content_type => 'application/json')
24
24
 
25
- capture_stdio("\n\n") do
26
- @token = EY::CLI::API.new
27
- end
25
+ EY::CLI::UI::Prompter.enable_mock!
26
+ EY::CLI::UI::Prompter.backend.next_answer = "my@email.example.com"
27
+ EY::CLI::UI::Prompter.backend.next_answer = "secret"
28
+
29
+ @token = EY::CLI::API.new
28
30
  end
29
31
 
30
32
  it "asks you for your credentials" do
31
- @out.should include("Email:")
32
- @out.should include("Password:")
33
+ EY::CLI::UI::Prompter.backend.questions.should == ["Email: ","Password: "]
33
34
  end
34
35
 
35
36
  it "gets the api token" do
@@ -4,6 +4,7 @@ require 'engineyard/cli'
4
4
  describe EY::CLI do
5
5
 
6
6
  it "sets up EY.ui" do
7
+ EY.instance_eval{ @ui = nil }
7
8
  EY.ui.should be_an(EY::UI)
8
9
  capture_stdout do
9
10
  EY::CLI.start(["help"])
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'net/ssh'
2
3
 
3
4
  describe "ey deploy without an eyrc file" do
4
5
 
@@ -50,6 +51,23 @@ end
50
51
  describe "ey deploy" do
51
52
  given "integration"
52
53
 
54
+ context "without ssh keys (with ssh enabled)" do
55
+ before do
56
+ ENV['NO_SSH'] = nil
57
+ Net::SSH.stub!(:start).and_raise(Net::SSH::AuthenticationFailed.new("no key"))
58
+ end
59
+
60
+ after do
61
+ ENV['NO_SSH'] = 'true'
62
+ end
63
+
64
+ it "tells you that you need to add an appropriate ssh key" do
65
+ api_scenario "one app, one environment"
66
+ fast_failing_ey ["deploy"]
67
+ @err.should include("Authentication Failed")
68
+ end
69
+ end
70
+
53
71
  context "with invalid input" do
54
72
  it "complains when there is no app" do
55
73
  api_scenario "empty"
@@ -36,7 +36,7 @@ module Spec
36
36
  def fast_failing_ey(*args)
37
37
  begin
38
38
  fast_ey(*args)
39
- raise ZeroExitStatus
39
+ raise ZeroExitStatus.new(@out, @err)
40
40
  rescue SystemExit => exit_status
41
41
  # SystemExit typically indicates a bogus command, which we
42
42
  # here in expected-to-fail land are entirely happy with.
@@ -100,6 +100,21 @@ shared_examples_for "it takes an environment name and an account name" do
100
100
  :ssh_username => 'turkey',
101
101
  }))
102
102
  end
103
+
104
+ context "when the backend raises an error" do
105
+ before do
106
+ failed_response = RestClient::Response.create(
107
+ '{ "message": "Important infos about how you failed!"}', OpenStruct.new(:code => 400), nil)
108
+ RestClient.stub!(:send).and_raise(RestClient::RequestFailed.new(failed_response))
109
+ end
110
+
111
+ it "returns the error message to the user" do
112
+ lambda do
113
+ fast_ey(command_to_run({:environment => "giblets", :account => "main"}).split(" "))
114
+ end.should raise_error(EY::Error, /400.*Important infos/)
115
+ end
116
+ end
117
+
103
118
  end
104
119
  end
105
120
 
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: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 14
10
- version: 1.3.14
9
+ - 15
10
+ version: 1.3.15
11
11
  platform: ruby
12
12
  authors:
13
13
  - EY Cloud Team
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-11 00:00:00 -08:00
18
+ date: 2011-02-11 00:00:00 -08:00
19
19
  default_executable: ey
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -31,9 +31,9 @@ dependencies:
31
31
  - 6
32
32
  version: 0.14.6
33
33
  requirement: *id001
34
+ type: :runtime
34
35
  name: thor
35
36
  prerelease: false
36
- type: :runtime
37
37
  - !ruby/object:Gem::Dependency
38
38
  version_requirements: &id002 !ruby/object:Gem::Requirement
39
39
  none: false
@@ -47,9 +47,9 @@ dependencies:
47
47
  - 0
48
48
  version: 1.6.0
49
49
  requirement: *id002
50
+ type: :runtime
50
51
  name: rest-client
51
52
  prerelease: false
52
- type: :runtime
53
53
  - !ruby/object:Gem::Dependency
54
54
  version_requirements: &id003 !ruby/object:Gem::Requirement
55
55
  none: false
@@ -63,9 +63,9 @@ dependencies:
63
63
  - 1
64
64
  version: 1.6.1
65
65
  requirement: *id003
66
+ type: :runtime
66
67
  name: highline
67
68
  prerelease: false
68
- type: :runtime
69
69
  - !ruby/object:Gem::Dependency
70
70
  version_requirements: &id004 !ruby/object:Gem::Requirement
71
71
  none: false
@@ -77,9 +77,9 @@ dependencies:
77
77
  - 0
78
78
  version: "0"
79
79
  requirement: *id004
80
+ type: :runtime
80
81
  name: json_pure
81
82
  prerelease: false
82
- type: :runtime
83
83
  - !ruby/object:Gem::Dependency
84
84
  version_requirements: &id005 !ruby/object:Gem::Requirement
85
85
  none: false
@@ -93,9 +93,9 @@ dependencies:
93
93
  - 4
94
94
  version: 0.0.4
95
95
  requirement: *id005
96
+ type: :runtime
96
97
  name: escape
97
98
  prerelease: false
98
- type: :runtime
99
99
  - !ruby/object:Gem::Dependency
100
100
  version_requirements: &id006 !ruby/object:Gem::Requirement
101
101
  none: false
@@ -109,9 +109,9 @@ dependencies:
109
109
  - 0
110
110
  version: 1.4.0
111
111
  requirement: *id006
112
+ type: :runtime
112
113
  name: engineyard-serverside-adapter
113
114
  prerelease: false
114
- type: :runtime
115
115
  - !ruby/object:Gem::Dependency
116
116
  version_requirements: &id007 !ruby/object:Gem::Requirement
117
117
  none: false
@@ -125,9 +125,9 @@ dependencies:
125
125
  - 23
126
126
  version: 2.0.23
127
127
  requirement: *id007
128
+ type: :runtime
128
129
  name: net-ssh
129
130
  prerelease: false
130
- type: :runtime
131
131
  description: This gem allows you to deploy your rails application to the Engine Yard cloud directly from the command line.
132
132
  email: cloud@engineyard.com
133
133
  executables:
@@ -139,6 +139,7 @@ extra_rdoc_files: []
139
139
  files:
140
140
  - bin/ey
141
141
  - lib/engineyard/api.rb
142
+ - lib/engineyard/cli/#recipes.rb#
142
143
  - lib/engineyard/cli/api.rb
143
144
  - lib/engineyard/cli/recipes.rb
144
145
  - lib/engineyard/cli/ui.rb
@@ -201,7 +202,19 @@ has_rdoc: true
201
202
  homepage: http://github.com/engineyard/engineyard
202
203
  licenses: []
203
204
 
204
- post_install_message:
205
+ post_install_message: |+
206
+
207
+ Welcome to Engine Yard!
208
+
209
+ Deploying for the first time? The Engine Yard Pandas want to help you!
210
+
211
+ Email pandas@engineyard.com with your questions or queries.
212
+ (Panda = 1. Polite Agent of Non-Destructive Assimilation; 2. Cute fluffy animal.)
213
+
214
+ We wish you every success with your business!
215
+
216
+ - The Pandas
217
+
205
218
  rdoc_options: []
206
219
 
207
220
  require_paths: