aptible-cli 0.5.15 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4a414273ca1b43ed9ba77b0d60edf901a10f984
4
- data.tar.gz: a792785c97710d096c958c89cac6cfa78b5da496
3
+ metadata.gz: 0e6d976b32bef3e1b4b34c49be4d7bfc524aa908
4
+ data.tar.gz: b53c2136b9de6bd7f09b87950bdf214f58adfffd
5
5
  SHA512:
6
- metadata.gz: d9b2f63dd6958f2fbdf26aea08d8ceb07a868eb3a67cb86c507293c008cfda491fa70689d63ca294827fd236907f1cba0864c2203612d9a1af87c5b6fdde3d52
7
- data.tar.gz: 3fe1e96e66fdb052f0a3de8bf99b85237a8a75e79a548d416be3dffd58f63c7b45556b7f0d2ac74c7dd923c11d0e37431b8ca8df65b345ee48e72e7395d27428
6
+ metadata.gz: a7300533f684f475ad4e981d9b9534758ec666c1a57c83a4e605da5fe06286f03877b589303a7027b854fcf6470d1b76ba8cb987f0c4bf1423171abfa2f117db
7
+ data.tar.gz: 4b6a7f6c26295bdbacdf9093113e32431a9c9ef73bbec8f2017996a89d0955a0c405305dfeec6e418181b96f326cb68551be16ed24b2b68ef83d8c3c7f268488
@@ -4,7 +4,7 @@ require 'json'
4
4
 
5
5
  require_relative 'helpers/token'
6
6
  require_relative 'helpers/operation'
7
- require_relative 'helpers/account'
7
+ require_relative 'helpers/environment'
8
8
  require_relative 'helpers/app'
9
9
  require_relative 'helpers/env'
10
10
 
@@ -6,19 +6,38 @@ module Aptible
6
6
  module Helpers
7
7
  module App
8
8
  include Helpers::Token
9
+ include Helpers::Environment
10
+
11
+ class HandleFromGitRemote
12
+ PATTERN = %r{
13
+ :((?<environment_handle>[0-9a-z\-_\.]+?)/)?(?<app_handle>[0-9a-z\-_\.]+)\.git
14
+ \z
15
+ }x
16
+
17
+ def self.parse(url)
18
+ PATTERN.match(url)
19
+ end
20
+ end
9
21
 
10
22
  def ensure_app(options = {})
11
23
  remote = options[:remote] || ENV['APTIBLE_REMOTE']
12
- handle = options[:app] ||
13
- handle_from_remote(remote) ||
14
- ensure_default_handle
15
- app = app_from_handle(handle)
24
+ handle = options[:app]
25
+ if handle
26
+ environment = ensure_environment(options)
27
+ else
28
+ handles = handle_from_remote(remote) || ensure_default_handle
29
+ handle = handles[:app_handle]
30
+ env_handle = handles[:environment_handle] || options[:environment]
31
+ environment = ensure_environment(environment: env_handle)
32
+ end
33
+
34
+ app = app_from_handle(handle, environment)
16
35
  return app if app
17
36
  fail Thor::Error, "Could not find app #{handle}"
18
37
  end
19
38
 
20
- def app_from_handle(handle)
21
- Aptible::Api::App.all(token: fetch_token).find do |a|
39
+ def app_from_handle(handle, environment)
40
+ environment.apps.find do |a|
22
41
  a.handle == handle
23
42
  end
24
43
  end
@@ -38,7 +57,7 @@ module Aptible
38
57
  def handle_from_remote(remote_name)
39
58
  git = Git.open(Dir.pwd)
40
59
  aptible_remote = git.remote(remote_name).url || ''
41
- aptible_remote[/:(?<name>.+)\.git/, :name]
60
+ HandleFromGitRemote.parse(aptible_remote)
42
61
  rescue
43
62
  nil
44
63
  end
