ey-core 3.1.2 → 3.1.3

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.
Files changed (63) hide show
  1. data/.ruby-version +1 -1
  2. data/.travis.yml +1 -0
  3. data/Gemfile +0 -2
  4. data/examples/add_instance.rb +74 -0
  5. data/examples/boot_env.rb +60 -0
  6. data/examples/stop_env.rb +51 -0
  7. data/examples/terminate_instance.rb +58 -0
  8. data/lib/ey-core/cli/accounts.rb +14 -6
  9. data/lib/ey-core/cli/applications.rb +32 -12
  10. data/lib/ey-core/cli/console.rb +24 -10
  11. data/lib/ey-core/cli/current_user.rb +13 -5
  12. data/lib/ey-core/cli/deploy.rb +110 -52
  13. data/lib/ey-core/cli/environments.rb +34 -12
  14. data/lib/ey-core/cli/errors.rb +10 -6
  15. data/lib/ey-core/cli/help.rb +30 -0
  16. data/lib/ey-core/cli/helpers/archive.rb +70 -0
  17. data/lib/ey-core/cli/helpers/chef.rb +35 -0
  18. data/lib/ey-core/cli/helpers/core.rb +195 -0
  19. data/lib/ey-core/cli/helpers/deprecated.rb +39 -0
  20. data/lib/ey-core/cli/helpers/log_streaming.rb +41 -0
  21. data/lib/ey-core/cli/helpers/stream_printer.rb +42 -0
  22. data/lib/ey-core/cli/init.rb +11 -8
  23. data/lib/ey-core/cli/login.rb +33 -21
  24. data/lib/ey-core/cli/logout.rb +18 -10
  25. data/lib/ey-core/cli/logs.rb +57 -35
  26. data/lib/ey-core/cli/main.rb +52 -15
  27. data/lib/ey-core/cli/recipes.rb +5 -87
  28. data/lib/ey-core/cli/recipes/apply.rb +83 -43
  29. data/lib/ey-core/cli/recipes/download.rb +48 -22
  30. data/lib/ey-core/cli/recipes/main.rb +21 -0
  31. data/lib/ey-core/cli/recipes/upload.rb +56 -23
  32. data/lib/ey-core/cli/scp.rb +11 -8
  33. data/lib/ey-core/cli/servers.rb +37 -15
  34. data/lib/ey-core/cli/ssh.rb +127 -70
  35. data/lib/ey-core/cli/status.rb +54 -14
  36. data/lib/ey-core/cli/subcommand.rb +47 -108
  37. data/lib/ey-core/cli/timeout_deploy.rb +56 -26
  38. data/lib/ey-core/cli/version.rb +13 -5
  39. data/lib/ey-core/cli/web.rb +7 -7
  40. data/lib/ey-core/cli/web/disable.rb +46 -20
  41. data/lib/ey-core/cli/web/enable.rb +40 -17
  42. data/lib/ey-core/cli/web/main.rb +21 -0
  43. data/lib/ey-core/cli/web/restart.rb +34 -15
  44. data/lib/ey-core/cli/whoami.rb +11 -3
  45. data/lib/ey-core/mock/searching.rb +4 -0
  46. data/lib/ey-core/model.rb +5 -0
  47. data/lib/ey-core/models/deployment.rb +7 -0
  48. data/lib/ey-core/models/environment.rb +5 -0
  49. data/lib/ey-core/models/request.rb +2 -0
  50. data/lib/ey-core/models/user.rb +2 -0
  51. data/lib/ey-core/requests/get_servers.rb +1 -1
  52. data/lib/ey-core/response.rb +4 -0
  53. data/lib/ey-core/subscribable.rb +3 -3
  54. data/lib/ey-core/version.rb +1 -1
  55. data/spec/ey-core/cli/accounts_spec.rb +20 -0
  56. data/spec/ey-core/cli/recipes/apply_spec.rb +4 -17
  57. data/spec/ey-core/cli/recipes/download_spec.rb +93 -0
  58. data/spec/ey-core/cli/recipes/upload_spec.rb +80 -0
  59. data/spec/servers_spec.rb +15 -0
  60. data/spec/spec_helper.rb +7 -0
  61. data/spec/support/cli_helpers.rb +38 -2
  62. metadata +116 -53
  63. checksums.yaml +0 -7
