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.
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
@@ -0,0 +1,21 @@
1
+ require 'ey-core/cli/subcommand'
2
+ require 'ey-core/cli/web/disable'
3
+ require 'ey-core/cli/web/enable'
4
+ require 'ey-core/cli/web/restart'
5
+
6
+ module Ey
7
+ module Core
8
+ module Cli
9
+ module Web
10
+ class Main < Ey::Core::Cli::Subcommand
11
+ title "web"
12
+ summary "Web related commands"
13
+
14
+ mount Disable
15
+ mount Enable
16
+ mount Restart
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,23 +1,42 @@
1
- class Ey::Core::Cli::Web::Restart < Ey::Core::Cli::Web
2
- title "restart"
3
- summary "Restart all application servers in an environment"
1
+ require 'ey-core/cli/subcommand'
4
2
 
5
- option :environment, short: "e", long: "environment", description: "Name or id of the environment to deploy to.", argument: "environment"
6
- option :account, short: "c", long: "account", description: "Name or id of the account that the environment resides in.", argument: "account"
3
+ module Ey
4
+ module Core
5
+ module Cli
6
+ module Web
7
+ class Restart < Ey::Core::Cli::Subcommand
8
+ title "restart"
9
+ summary "Restart all application servers in an environment"
7
10
 
8
- def handle
9
- operator, environment = core_operator_and_environment_for(options)
11
+ option :environment,
12
+ short: "e",
13
+ long: "environment",
14
+ description: "Name or id of the environment to deploy to.",
15
+ argument: "environment"
10
16
 
11
- puts "Restarting application servers in #{environment.name}".green
17
+ option :account,
18
+ short: "c",
19
+ long: "account",
20
+ description: "Name or id of the account that the environment resides in.",
21
+ argument: "account"
12
22
 
13
- request = environment.restart_app_servers
14
- request.wait_for { |r| r.ready? }
23
+ def handle
24
+ operator, environment = core_operator_and_environment_for(options)
15
25
 
16
- if request.successful
17
- puts "Successfully restarted application servers".green
18
- else
19
- puts "Restarting application servers has failed".red
20
- ap request
26
+ puts "Restarting application servers in #{environment.name}".green
27
+
28
+ request = environment.restart_app_servers
29
+ request.wait_for { |r| r.ready? }
30
+
31
+ if request.successful
32
+ puts "Successfully restarted application servers".green
33
+ else
34
+ puts "Restarting application servers has failed".red
35
+ ap request
36
+ end
37
+ end
38
+ end
39
+ end
21
40
  end
22
41
  end
23
42
  end
@@ -1,4 +1,12 @@
1
- class Ey::Core::Cli::Whoami < Ey::Core::Cli::CurrentUser
2
- title "whoami"
3
- summary "Print the current user information (alias for current_user)"
1
+ require 'ey-core/cli/current_user'
2
+
3
+ module Ey
4
+ module Core
5
+ module Cli
6
+ class Whoami < CurrentUser
7
+ title "whoami"
8
+ summary "Print the current user information (alias for current_user)"
9
+ end
10
+ end
11
+ end
4
12
  end
@@ -53,6 +53,10 @@ module Ey::Core::Mock
53
53
  def search(resources, params)
54
54
  search_params = Cistern::Hash.stringify_keys(params)
55
55
 
56
+ search_params.select { |k,v| v.respond_to?(:id) }.each do |k,v|
57
+ search_params[k] = v.id
58
+ end
59
+
56
60
  resources.select do |id, attrs|
57
61
  search_params.all? do |term, condition|
58
62
  if condition.kind_of? Array
data/lib/ey-core/model.rb CHANGED
@@ -7,6 +7,11 @@ class Ey::Core::Model < Cistern::Model
7
7
  end
8
8
  end
9
9
 
10
+ def to_s
11
+ shortname = self.class.name.split("::").last
12
+ "#{shortname}:#{id}"
13
+ end
14
+
10
15
  def self.range_parser(v)
11
16
  case v
12
17
  when Range then
@@ -11,12 +11,19 @@ class Ey::Core::Client::Deployment < Ey::Core::Model
11
11
  attribute :resolved_ref
12
12
  attribute :started_at, type: :time