@@ -0,0 +1,49 @@
1
+ require 'aptible/api'
2
+ require 'git'
3
+
4
+ module Aptible
5
+ module CLI
6
+ module Helpers
7
+ module Environment
8
+ include Helpers::Token
9
+
10
+ def scoped_environments(options)
11
+ if options[:environment]
12
+ if (environment = environment_from_handle(options[:environment]))
13
+ [environment]
14
+ else
15
+ fail Thor::Error, 'Specified account does not exist'
16
+ end
17
+ else
18
+ Aptible::Api::Account.all(token: fetch_token)
19
+ end
20
+ end
21
+
22
+ def ensure_environment(options = {})
23
+ if (handle = options[:environment])
24
+ environment = environment_from_handle(handle)
25
+ return environment if environment
26
+ fail Thor::Error, "Could not find environment #{handle}"
27
+ else
28
+ ensure_default_environment
29
+ end
30
+ end
31
+
32
+ def environment_from_handle(handle)
33
+ Aptible::Api::Account.all(token: fetch_token).find do |a|
34
+ a.handle == handle
35
+ end
36
+ end
37
+
38
+ def ensure_default_environment
39
+ environments = Aptible::Api::Account.all(token: fetch_token)
40
+ return environments.first if environments.count == 1
41
+
42
+ fail Thor::Error, <<-ERR.gsub(/\s+/, ' ').strip
43
+ Multiple environments available, please specify with --environment
44
+ ERR
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -4,15 +4,15 @@ module Aptible
4
4
  module Apps
5
5
  def self.included(thor)
6
6
  thor.class_eval do
7
- include Helpers::Account
7
+ include Helpers::Environment
8
8
  include Helpers::Token
9
9
 
10
10
  desc 'apps', 'List all applications'
11
- option :account
11
+ option :environment
12
12
  def apps
13
- scoped_accounts(options).each do |account|
14
- say "=== #{account.handle}"
15
- account.apps.each do |app|
13
+ scoped_environments(options).each do |env|
14
+ say "=== #{env.handle}"
15
+ env.apps.each do |app|
16
16
  say app.handle
17
17
  end
18
18
  say ''
@@ -20,10 +20,10 @@ module Aptible
20
20
  end
21
21
 
22
22
  desc 'apps:create HANDLE', 'Create a new application'
23
- option :account
23
+ option :environment
24
24
  define_method 'apps:create' do |handle|
25
- account = ensure_account(options)
26
- app = account.create_app(handle: handle)
25
+ environment = ensure_environment(options)
26
+ app = environment.create_app(handle: handle)
27
27
 
28
28
  if app.errors.any?
29
29
  fail Thor::Error, app.errors.full_messages.first
@@ -34,6 +34,7 @@ module Aptible
34
34
 
35
35
  desc 'apps:scale TYPE NUMBER', 'Scale app to NUMBER of instances'
36
36
  option :app
37
+ option :environment
37
38
  define_method 'apps:scale' do |type, n|
38
39
  num = Integer(n)
39
40
  app = ensure_app(options)
@@ -43,6 +44,7 @@ module Aptible
43
44
  end
44
45
 
45
46
  option :app
47
+ option :environment
46
48
  desc 'apps:deprovision', 'Deprovision an app'
47
49
  define_method 'apps:deprovision' do
48
50
  app = ensure_app(options)
@@ -11,21 +11,21 @@ module Aptible
11
11
  include Term::ANSIColor
12
12
 
13
13
  desc 'db:list', 'List all databases'
14
- option :account
14
+ option :environment
15
15
  define_method 'db:list' do
16
- scoped_accounts(options).each do |account|
17
- present_account_databases(account)
16
+ scoped_environments(options).each do |env|
17
+ present_environment_databases(env)
18
18
  end
19
19
  end
20
20
 
21
21
  desc 'db:create HANDLE', 'Create a new database'
22
22
  option :type, default: 'postgresql'
23
23
  option :size, default: 10
24
- option :account
24
+ option :environment
25
25
  define_method 'db:create' do |handle|
26
- account = ensure_account(options)
27
- database = account.create_database(handle: handle,
28
- type: options[:type])
26
+ environment = ensure_environment(options)
27
+ database = environment.create_database(handle: handle,
28
+ type: options[:type])
29
29
 
30
30
  if database.errors.any?
31
31
  fail Thor::Error, database.errors.full_messages.first
@@ -38,28 +38,36 @@ module Aptible
38
38
  end