@@ -1,26 +1,52 @@
1
- class Ey::Core::Cli::Recipes::Download < Ey::Core::Cli::Recipes
2
- title "download"
3
- summary "Download a copy of the custom chef recipes from this environment into the current directory"
4
- description <<-DESC
5
- The recipes will be unpacked into a directory called "cookbooks" in the
6
- current directory. This is the opposite of 'recipes upload'.
7
-
8
- If the cookbooks directory already exists, an error will be raised.
9
- DESC
10
-
11
- option :environment, short: "e", long: "environment", description: "Environment that will receive the recipes.", argument: "environment"
12
- option :account, short: "c", long: "account", description: "Name of the account in which the environment can be found.", argument: "account"
13
-
14
- def handle
15
- if File.exist?("cookbooks")
16
- raise Ey::Core::Clie::RecipesExist.new("Cannot download recipes, cookbooks directory already exists.")
17
- end
1
+ require 'ey-core/cli/subcommand'
2
+ require 'ey-core/cli/helpers/archive'
3
+
4
+ module Ey
5
+ module Core
6
+ module Cli
7
+ module Recipes
8
+ class Download < Ey::Core::Cli::Subcommand
9
+ include Ey::Core::Cli::Helpers::Archive
10
+
11
+ title "download"
12
+ summary "Download a copy of the custom chef recipes from this environment into the current directory"
13
+
14
+ description <<-DESC
15
+ The recipes will be unpacked into a directory called "cookbooks" in the
16
+ current directory. This is the opposite of 'recipes upload'.
17
+
18
+ If the cookbooks directory already exists, an error will be raised.
19
+ DESC
18
20
 
19
- operator, environment = core_operator_and_environment_for(options)
20
- puts "Downloading recipes".green
21
- recipes = environment.download_recipes
21
+ option :environment,
22
+ short: "e",
23
+ long: "environment",
24
+ description: "Environment that will receive the recipes.",
25
+ argument: "environment"
22
26
 
23
- puts "Extracting recipes to 'cookbooks/'".green
24
- untar(ungzip(recipes), './')
27
+ option :account,
28
+ short: "c",
29
+ long: "account",
30
+ description: "Name of the account in which the environment can be found.",
31
+ argument: "account"
32
+
33
+ def handle
34
+ if File.exist?("cookbooks")
35
+ raise Ey::Core::Cli::RecipesExist.new(
36
+ "Cannot download recipes, cookbooks directory already exists."
37
+ )
38
+ end
39
+
40
+ operator, environment = core_operator_and_environment_for(options)
41
+
42
+ puts "Downloading recipes".green
43
+ recipes = environment.download_recipes
44
+
45
+ puts "Extracting recipes to 'cookbooks/'".green
46
+ untar(ungzip(recipes), './')
47
+ end
48
+ end
49
+ end
50
+ end
25
51
  end
26
52
  end
