ey-core 3.1.2 → 3.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby-version +1 -1
- data/.travis.yml +1 -0
- data/Gemfile +0 -2
- data/examples/add_instance.rb +74 -0
- data/examples/boot_env.rb +60 -0
- data/examples/stop_env.rb +51 -0
- data/examples/terminate_instance.rb +58 -0
- data/lib/ey-core/cli/accounts.rb +14 -6
- data/lib/ey-core/cli/applications.rb +32 -12
- data/lib/ey-core/cli/console.rb +24 -10
- data/lib/ey-core/cli/current_user.rb +13 -5
- data/lib/ey-core/cli/deploy.rb +110 -52
- data/lib/ey-core/cli/environments.rb +34 -12
- data/lib/ey-core/cli/errors.rb +10 -6
- data/lib/ey-core/cli/help.rb +30 -0
- data/lib/ey-core/cli/helpers/archive.rb +70 -0
- data/lib/ey-core/cli/helpers/chef.rb +35 -0
- data/lib/ey-core/cli/helpers/core.rb +195 -0
- data/lib/ey-core/cli/helpers/deprecated.rb +39 -0
- data/lib/ey-core/cli/helpers/log_streaming.rb +41 -0
- data/lib/ey-core/cli/helpers/stream_printer.rb +42 -0
- data/lib/ey-core/cli/init.rb +11 -8
- data/lib/ey-core/cli/login.rb +33 -21
- data/lib/ey-core/cli/logout.rb +18 -10
- data/lib/ey-core/cli/logs.rb +57 -35
- data/lib/ey-core/cli/main.rb +52 -15
- data/lib/ey-core/cli/recipes.rb +5 -87
- data/lib/ey-core/cli/recipes/apply.rb +83 -43
- data/lib/ey-core/cli/recipes/download.rb +48 -22
- data/lib/ey-core/cli/recipes/main.rb +21 -0
- data/lib/ey-core/cli/recipes/upload.rb +56 -23
- data/lib/ey-core/cli/scp.rb +11 -8
- data/lib/ey-core/cli/servers.rb +37 -15
- data/lib/ey-core/cli/ssh.rb +127 -70
- data/lib/ey-core/cli/status.rb +54 -14
- data/lib/ey-core/cli/subcommand.rb +47 -108
- data/lib/ey-core/cli/timeout_deploy.rb +56 -26
- data/lib/ey-core/cli/version.rb +13 -5
- data/lib/ey-core/cli/web.rb +7 -7
- data/lib/ey-core/cli/web/disable.rb +46 -20
- data/lib/ey-core/cli/web/enable.rb +40 -17
- data/lib/ey-core/cli/web/main.rb +21 -0
- data/lib/ey-core/cli/web/restart.rb +34 -15
- data/lib/ey-core/cli/whoami.rb +11 -3
- data/lib/ey-core/mock/searching.rb +4 -0
- data/lib/ey-core/model.rb +5 -0
- data/lib/ey-core/models/deployment.rb +7 -0
- data/lib/ey-core/models/environment.rb +5 -0
- data/lib/ey-core/models/request.rb +2 -0
- data/lib/ey-core/models/user.rb +2 -0
- data/lib/ey-core/requests/get_servers.rb +1 -1
- data/lib/ey-core/response.rb +4 -0
- data/lib/ey-core/subscribable.rb +3 -3
- data/lib/ey-core/version.rb +1 -1
- data/spec/ey-core/cli/accounts_spec.rb +20 -0
- data/spec/ey-core/cli/recipes/apply_spec.rb +4 -17
- data/spec/ey-core/cli/recipes/download_spec.rb +93 -0
- data/spec/ey-core/cli/recipes/upload_spec.rb +80 -0
- data/spec/servers_spec.rb +15 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/cli_helpers.rb +38 -2
- metadata +116 -53
- checksums.yaml +0 -7
data/lib/ey-core/cli/status.rb
CHANGED
@@ -1,20 +1,60 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
summary "Show the deployment status of the app"
|
1
|
+
require 'ey-core/cli/subcommand'
|
2
|
+
require 'ey-core/cli/helpers/log_streaming'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module Ey
|
5
|
+
module Core
|
6
|
+
module Cli
|
7
|
+
class Status < Subcommand
|
8
|
+
include Ey::Core::Cli::Helpers::LogStreaming
|
9
|
+
title "status"
|
10
|
+
summary "Show the deployment status of the app"
|
11
|
+
description <<-DESC
|
12
|
+
Show the current status of the most recent deployment of the specifed application and environment
|
13
|
+
DESC
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
15
|
+
option :environment,
|
16
|
+
short: "e",
|
17
|
+
long: "environment",
|
18
|
+
description: "Name or id of the environment to deploy to.",
|
19
|
+
argument: "Environment"
|
12
20
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
21
|
+
option :account,
|
22
|
+
short: 'c',
|
23
|
+
long: 'account',
|
24
|
+
description: 'Name or ID of the account that the environment resides in. If no account is specified, the app will deploy to the first environment that meets the criteria, in the accounts you have access to.',
|
25
|
+
argument: 'Account name or id'
|
17
26
|
|
18
|
-
|
27
|
+
option :app,
|
28
|
+
short: "a",
|
29
|
+
long: "app",
|
30
|
+
description: "Application name or ID to deploy. If :account is not specified, this will be the first app that matches the criteria in the accounts you have access to.",
|
31
|
+
argument: "app"
|
32
|
+
|
33
|
+
switch :tail,
|
34
|
+
long: "tail",
|
35
|
+
description: "tail in-progress deployment log"
|
36
|
+
|
37
|
+
def handle
|
38
|
+
operator, environment = core_operator_and_environment_for(self.options)
|
39
|
+
app = core_application_for(environment, self.options)
|
40
|
+
deploy = environment.latest_deploy(app)
|
41
|
+
|
42
|
+
puts environment.release_label
|
43
|
+
puts "#{environment.servers.size} servers"
|
44
|
+
environment.servers.each do |s|
|
45
|
+
puts [s.provisioned_id, s.role, s.state].join(" ")
|
46
|
+
end
|
47
|
+
if deploy
|
48
|
+
ap deploy
|
49
|
+
if switch_active?(:tail)
|
50
|
+
stream_deploy_log(deploy.request)
|
51
|
+
end
|
52
|
+
else
|
53
|
+
puts "Never Deployed"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
19
59
|
end
|
20
60
|
end
|
@@ -1,113 +1,52 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
puts "Found legacy .eyrc token. Migrating to core file".green
|
27
|
-
write_core_yaml(legacy_token)
|
28
|
-
retry
|
29
|
-
elsif e.message.match(/missing token/i)
|
30
|
-
abort "Missing credentials: Run 'ey login' to retrieve your Engine Yard Cloud API token.".yellow
|
31
|
-
else
|
32
|
-
raise e
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def core_url
|
37
|
-
env_url = ENV["CORE_URL"] || ENV["CLOUD_URL"]
|
38
|
-
(env_url && File.join(env_url, '/')) || "https://api.engineyard.com/"
|
39
|
-
end
|
40
|
-
|
41
|
-
def current_accounts
|
42
|
-
core_client.users.current.accounts
|
43
|
-
end
|
44
|
-
|
45
|
-
def longest_length_by_name(collection)
|
46
|
-
collection.map(&:name).group_by(&:size).max.last.length
|
47
|
-
end
|
48
|
-
|
49
|
-
def write_core_yaml(token=nil)
|
50
|
-
core_yaml[core_url] = token if token
|
51
|
-
File.open(self.class.core_file, "w") { |f| f.puts core_yaml.to_yaml }
|
52
|
-
end
|
53
|
-
|
54
|
-
def eyrc_yaml
|
55
|
-
@eyrc_yaml ||= YAML.load_file(self.class.eyrc) || {}
|
56
|
-
rescue Errno::ENOENT => e # we don't really care if this doesn't exist
|
57
|
-
{}
|
58
|
-
end
|
59
|
-
|
60
|
-
def core_yaml
|
61
|
-
@core_yaml ||= YAML.load_file(self.class.core_file) || {}
|
62
|
-
rescue Errno::ENOENT => e
|
63
|
-
puts "Creating #{self.class.core_file}".yellow
|
64
|
-
FileUtils.touch(self.class.core_file)
|
65
|
-
retry
|
66
|
-
end
|
67
|
-
|
68
|
-
def core_account_for(options={})
|
69
|
-
@core_account ||= core_client.accounts.get(options[:account])
|
70
|
-
@core_account ||= core_client.users.current.accounts.first(name: options[:account])
|
71
|
-
end
|
72
|
-
|
73
|
-
def operator(options)
|
74
|
-
options[:account] ? core_account_for(options) : core_client
|
75
|
-
end
|
76
|
-
|
77
|
-
def core_operator_and_environment_for(options={})
|
78
|
-
operator = operator(options)
|
79
|
-
environment = operator.environments.get(options[:environment]) || operator.environments.first(name: options[:environment])
|
80
|
-
[operator, environment]
|
81
|
-
end
|
82
|
-
|
83
|
-
def core_environment_for(options={})
|
84
|
-
core_client.environments.get(options[:environment]) || core_client.environments.first(name: options[:environment])
|
85
|
-
end
|
86
|
-
|
87
|
-
def core_server_for(options={})
|
88
|
-
operator = options.fetch(:operator, core_client)
|
89
|
-
operator.servers.get(options[:server]) || operator.servers.first(provisioned_id: options[:server])
|
90
|
-
end
|
91
|
-
|
92
|
-
def core_application_for(options={})
|
93
|
-
return nil unless options[:app]
|
94
|
-
|
95
|
-
app = begin
|
96
|
-
Integer(options[:app])
|
97
|
-
rescue
|
98
|
-
options[:app]
|
1
|
+
require 'belafonte'
|
2
|
+
require 'colorize'
|
3
|
+
require 'table_print'
|
4
|
+
require 'ey-core'
|
5
|
+
require 'ey-core/cli/helpers/core'
|
6
|
+
|
7
|
+
module Ey
|
8
|
+
module Core
|
9
|
+
module Cli
|
10
|
+
class Subcommand < Belafonte::App
|
11
|
+
include Ey::Core::Cli::Helpers::Core
|
12
|
+
|
13
|
+
def setup
|
14
|
+
$stdout = stdout
|
15
|
+
$stderr = stderr
|
16
|
+
$stdin = stdin
|
17
|
+
$kernel = kernel
|
18
|
+
end
|
19
|
+
|
20
|
+
def run_handle
|
21
|
+
super
|
22
|
+
rescue Ey::Core::Response::Error => e
|
23
|
+
if ENV["DEBUG"]
|
24
|
+
puts e.inspect
|
25
|
+
puts e.backtrace
|
99
26
|
end
|
27
|
+
handle_core_error(e)
|
28
|
+
rescue => e
|
29
|
+
if ENV["DEBUG"]
|
30
|
+
puts e.inspect
|
31
|
+
puts e.backtrace
|
32
|
+
end
|
33
|
+
stderr.puts "Error:".red
|
34
|
+
stderr.puts Wrapomatic.wrap(e.message, indents: 1)
|
35
|
+
raise SystemExit.new(255)
|
36
|
+
end
|
37
|
+
|
38
|
+
#TODO: a lot more errors that would could handle with nice messages, eventually this should probably be it's own class
|
39
|
+
def handle_core_error(e)
|
40
|
+
stderr.puts "Error: #{e.error_type}".red
|
41
|
+
(e.response.body["errors"] || [e.message]).each do |message|
|
42
|
+
stderr.puts Wrapomatic.wrap(message, indents: 1)
|
43
|
+
end
|
44
|
+
if e.is_a?(Ey::Core::Response::Unauthorized)
|
45
|
+
stderr.puts "Check the contents of ~/.ey-core vs https://cloud.engineyard.com/cli"
|
46
|
+
end
|
47
|
+
raise SystemExit.new(255)
|
48
|
+
end
|
100
49
|
|
101
|
-
actor = options[:environment].is_a?(Ey::Core::Client::Environment) ? options[:environment].account : operator(options)
|
102
|
-
|
103
|
-
if app.is_a?(Integer)
|
104
|
-
actor.applications.get(app)
|
105
|
-
else
|
106
|
-
applications = actor.applications.all(name: app)
|
107
|
-
if applications.count == 1
|
108
|
-
applications.first
|
109
|
-
else
|
110
|
-
raise Ey::Core::Cli::AmbiguousSearch.new("Found multiple applications that matched that search. Please be more specific by specifying the account, environment, and application name.")
|
111
50
|
end
|
112
51
|
end
|
113
52
|
end
|
@@ -1,28 +1,58 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
1
|
+
require 'ey-core/cli/subcommand'
|
2
|
+
|
3
|
+
module Ey
|
4
|
+
module Core
|
5
|
+
module Cli
|
6
|
+
class TimeoutDeploy < Subcommand
|
7
|
+
title "timeout-deploy"
|
8
|
+
summary "Fail a stuck unfinished deployment"
|
9
|
+
description <<-DESC
|
10
|
+
NOTICE: Timing out a deploy does not stop currently running deploy
|
11
|
+
processes.
|
12
|
+
|
13
|
+
The latest running deployment will be marked as failed, allowing a
|
14
|
+
new deployment to be run. It is possible to mark a potentially successful
|
15
|
+
deployment as failed. Only run this when a deployment is known to be
|
16
|
+
wrongly unfinished/stuck and when further deployments are blocked.
|
17
|
+
DESC
|
18
|
+
|
19
|
+
option :environment,
|
20
|
+
short: "e",
|
21
|
+
long: "environment",
|
22
|
+
description: "Name or id of the environment to deploy to.",
|
23
|
+
argument: "Environment"
|
24
|
+
|
25
|
+
option :account,
|
26
|
+
short: 'c',
|
27
|
+
long: 'account',
|
28
|
+
description: 'Name or ID of the account that the environment resides in. If no account is specified, the app will deploy to the first environment that meets the criteria, in the accounts you have access to.',
|
29
|
+
argument: 'Account name or id'
|
30
|
+
|
31
|
+
option :app,
|
32
|
+
short: "a",
|
33
|
+
long: "app",
|
34
|
+
description: "Application name or ID to deploy. If :account is not specified, this will be the first app that matches the criteria in the accounts you have access to.",
|
35
|
+
argument: "app"
|
36
|
+
|
37
|
+
option :message,
|
38
|
+
short: "m",
|
39
|
+
long: "message",
|
40
|
+
description: "Custom message for why the deploy is timed out",
|
41
|
+
argument: "message"
|
42
|
+
|
43
|
+
def handle
|
44
|
+
operator, environment = core_operator_and_environment_for(self.options)
|
45
|
+
app = core_application_for(environment, options)
|
46
|
+
deployment = core_client.
|
47
|
+
deployments.
|
48
|
+
first(environment_id: environment.id, application_id: app.id)
|
49
|
+
|
50
|
+
puts "Timing out the most recent deployment (deploy started at: #{deployment.started_at})".green
|
51
|
+
|
52
|
+
deployment.timeout(option(:message))
|
53
|
+
ap deployment
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
27
57
|
end
|
28
58
|
end
|
data/lib/ey-core/cli/version.rb
CHANGED
@@ -1,8 +1,16 @@
|
|
1
|
-
|
2
|
-
title "version"
|
3
|
-
summary "Print the version of the gem"
|
1
|
+
require 'ey-core/cli/subcommand'
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
module Ey
|
4
|
+
module Core
|
5
|
+
module Cli
|
6
|
+
class Version < Subcommand
|
7
|
+
title "version"
|
8
|
+
summary "Print the version of the gem"
|
9
|
+
|
10
|
+
def handle
|
11
|
+
puts Ey::Core::VERSION
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
7
15
|
end
|
8
16
|
end
|
data/lib/ey-core/cli/web.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
|
2
|
-
title "web"
|
3
|
-
summary "Web related commands"
|
1
|
+
require 'ey-core/cli/web/main'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module Ey
|
4
|
+
module Core
|
5
|
+
module Cli
|
6
|
+
module Web
|
7
|
+
end
|
8
|
+
end
|
9
9
|
end
|
10
10
|
end
|
@@ -1,23 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
1
|
+
require 'ey-core/cli/subcommand'
|
2
|
+
|
3
|
+
module Ey
|
4
|
+
module Core
|
5
|
+
module Cli
|
6
|
+
module Web
|
7
|
+
class Disable < Ey::Core::Cli::Subcommand
|
8
|
+
title "disable"
|
9
|
+
summary "Put up the maintenance page for this application in the given environment."
|
10
|
+
|
11
|
+
option :app,
|
12
|
+
short: "a",
|
13
|
+
long: "app",
|
14
|
+
description: "Name or id of the application whose maintenance page will be put up",
|
15
|
+
argument: "app"
|
16
|
+
|
17
|
+
option :environment,
|
18
|
+
short: "e",
|
19
|
+
long: "environment",
|
20
|
+
description: "Name or id of the environment to deploy to.",
|
21
|
+
argument: "Environment"
|
22
|
+
|
23
|
+
option :account,
|
24
|
+
short: 'c',
|
25
|
+
long: 'account',
|
26
|
+
description: 'Name or ID of the account that the environment resides in.',
|
27
|
+
argument: 'Account name or id'
|
28
|
+
|
29
|
+
def handle
|
30
|
+
operator, environment = core_operator_and_environment_for(self.options)
|
31
|
+
application = core_application_for(environment, self.options)
|
32
|
+
|
33
|
+
puts "Enabling maintenance page for #{application.name} on #{environment.name}".green
|
34
|
+
|
35
|
+
request = environment.maintenance(application, "enable")
|
36
|
+
request.wait_for { |r| r.ready? }
|
37
|
+
|
38
|
+
if request.successful
|
39
|
+
puts "Successfully put up maintenance page".green
|
40
|
+
else
|
41
|
+
puts "Enabling maintenance mode was not successful".red
|
42
|
+
ap request
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
21
47
|
end
|
22
48
|
end
|
23
49
|
end
|
@@ -1,23 +1,46 @@
|
|
1
|
-
|
2
|
-
title "enable"
|
3
|
-
summary "Remove the maintenance page for this application in the given environment."
|
1
|
+
require 'ey-core/cli/subcommand'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module Ey
|
4
|
+
module Core
|
5
|
+
module Cli
|
6
|
+
module Web
|
7
|
+
class Enable < Ey::Core::Cli::Subcommand
|
8
|
+
title "enable"
|
9
|
+
summary "Remove the maintenance page for this application in the given environment."
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
option :app,
|
12
|
+
short: "a",
|
13
|
+
long: "app",
|
14
|
+
description: "Name or id of the application whose maintenance page will be removed",
|
15
|
+
argument: "app"
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
option :environment,
|
18
|
+
short: "e",
|
19
|
+
long: "environment",
|
20
|
+
description: "Name or id of the environment to deploy to.",
|
21
|
+
argument: "Environment"
|
22
|
+
|
23
|
+
option :account,
|
24
|
+
short: 'c',
|
25
|
+
long: 'account',
|
26
|
+
description: 'Name or ID of the account that the environment resides in.',
|
27
|
+
argument: 'account'
|
28
|
+
|
29
|
+
def handle
|
30
|
+
operator, environment = core_operator_and_environment_for(self.options)
|
31
|
+
application = core_application_for(environment, options)
|
32
|
+
puts "Disabling maintenance for #{application.name} on #{environment.name}".green
|
33
|
+
request = environment.maintenance(application, "disable")
|
34
|
+
request.wait_for { |r| r.ready? }
|
35
|
+
if request.successful
|
36
|
+
puts "Successfully disabled maintenance page".green
|
37
|
+
else
|
38
|
+
puts "Disabling maintenance mode was not successful".red
|
39
|
+
ap request
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
21
44
|
end
|
22
45
|
end
|
23
46
|
end
|