39
39
 
40
40
  desc 'db:clone SOURCE DEST', 'Clone a database to create a new one'
41
+ option :environment
41
42
  define_method 'db:clone' do |source_handle, dest_handle|
42
- dest = clone_database(source_handle, dest_handle)
43
+ environment = ensure_environment(options)
44
+ dest = clone_database(source_handle, dest_handle, environment)
43
45
  say dest.connection_url
44
46
  end
45
47
 
46
48
  desc 'db:dump HANDLE', 'Dump a remote database to file'
49
+ option :environment
47
50
  define_method 'db:dump' do |handle|
48
- dump_database(handle)
51
+ environment = ensure_environment(options)
52
+ dump_database(handle, environment)
49
53
  end
50
54
 
51
55
  desc 'db:execute HANDLE SQL_FILE', 'Executes sql against a database'
56
+ option :environment
52
57
  define_method 'db:execute' do |handle, sql_path|
53
- execute_local_tunnel(handle) do |url|
58
+ environment = ensure_environment(options)
59
+ execute_local_tunnel(handle, environment) do |url|
54
60
  say "Executing #{sql_path} against #{handle}"
55
61
  `psql #{url} < #{sql_path}`
56
62
  end
57
63
  end
58
64
 
59
65
  desc 'db:tunnel HANDLE', 'Create a local tunnel to a database'
66
+ option :environment
60
67
  option :port, type: :numeric
61
68
  define_method 'db:tunnel' do |handle|
62
- database = database_from_handle(handle)
69
+ environment = ensure_environment(options)
70
+ database = database_from_handle(handle, environment)
63
71
  local_port = options[:port] || random_local_port
64
72
 
65
73
  say 'Creating tunnel...', :green
@@ -77,8 +85,10 @@ module Aptible
77
85
  end
78
86
 
79
87
  desc 'db:deprovision HANDLE', 'Deprovision a database'
88
+ option :environment
80
89
  define_method 'db:deprovision' do |handle|
81
- database = database_from_handle(handle)
90
+ environment = ensure_environment(options)
91
+ database = database_from_handle(handle, environment)
82
92
  say "Deprovisioning #{handle}..."
83
93
  database.update!(status: 'deprovisioned')
84
94
  database.create_operation!(type: 'deprovision')
@@ -86,9 +96,9 @@ module Aptible
86
96
 
87
97
  private
88
98
 
89
- def present_account_databases(account)
90
- say "=== #{account.handle}"
91
- account.databases.each { |db| say db.handle }
99
+ def present_environment_databases(environment)
100
+ say "=== #{environment.handle}"
101
+ environment.databases.each { |db| say db.handle }
92
102
  say ''
93
103
  end
94
104
 
@@ -104,8 +114,10 @@ module Aptible
104
114
  Kernel.exec(command)
105
115
  end
106
116
 
107
- def database_from_handle(handle, options = { postgres_only: false })
108
- all = Aptible::Api::Database.all(token: fetch_token)
117
+ def database_from_handle(handle,
118
+ environment,
119
+ options = { postgres_only: false })
120
+ all = environment.databases
109
121
  database = all.find { |a| a.handle == handle }
110
122
 
111
123
  unless database
@@ -119,16 +131,16 @@ module Aptible
119
131
  database
120
132
  end
121
133
 
122
- def clone_database(source_handle, dest_handle)
123
- source = database_from_handle(source_handle)
134
+ def clone_database(source_handle, dest_handle, environment)
135
+ source = database_from_handle(source_handle, environment)
124
136
  op = source.create_operation(type: 'clone', handle: dest_handle)
125
137
  poll_for_success(op)
126
138
 
127
139
  database_from_handle(dest_handle)
128
140
  end
129
141
 
130
- def dump_database(handle)
131
- execute_local_tunnel(handle) do |url|
142
+ def dump_database(handle, environment)
143
+ execute_local_tunnel(handle, environment) do |url|
132
144
  filename = "#{handle}.dump"
133
145
  say "Dumping to #{filename}"
134
146
  `pg_dump #{url} > #{filename}`
@@ -137,8 +149,10 @@ module Aptible
137
149
 