@@ -0,0 +1,21 @@
1
+ require 'ey-core/cli/subcommand'
2
+ require 'ey-core/cli/recipes/apply'
3
+ require 'ey-core/cli/recipes/download'
4
+ require 'ey-core/cli/recipes/upload'
5
+
6
+ module Ey
7
+ module Core
8
+ module Cli
9
+ module Recipes
10
+ class Main < Ey::Core::Cli::Subcommand
11
+ title "recipes"
12
+ summary "Chef specific commands"
13
+
14
+ mount Ey::Core::Cli::Recipes::Apply
15
+ mount Ey::Core::Cli::Recipes::Download
16
+ mount Ey::Core::Cli::Recipes::Upload
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,27 +1,60 @@
1
- class Ey::Core::Cli::Recipes::Upload < Ey::Core::Cli::Recipes
2
- title "upload"
3
- summary "Upload custom recipes to an environment"
4
- option :environment, short: "e", long: "environment", description: "Environment that will receive the recipes.", argument: "environment"
5
- option :account, short: "c", long: "account", description: "Name of the account in which the environment can be found.", argument: "account"
6
- option :file, short: "f", long: "file", description: "Path to recipes", argument: "path"
7
-
8
- switch :apply, short: "a", long: "apply", description: "Apply the recipes immediately after they are uploaded"
9
-
10
- def handle
11
- operator, environment = core_operator_and_environment_for(options)
12
- path = option(:file) || "cookbooks/"
13
-
14
- puts "Uploading custom recipes for #{environment.name}".green
15
- begin
16
- upload_recipes(environment, path)
17
- puts "Uploading custom recipes complete".green
18
- rescue => e
19
- abort "There was a problem uploading the recipes".red
20
- puts e.inspect
21
- end
1
+ require 'ey-core/cli/subcommand'
2
+ require 'ey-core/cli/helpers/chef'
3
+ require 'ey-core/cli/helpers/archive'
4
+
5
+ module Ey
6
+ module Core
7
+ module Cli
8
+ module Recipes
9
+ class Upload < Ey::Core::Cli::Subcommand
10
+ include Ey::Core::Cli::Helpers::Archive
11
+ include Ey::Core::Cli::Helpers::Chef
12
+
13
+ title "upload"
14
+ summary "Upload custom recipes to an environment"
15
+
16
+ option :environment,
17
+ short: "e",
18
+ long: "environment",
19
+ description: "Environment that will receive the recipes.",
20
+ argument: "environment"
21
+
22
+ option :account,
23
+ short: "c",
24
+ long: "account",
25
+ description: "Name of the account in which the environment can be found.",
26
+ argument: "account"
27
+
28
+ option :file,
29
+ short: "f",
30
+ long: "file",
31
+ description: "Path to recipes",
32
+ argument: "path"
33
+
34
+ switch :apply,
35
+ short: "a",
36
+ long: "apply",
37
+ description: "Apply the recipes immediately after they are uploaded"
38
+
39
+ def handle
40
+ operator, environment = core_operator_and_environment_for(options)
41
+ path = option(:file) || "cookbooks/"
42
+
43
+ puts "Uploading custom recipes for #{environment.name}".green
44
+
45
+ begin
46
+ upload_recipes(environment, path)
47
+ puts "Uploading custom recipes complete".green
48
+ rescue => e
49
+ abort "There was a problem uploading the recipes".red
50
+ end
22
51
 
23
- if switch_active?(:apply)
24
- run_chef("custom", environment)
52
+ if switch_active?(:apply)
53
+ run_chef("custom", environment)
54
+ end
55
+ end
56
+ end
57
+ end
25
58
  end
26
59
  end
27
60
  end
@@ -1,11 +1,14 @@
1
- class Ey::Core::Cli::Scp < Ey::Core::Cli::Subcommand
2
- title "scp"
3
- summary "This command is deprecated"
4
- description <<-DESC
5
- The scp command has been deprecated. We apologize for any inconvenience.
6
- DESC
1
+ require 'ey-core/cli/subcommand'
2
+ require 'ey-core/cli/helpers/deprecated'
7
3
 
8
- def handle
9
- abort "This command is deprecated".red
4
+ module Ey
5
+ module Core
6
+ module Cli
7
+ class Scp < Subcommand
8
+ include Helpers::Deprecated
9
+
10
+ deprecate('scp')
11
+ end
12
+ end
10
13
  end
11
14
  end
@@ -1,19 +1,41 @@
1
- class Ey::Core::Cli::Servers < Ey::Core::Cli::Subcommand
2
- title "servers"
3
- summary "List servers you have access to"
4
- option :account, short: 'c', long: 'account', description: 'Filter by account name or id', argument: 'Account'
5
- option :environment, short: "-e", long: "environment", description: "Filter by environment.", argument: "environment"
1
+ require 'ey-core/cli/subcommand'
6
2
 
7
- def handle
8
- servers = if option(:account)
9
- account = core_account_for(options)
10
- core_client.servers.all(account: account)
11
- elsif environment = option(:environment)
12
- (core_client.environments.get(environment) || core_client.environments.first(name: environment)).servers.all
13
- else
14
- core_client.servers.all
15
- end
3
+ module Ey
4
+ module Core
5
+ module Cli
6
+ class Servers < Subcommand
7
+ title "servers"
8
+ summary "List servers you have access to"
16
9
 
