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
@@ -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