138
150
  # Creates a local tunnel and yields the url to it
139
151
 
140
- def execute_local_tunnel(handle)
141
- database = database_from_handle(handle, postgres_only: true)
152
+ def execute_local_tunnel(handle, environment)
153
+ database = database_from_handle(handle,
154
+ environment,
155
+ postgres_only: true)
142
156
 
143
157
  local_port = random_local_port
144
158
  pid = fork { establish_connection(database, local_port) }
@@ -11,6 +11,7 @@ module Aptible
11
11
 
12
12
  desc 'domains', "Print an app's current virtual domains"
13
13
  option :app
14
+ option :environment
14
15
  option :verbose, aliases: '-v'
15
16
  option :remote, aliases: '-r'
16
17
  def domains
@@ -1,5 +1,5 @@
1
1
  module Aptible
2
2
  module CLI
3
- VERSION = '0.5.15'
3
+ VERSION = '0.6.0'
4
4
  end
5
5
  end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Aptible::CLI::Helpers::App::HandleFromGitRemote do
4
+ it 'should parse handle from remote without account' do
5
+ str = 'git@test.aptible.com:test-app.git'
6
+ result = described_class.parse(str)[:app_handle]
7
+ expect(result).not_to be nil
8
+ expect(result).to eql 'test-app'
9
+ end
10
+
11
+ it 'should parse handle from remote with account' do
12
+ str = 'git@test.aptible.com:test-account/test-app.git'
13
+ result = described_class.parse(str)[:app_handle]
14
+ expect(result).not_to be nil
15
+ expect(result).to eql 'test-app'
16
+ end
17
+ end
@@ -21,7 +21,11 @@ describe Aptible::CLI::Agent do
21
21
 
22
22
  let(:service) { Service.new(process_type: 'web') }
23
23
  let(:op) { Operation.new(status: 'succeeded') }
24
- let(:account) { Account.new(bastion_host: 'localhost', dumptruck_port: 1234) }
24
+ let(:account) do
25
+ Account.new(bastion_host: 'localhost',
26
+ dumptruck_port: 1234,
27
+ handle: 'aptible')
28
+ end
25
29
  let(:apps) do
26
30
  [App.new(handle: 'hello', services: [service], account: account)]
27
31
  end
@@ -31,14 +35,27 @@ describe Aptible::CLI::Agent do
31
35
  allow(service).to receive(:create_operation) { op }
32
36
  allow(subject).to receive(:options) { { app: 'hello' } }
33
37
  allow(op).to receive(:resource) { apps.first }
34
- allow(Aptible::Api::App).to receive(:all) { apps }
38
+ allow(Aptible::Api::Account).to receive(:all) { [account] }
39
+ allow(account).to receive(:apps) { apps }
35
40
 
36
41
  subject.send('apps:scale', 'web', 3)
37
42
  end
38
43
 
44
+ it 'should fail if environment is non-existent' do
45
+ allow(subject).to receive(:options) { { environment: 'foo', app: 'web' } }
46
+ allow(service).to receive(:create_operation) { op }
47
+ allow(Aptible::Api::Account).to receive(:all) { [] }
48
+ allow(account).to receive(:apps) { [apps] }
49
+
50
+ expect do
51
+ subject.send('apps:scale', 'web', 3)
52
+ end.to raise_error(Thor::Error)
53
+ end
54
+
39
55
  it 'should fail if app is non-existent' do
40
56
  allow(service).to receive(:create_operation) { op }
41
- allow(Aptible::Api::App).to receive(:all) { apps }
57
+ allow(Aptible::Api::Account).to receive(:all) { [account] }
58
+ allow(account).to receive(:apps) { [] }
42
59
 
43
60
  expect do
44
61
  subject.send('apps:scale', 'web', 3)
@@ -14,6 +14,11 @@ describe Aptible::CLI::Agent do
14
14
  before { subject.stub(:random_local_port) { 4242 } }
15
15
  before { subject.stub(:establish_connection) }
16
16
 
17
+ let(:account) do
18
+ Account.new(bastion_host: 'localhost',
19
+ dumptruck_port: 1234,
20
+ handle: 'aptible')
21
+ end
17
22
  let(:database) do