17
- puts TablePrint::Printer.new(servers, [{id: {width: 10}}, :role, :provisioned_id]).table_print
10
+ option :account,
11
+ short: 'c',
12
+ long: 'account',
13
+ description: 'Filter by account name or id',
14
+ argument: 'Account'
15
+
16
+ option :environment,
17
+ short: "-e",
18
+ long: "environment",
19
+ description: "Filter by environment.",
20
+ argument: "environment"
21
+
22
+ def handle
23
+ puts TablePrint::Printer.
24
+ new(servers, [{id: {width: 10}}, :role, :provisioned_id]).
25
+ table_print
26
+ end
27
+
28
+ private
29
+ def servers
30
+ if option(:account)
31
+ core_client.servers.all(account: core_account)
32
+ elsif environment = option(:environment)
33
+ (core_client.environments.get(environment) || core_client.environments.first(name: environment)).servers.all
34
+ else
35
+ core_client.servers.all
36
+ end
37
+ end
38
+ end
39
+ end
18
40
  end
19
41
  end
@@ -1,81 +1,138 @@
1
1
  require 'ey-core/cli/helpers/server_sieve'
2
+ require 'ey-core/cli/subcommand'
2
3
 
3
- class Ey::Core::Cli::Ssh < Ey::Core::Cli::Subcommand
4
- title "ssh"
5
- summary "Open an SSH session to the environment's application master"
6
- option :account, short: "c", long: "account", description: "Name or id of account", argument: "account"
7
- option :environment, short: "e", long: "environment", description: "Name or id of environment", argument: "environment"
8
- option :server, short: 's', long: "server", description: "Specific server to ssh into. Id or amazon id (i-12345)", argument: "server"
9
- option :utilities, long: "utilities", description: "Run command on the utility servers with the given names. Specify all to run the command on all utility servers.", argument: "'all,resque,redis,etc'"
10
- option :command, long: "command", description: "Command to run", argument: "'command with args'"
11
- option :shell, short: 's', long: "shell", description: "Run command in a shell other than bash", argument: "shell"
12
- option :bind_address, long: "bind_address", description: "When no command is specified, pass -L to ssh", argument: "bind address"
13
-
14
- switch :all, long: "all", description: "Run command on all servers"
15
- switch :app_servers, long: "app_servers", description: "Run command on all application servers"
16
- switch :db_servers, long: "db_servers", description: "Run command on all database servers"
17
- switch :db_master, long: "db_master", description: "Run command on database master"
18
- switch :db_slaves, long: "db_slaves", description: "Run command on database slaves"
19
- switch :tty, short: 't', long: "tty", description: "Allocated a tty for the command"
20
-
21
- def handle
22
- operator, environment = core_operator_and_environment_for(options)
23
- abort "Unable to find matching environment".red unless environment
24
-
25
- cmd = option(:command)
26
- ssh_opts = []
27
- ssh_cmd = ["ssh"]
28
- exits = []
29
- user = environment.username
30
- servers = []
31
-
32
- if option(:command)
33
- if shell = option(:shell)
34
- cmd = Escape.shell_command([shell,'-lc',cmd])
35
- end
4
+ module Ey
5
+ module Core
6
+ module Cli
7
+ class Ssh < Subcommand
8
+ title "ssh"
9
+ summary "Open an SSH session to the environment's application master"
36
10
 
37
- if switch_active?(:tty)
38
- ssh_opts << "-t"
39
- elsif cmd.match(/sudo/)
40
- puts "sudo commands often need a tty to run correctly. Use -t option to spawn a tty.".yellow
41
- end
11
+ option :account,
12
+ short: "c",
13
+ long: "account",
14
+ description: "Name or id of account",
15
+ argument: "account"
42
16
 
43
- servers += Ey::Core::Cli::Helpers::ServerSieve.filter(
44
- environment.servers,
45
- all: switch_active?(:all),
46
- app_servers: switch_active?(:app_servers),
47
- db_servers: switch_active?(:db_servers),
48
- db_master: switch_active?(:db_master),
49
- utilities: option(:utilities)
50
- )
51
- else
52
- if option(:bind_address)
53
- ssh_opts += ["-L", option(:bind_address)]
54
- end
17
+ option :environment,
18
+ short: "e",
19
+ long: "environment",
20
+ description: "Name or id of environment",
21
+ argument: "environment"
55
22
 
56
- if option(:server)
57
- servers += [core_server_for(server: option[:server], operator: environment)]
58
- else
59
- servers += (environment.servers.all(role: "app_master") + environment.servers.all(role: "solo")).to_a
60
- end
61
- end
23
+ option :server,
24
+ short: 's',
25
+ long: "server",
26
+ description: "Specific server to ssh into. Id or amazon id (i-12345)",
27
+ argument: "server"
62
28
 