13
13
  attribute :successful, type: :boolean
14
+ attribute :verbose
15
+ attribute :streaming
16
+ attribute :request_url, aliases: :request
14
17
 
15
18
  has_one :account
16
19
  has_one :environment
17
20
  has_one :application
18
21
  has_one :user
19
22
 
23
+ def request
24
+ self.request_url && self.connection.requests.get(self.request_url.split("/").last)
25
+ end
26
+
20
27
  def timeout(message=nil)
21
28
  merge_attributes(self.connection.timeout_deployment("id" => self.id, "message" => message).body["deployment"])
22
29
  end
@@ -31,6 +31,11 @@ class Ey::Core::Client::Environment < Ey::Core::Model
31
31
 
32
32
  attr_accessor :application_id
33
33
 
34
+ def latest_deploy(app)
35
+ deployments = connection.deployments.all(environment_id: self.id, application_id: app.id)
36
+ deployments.first
37
+ end
38
+
34
39
  # @param application [Ey::Core::Client::Application]
35
40
  # @option opts [Ey::Core::Client::ApplicationArchive] :archive
36
41
  def deploy(application, opts={})
@@ -65,6 +65,8 @@ class Ey::Core::Client::Request < Ey::Core::Model
65
65
  self.connection.database_servers.get!(resource_id)
66
66
  when /database_service/
67
67
  self.connection.database_services.get!(resource_id)
68
+ when /deployment/
69
+ self.connection.deployments.get!(resource_id)
68
70
  when /firewall(?!_rule)/
69
71
  self.connection.firewalls.get!(resource_id)
70
72
  when /firewall_rule/
@@ -9,6 +9,7 @@ class Ey::Core::Client::User < Ey::Core::Model
9
9
  attribute :deleted_at
10
10
 
11
11
  has_many :accounts
12
+ has_many :environments
12
13
  has_many :keypairs
13
14
  has_many :tokens
14
15
 
@@ -33,4 +34,5 @@ class Ey::Core::Client::User < Ey::Core::Model
33
34
  def destroy!
34
35
  self.connection.destroy_user("id" => self.id) && true
35
36
  end
37
+
36
38
  end
@@ -14,7 +14,7 @@ class Ey::Core::Client
14
14
  def get_servers(params={})
15
15
  extract_url_params!(params)
16
16
 
17
- headers, servers_page = search_and_page(params, :servers, search_keys: %w[cluster environment provider state private_hostname public_hostname provisioned_id role])
17
+ headers, servers_page = search_and_page(params, :servers, search_keys: %w[account environment provider state private_hostname public_hostname provisioned_id role])
18
18
 
19
19
  response(
20
20
  :body => {"servers" => servers_page},
@@ -13,6 +13,10 @@ class Ey::Core::Response
13
13
  }.inspect
14
14
  )
15
15
  end
16
+
17
+ def error_type
18
+ self.class.name.split(":").last
19
+ end
16
20
  end
17
21
 
18
22
  BadRequest = Class.new(Error)
@@ -30,17 +30,17 @@ module Ey::Core::Subscribable
30
30
  end
31
31
 
32
32
  deferred.callback do
33
- block.call({"meta" => true, "created_at" => Time.now,"message" => "successfully subscribed"})
33
+ block.call({"meta" => true, "created_at" => Time.now,"message" => "successfully connected to log streaming service\n"})
34
34
  end
35
35
 
36
36
  deferred.errback do |error|
37
- block.call({"meta" => true, "created_at" => Time.now, "message" => "subscription failed: #{error.inspect}"})
37
+ block.call({"meta" => true, "created_at" => Time.now, "message" => "failed to stream output: #{error.inspect}\n"})
38
38
  EM.stop_event_loop
39
39
  end
40
40
 
41
41
  EventMachine::PeriodicTimer.new(5) do
42
42
  if resource.reload.ready?
43
- block.call({"meta" => true, "created_at" => Time.now, "message" => "#{resource} is finished"})
43
+ block.call({"meta" => true, "created_at" => Time.now, "message" => "#{resource} finished"})
44
44
  EM.stop_event_loop
45
45
  end
46
46
  end
@@ -1,5 +1,5 @@
1
1
  module Ey
2
2
  module Core