18
23
  Database.new(
19
24
  type: 'postgresql',
@@ -25,14 +30,16 @@ describe Aptible::CLI::Agent do
25
30
 
26
31
  describe '#db:tunnel' do
27
32
  it 'should fail if database is non-existent' do
28
- allow(Aptible::Api::Database).to receive(:all) { [] }
33
+ allow(Aptible::Api::Account).to receive(:all) { [account] }
34
+ allow(account).to receive(:databases) { [] }
29
35
  expect do
30
36
  subject.send('db:tunnel', 'foobar')
31
37
  end.to raise_error('Could not find database foobar')
32
38
  end
33
39
 
34
40
  it 'should print a message about how to connect' do
35
- allow(Aptible::Api::Database).to receive(:all) { [database] }
41
+ allow(Aptible::Api::Account).to receive(:all) { [account] }
42
+ allow(account).to receive(:databases) { [database] }
36
43
  local_url = 'postgresql://aptible:password@127.0.0.1:4242/db'
37
44
  expect(subject).to receive(:say).with('Creating tunnel...', :green)
38
45
  expect(subject).to receive(:say).with("Connect at #{local_url}", :green)
@@ -66,7 +73,7 @@ describe Aptible::CLI::Agent do
66
73
  setup_prod_and_staging_accounts
67
74
  allow(subject).to receive(:say)
68
75
 
69
- subject.options = { account: 'staging' }
76
+ subject.options = { environment: 'staging' }
70
77
  subject.send('db:list')
71
78
 
72
79
  expect(subject).to have_received(:say).with('=== staging')
@@ -84,7 +91,7 @@ describe Aptible::CLI::Agent do
84
91
  setup_prod_and_staging_accounts
85
92
  allow(subject).to receive(:say)
86
93
 
87
- subject.options = { account: 'foo' }
94
+ subject.options = { environment: 'foo' }
88
95
  expect { subject.send('db:list') }.to raise_error(
89
96
  'Specified account does not exist'
90
97
  )
@@ -22,6 +22,11 @@ describe Aptible::CLI::Agent do
22
22
  let(:op) { Operation.new(status: 'succeeded') }
23
23
  let(:app) { App.new(handle: 'hello', services: [service]) }
24
24
  let(:apps) { [app] }
25
+ let(:account) do
26
+ Account.new(bastion_host: 'localhost',
27
+ dumptruck_port: 1234,
28
+ handle: 'aptible')
29
+ end
25
30
 
26
31
  let(:vhost1) { Vhost.new(virtual_domain: 'domain1', external_host: 'host1') }
27
32
  let(:vhost2) { Vhost.new(virtual_domain: 'domain2', external_host: 'host2') }
@@ -30,7 +35,8 @@ describe Aptible::CLI::Agent do
30
35
  it 'should print out the hostnames' do
31
36
  allow(service).to receive(:create_operation) { op }
32
37
  allow(subject).to receive(:options) { { app: 'hello' } }
33
- allow(Aptible::Api::App).to receive(:all) { apps }
38
+ allow(Aptible::Api::Account).to receive(:all) { [account] }
39
+ allow(account).to receive(:apps) { apps }
34
40
 
35
41
  expect(app).to receive(:vhosts) { [vhost1, vhost2] }
36
42
  expect(subject).to receive(:say).with('domain1')
@@ -41,7 +47,18 @@ describe Aptible::CLI::Agent do
41
47
 
42
48
  it 'should fail if app is non-existent' do
43
49
  allow(service).to receive(:create_operation) { op }
44
- allow(Aptible::Api::App).to receive(:all) { apps }
50
+ allow(Aptible::Api::Account).to receive(:all) { [account] }
51
+ allow(account).to receive(:apps) { apps }
52
+
53
+ expect do
54
+ subject.send('domains')
55
+ end.to raise_error(Thor::Error)
56
+ end
57
+
58
+ it 'should fail if environment is non-existent' do
59
+ allow(service).to receive(:create_operation) { op }
60
+ allow(Aptible::Api::Account).to receive(:all) { [] }
61
+ allow(account).to receive(:apps) { apps }
45
62
 
46
63
  expect do
47
64
  subject.send('domains')
@@ -51,7 +68,8 @@ describe Aptible::CLI::Agent do
51
68
  it 'should print hostnames if -v is passed' do
52
69
  allow(service).to receive(:create_operation) { op }
53
70
  allow(subject).to receive(:options) { { verbose: true, app: 'hello' } }
54
- allow(Aptible::Api::App).to receive(:all) { apps }
71
+ allow(Aptible::Api::Account).to receive(:all) { [account] }
72
+ allow(account).to receive(:apps) { apps }
55
73
 
56
74
  expect(app).to receive(:vhosts) { [vhost1, vhost2] }
57
75
  expect(subject).to receive(:say).with('domain1 -> host1')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aptible-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.15
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Macreery
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-13 00:00:00.000000000 Z
11
+ date: 2016-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aptible-api
@@ -170,9 +170,9 @@ files:
170
170
  - bin/aptible
171
171
  - lib/aptible/cli.rb
172
172
  - lib/aptible/cli/agent.rb
173
- - lib/aptible/cli/helpers/account.rb
174
173
  - lib/aptible/cli/helpers/app.rb
175
174
  - lib/aptible/cli/helpers/env.rb
175
+ - lib/aptible/cli/helpers/environment.rb
176
176
  - lib/aptible/cli/helpers/operation.rb
177
177
  - lib/aptible/cli/helpers/token.rb
178
178
  - lib/aptible/cli/subcommands/apps.rb
@@ -186,6 +186,7 @@ files:
186
186
  - lib/aptible/cli/subcommands/ssh.rb
187
187
  - lib/aptible/cli/version.rb
188
188
  - spec/aptible/cli/agent_spec.rb
189
+ - spec/aptible/cli/helpers/handle_from_git_remote.rb
189
190
  - spec/aptible/cli/subcommands/apps_spec.rb
190
191
  - spec/aptible/cli/subcommands/db_spec.rb
191
192
  - spec/aptible/cli/subcommands/domains_spec.rb
@@ -212,12 +213,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
213
  version: '0'
213
214
  requirements: []
214
215
  rubyforge_project:
215
- rubygems_version: 2.2.2
216
+ rubygems_version: 2.4.5
216
217
  signing_key:
217
218
  specification_version: 4
218
219
  summary: Command-line interface for Aptible services
219
220
  test_files:
220
221
  - spec/aptible/cli/agent_spec.rb
222
+ - spec/aptible/cli/helpers/handle_from_git_remote.rb
221
223
  - spec/aptible/cli/subcommands/apps_spec.rb
222
224
  - spec/aptible/cli/subcommands/db_spec.rb
223
225
  - spec/aptible/cli/subcommands/domains_spec.rb
@@ -1,49 +0,0 @@
1
- require 'aptible/api'
2
- require 'git'
3
-
4
- module Aptible
5
- module CLI
6
- module Helpers
7
- module Account
8
- include Helpers::Token
9
-
10
- def scoped_accounts(options)
11
- if options[:account]
12
- if (account = account_from_handle(options[:account]))
13
- [account]
14
- else
15
- fail Thor::Error, 'Specified account does not exist'
16
- end
17
- else
18
- Aptible::Api::Account.all(token: fetch_token)
19
- end
20
- end
21
-
22
- def ensure_account(options = {})
23
- if (handle = options[:account])
24
- account = account_from_handle(handle)
25
- return account if account
26
- fail "Could not find account #{handle}"
27
- else
28
- ensure_default_account
29
- end
30
- end
31
-
32
- def account_from_handle(handle)
33
- Aptible::Api::Account.all(token: fetch_token).find do |a|
34
- a.handle == handle
35
- end
36
- end
37
-
38
- def ensure_default_account
39
- accounts = Aptible::Api::Account.all(token: fetch_token)
40
- return accounts.first if accounts.count == 1
41
-
42
- fail Thor::Error, <<-ERR.gsub(/\s+/, ' ').strip
43
- Multiple accounts available, please specify with --account
44
- ERR
45
- end
46
- end
47
- end
48
- end
49
- end