63
- if servers.empty?
64
- abort "Unable to find any matching servers. Aborting.".red
65
- end
29
+ option :utilities,
30
+ long: "utilities",
31
+ description: "Run command on the utility servers with the given names. Specify all to run the command on all utility servers.",
32
+ argument: "'all,resque,redis,etc'"
66
33
 
67
- servers.uniq!
34
+ option :command,
35
+ long: "command",
36
+ description: "Command to run",
37
+ argument: "'command with args'"
68
38
 
69
- servers.each do |server|
70
- host = server.public_hostname
71
- name = server.name ? "#{server.role} (#{server.name})" : server.role
72
- puts "\nConnecting to #{name} #{host}".green
73
- sshcmd = Escape.shell_command((ssh_cmd + ["#{user}@#{host}"] + [cmd]).compact)
74
- puts "Running command: #{sshcmd}".green
75
- system sshcmd
76
- exits << $?.exitstatus
77
- end
39
+ option :shell,
40
+ short: 's',
41
+ long: "shell",
42
+ description: "Run command in a shell other than bash",
43
+ argument: "shell"
44
+
45
+ option :bind_address,
46
+ long: "bind_address",
47
+ description: "When no command is specified, pass -L to ssh",
48
+ argument: "bind address"
49
+
50
+ switch :all,
51
+ long: "all",
52
+ description: "Run command on all servers"
53
+
54
+ switch :app_servers,
55
+ long: "app_servers",
56
+ description: "Run command on all application servers"
57
+
58
+ switch :db_servers,
59
+ long: "db_servers",
60
+ description: "Run command on all database servers"
61
+
62
+ switch :db_master,
63
+ long: "db_master",
64
+ description: "Run command on database master"
65
+
66
+ switch :db_slaves,
67
+ long: "db_slaves",
68
+ description: "Run command on database slaves"
78
69
 
79
- exit exits.detect {|status| status != 0 } || 0
70
+ switch :tty,
71
+ short: 't',
72
+ long: "tty",
73
+ description: "Allocated a tty for the command"
74
+
75
+ def handle
76
+ operator, environment = core_operator_and_environment_for(options)
77
+ abort "Unable to find matching environment".red unless environment
78
+
79
+ cmd = option(:command)
80
+ ssh_opts = []
81
+ ssh_cmd = ["ssh"]
82
+ exits = []
83
+ user = environment.username
84
+ servers = []
85
+
86
+ if option(:command)
87
+ if shell = option(:shell)
88
+ cmd = Escape.shell_command([shell,'-lc',cmd])
89
+ end
90
+
91
+ if switch_active?(:tty)
92
+ ssh_opts << "-t"
93
+ elsif cmd.match(/sudo/)
94
+ puts "sudo commands often need a tty to run correctly. Use -t option to spawn a tty.".yellow
95
+ end
96
+
97
+ servers += Ey::Core::Cli::Helpers::ServerSieve.filter(
98
+ environment.servers,
99
+ all: switch_active?(:all),
100
+ app_servers: switch_active?(:app_servers),
101
+ db_servers: switch_active?(:db_servers),
102
+ db_master: switch_active?(:db_master),
103
+ utilities: option(:utilities)
104
+ )
105
+ else
106
+ if option(:bind_address)
107
+ ssh_opts += ["-L", option(:bind_address)]
108
+ end
109
+
110
+ if option(:server)
111
+ servers += [core_server_for(server: option[:server], operator: environment)]
112
+ else
113
+ servers += (environment.servers.all(role: "app_master") + environment.servers.all(role: "solo")).to_a
114
+ end
115
+ end
116
+
117
+ if servers.empty?
118
+ abort "Unable to find any matching servers. Aborting.".red
119
+ end
120
+
121
+ servers.uniq!
122
+
123
+ servers.each do |server|
124
+ host = server.public_hostname
125
+ name = server.name ? "#{server.role} (#{server.name})" : server.role
126
+ puts "\nConnecting to #{name} #{host}".green
127
+ sshcmd = Escape.shell_command((ssh_cmd + ["#{user}@#{host}"] + [cmd]).compact)
128
+ puts "Running command: #{sshcmd}".green
129
+ system sshcmd
130
+ exits << $?.exitstatus
131
+ end
132
+
133
+ exit exits.detect {|status| status != 0 } || 0
134
+ end
135
+ end
136
+ end
80
137
  end
81
138
  end