3
- VERSION = "3.1.2"
3
+ VERSION = "3.1.3"
4
4
  end
5
5
  end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'ey-core/cli/accounts'
3
+
4
+ describe Ey::Core::Cli::Accounts do
5
+ set_up_cli
6
+
7
+ context 'ey-core recipes accounts' do
8
+ it 'lists my account ids' do
9
+ execute
10
+
11
+ expect(standard_output).to match(/#{Regexp.escape(account.id)}/)
12
+ end
13
+
14
+ it 'lists my account names' do
15
+ execute
16
+
17
+ expect(standard_output).to match(/#{Regexp.escape(account.name)}/)
18
+ end
19
+ end
20
+ end
@@ -1,20 +1,10 @@
1
1
  require 'spec_helper'
2
- require 'stringio'
3
- require 'belafonte'
4
- require 'ey-core/cli'
5
- require 'ey-core/cli/subcommand'
6
- require 'ey-core/cli/recipes'
7
2
  require 'ey-core/cli/recipes/apply'
8
3
 
9
4
  describe Ey::Core::Cli::Recipes::Apply do
10
5
  set_up_cli
11
6
 
12
7
  before(:each) do
13
- allow_any_instance_of(described_class).
14
- to receive(:core_operator_and_environment_for).
15
- with(any_args).
16
- and_return([operator, environment])
17
-
18
8
  allow_any_instance_of(described_class).
19
9
  to receive(:run_chef).
20
10
  with(any_args).
@@ -22,7 +12,7 @@ describe Ey::Core::Cli::Recipes::Apply do
22
12
  end
23
13
 
24
14
  context 'ey-core recipes apply --main' do
25
- let(:argv) {['--main']}
15
+ arguments '--main'
26
16
 
27
17
  it 'performs a main chef run' do
28
18
  expect(cli).to receive(:run_chef).with('main', environment)
@@ -33,7 +23,7 @@ describe Ey::Core::Cli::Recipes::Apply do
33
23
  end
34
24
 
35
25
  context 'ey-core recipes apply --custom' do
36
- let(:argv) {['--custom']}
26
+ arguments '--custom'
37
27
 
38
28
  it 'performs a custom chef run' do
39
29
  expect(cli).to receive(:run_chef).with('custom', environment)
@@ -44,7 +34,7 @@ describe Ey::Core::Cli::Recipes::Apply do
44
34
  end
45
35
 
46
36
  context 'ey-core recipes apply --quick' do
47
- let(:argv) {['--quick']}
37
+ arguments '--quick'
48
38
 
49
39
  it 'performs a quick chef run' do
50
40
  expect(cli).to receive(:run_chef).with('quick', environment)
@@ -55,7 +45,7 @@ describe Ey::Core::Cli::Recipes::Apply do
55
45
  end
56
46
 
57
47
  context 'ey-core recipes apply --full' do
58
- let(:argv) {['--full']}
48
+ arguments '--full'
59
49
 
60
50
  it 'performs both a main and a custom chef run' do
61
51
  expect(cli).to receive(:run_chef).with('main', environment)
@@ -82,9 +72,6 @@ describe Ey::Core::Cli::Recipes::Apply do
82
72
  attempt = described_class.new(combination, stdin, stdout, stderr, kernel)
83
73
 
84
74
  expect(attempt.execute!).not_to eql(0)
85
-
86
-
87
-
88
75
  end
89
76
  end
90
77
  end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+ require 'ey-core/cli/recipes/download'
3
+
4
+ describe Ey::Core::Cli::Recipes::Download do
5
+ set_up_cli
6
+
7
+ before(:each) do
8
+ allow_any_instance_of(described_class).
9
+ to receive(:untar).
10
+ with(any_args).
11
+ and_return(true)
12
+
13
+ allow_any_instance_of(described_class).
14
+ to receive(:ungzip).
15
+ with(any_args).
16
+ and_return(true)
17
+ end
18
+
19
+ context 'ey-core recipes download' do
20
+ context 'with an existing cookbooks directory' do
21
+ before(:each) do
22
+ allow(File).to receive(:exist?).with("cookbooks").and_return(true)
23
+ end
24
+
25
+ it 'fails out, advising that the cookbooks already exist locally' do
26
+ status = execute
27
+
28
+ expect(error_output).
29
+ to include(
30
+ 'Cannot download recipes, cookbooks directory already exists.'
31
+ )
32
+
33
+ expect(status).to eql(255)
34
+ end
35
+ end
36
+
37
+ context 'with no cookbooks directory' do
38
+ before(:each) do
39
+ allow(File).to receive(:exist?).with("cookbooks").and_return(false)
40
+
41
+ allow(environment).
42
+ to receive(:download_recipes).
43
+ and_return('cookbooks.tar.gz')
44
+
45
+ allow(cli).
46
+ to receive(:ungzip)
47
+
48
+ allow(cli).
49
+ to receive(:untar)
50
+ end
51
+
52
+ it 'advises that the cookbooks are being downloaded' do
53
+ execute
54
+
55
+ expect(standard_output).to include('Downloading recipes'.green)
56
+ end
57
+
58
+ it 'downloads the cookbooks archive' do
59
+ expect(environment).
60
+ to receive(:download_recipes).
61
+ and_call_original
62
+
63
+ execute
64
+ end
65
+
66
+ it 'advises that the downloaded archive is being extracted' do
67
+ execute
68
+
69
+ expect(standard_output).
70
+ to match(/Extracting recipes to 'cookbooks\/'/)
71
+ end
72
+
73
+ it 'unarchives the downloaded archive' do
74
+ allow(environment).to receive(:download_recipes).and_return('cookbooks.tar.gz')
75
+ expect(cli).
76
+ to receive(:ungzip).
77
+ with('cookbooks.tar.gz').
78
+ and_return('cookbooks.tar')
79
+
80
+ expect(cli).
81
+ to receive(:untar).
82
+ with('cookbooks.tar', './').
83
+ and_return(true)
84
+
85
+ execute
86
+ end
87
+
88
+ it 'exits cleanly' do
89
+ expect(execute).to eql(0)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'ey-core/cli/recipes/upload'
3
+
4
+ describe Ey::Core::Cli::Recipes::Upload do
5
+ set_up_cli
6
+
7
+ before(:each) do
8
+ allow_any_instance_of(described_class).
9
+ to receive(:run_chef).
10
+ with(any_args).
11
+ and_return(true)
12
+
13
+ allow_any_instance_of(described_class).
14
+ to receive(:upload_recipes).
15
+ with(any_args).
16
+ and_return(true)
17
+ end
18
+
19
+ context 'ey-core recipes upload' do
20
+ it 'advises that it is uploading recipes for the current environment' do
21
+ execute
22
+
23
+ expect(standard_output).
24
+ to match(/Uploading custom recipes for /)
25
+ end
26
+
27
+ it 'uploads the recipes' do
28
+ expect(cli).to receive(:upload_recipes).with(environment, 'cookbooks/')
29
+
30
+ execute
31
+ end
32
+
33
+ context 'upon uploading successfully' do
34
+ it 'advises that the upload completed' do
35
+ execute
36
+
37
+ expect(standard_output).
38
+ to match(/Uploading custom recipes complete/)
39
+ end
40
+ end
41
+
42
+ context 'upon failing to upload' do
43
+ before(:each) do
44
+ allow(cli).
45
+ to receive(:upload_recipes).
46
+ with(environment, 'cookbooks/').
47
+ and_raise('big bada boom')
48
+ end
49
+
50
+ it 'aborts, advising that the upload failed' do
51
+ status = execute
52
+
53
+ expect(error_output).
54
+ to match(/There was a problem uploading the recipes/)
55
+
56
+ expect(status).not_to eql(0)
57
+ end
58
+ end
59
+ end
60
+
61
+ context 'ey-core recipes upload --apply' do
62
+ arguments '--apply'
63
+
64
+ it 'performs a custom chef run' do
65
+ expect(cli).to receive(:run_chef).with('custom', environment)
66
+
67
+ execute
68
+ end
69
+ end
70
+
71
+ context 'ey-core recipes upload --path /some/path' do
72
+ arguments '--file /some/path'
73
+
74
+ it 'uploads the recipes from the given path' do
75
+ expect(cli).to receive(:upload_recipes).with(environment, '/some/path')
76
+
77
+ execute
78
+ end
79
+ end
80
+ end