acquia_toolbelt 2.3.2 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Acquia Toolbelt
1
+ # Acquia Toolbelt
2
2
 
3
3
  The Acquia Toolbelt is a CLI tool for using the Acquia Cloud API. Some of the
4
4
  features include getting information around your servers, subscription,
@@ -50,20 +50,26 @@ Without parameters:
50
50
  ```bash
51
51
  $ acquia databases:list
52
52
 
53
- > mydb
54
- > mydb2
53
+ +------------------------+
54
+ | Name |
55
+ +------------------------+
56
+ | acquiatoolbeltdev |
57
+ | example-db |
58
+ | newer-db |
59
+ +------------------------+
55
60
  ```
56
61
 
57
62
  With parameters:
58
63
 
59
64
  ```bash
60
- $ acquia databases:list -e dev -d mydb
65
+ $ acquia databases:list --environment=dev --database=acquiatoolbeltdev
66
+
67
+ +-------------------+----------+-----------------+-----------+------------+----------------------+
68
+ | Name | Username | Password | Host | DB cluster | Instance name |
69
+ +-------------------+----------+-----------------+-----------+------------+----------------------+
70
+ | acquiatoolbeltdev | s22614 | 7Ps5kU7s3VEvFTj | free-4422 | 3119 | acquiatoolbeltdevdev |
71
+ +-------------------+----------+-----------------+-----------+------------+----------------------+
61
72
 
62
- > Username: exampledb
63
- > Password: h5hKN4v2nc*1nd
64
- > Host: staging-1234
65
- > DB cluster: 1111
66
- > Instance name: mydb8717
67
73
  ```
68
74
 
69
75
  ## Getting started
@@ -144,6 +150,7 @@ This library aims to support and is [tested against](https://travis-ci.org/jacob
144
150
  * Ruby 1.9.2
145
151
  * Ruby 1.9.3
146
152
  * Ruby 2.0.0
153
+ * Ruby 2.1.0
147
154
 
148
155
  If you would like support for other implementations or versions, please open an
149
156
  issue and it can be looked into.
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'acquia_toolbelt/version'
@@ -25,6 +24,7 @@ Gem::Specification.new do |spec|
25
24
  spec.add_runtime_dependency 'rainbow', '1.1.4'
26
25
  spec.add_runtime_dependency 'sshkey', '1.6.0'
27
26
  spec.add_runtime_dependency 'multi_json', '1.8.2'
27
+ spec.add_runtime_dependency 'terminal-table', '1.4.5'
28
28
 
29
29
  spec.add_development_dependency 'bundler', '~> 1.3'
30
30
  spec.add_development_dependency 'rake', '10.1.0'
@@ -15,7 +15,7 @@ module AcquiaToolbelt
15
15
  def login
16
16
  cli = HighLine.new
17
17
  user = cli.ask('Enter your username: ')
18
- password = cli.ask('Enter your password: ') { |q| q.echo = false }
18
+ password = cli.ask('Enter your password (typing will be hidden): ') { |q| q.echo = false }
19
19
 
20
20
  # Update (or create if needed) the netrc file that will contain the user
21
21
  # authentication details.
@@ -10,13 +10,17 @@ module AcquiaToolbelt
10
10
  # database - The name of the database you wish to fetch the information
11
11
  # about.
12
12
  #
13
- # Returns multiple lines.
14
- def output_database_instance(database)
15
- ui.say "> Username: #{database['username']}"
16
- ui.say "> Password: #{database['password']}"
17
- ui.say "> Host: #{database['host']}"
18
- ui.say "> DB cluster: #{database['db_cluster']}"
19
- ui.say "> Instance name: #{database['instance_name']}"
13
+ # Returns the row of data for the database.
14
+ def database_details(database)
15
+ row_data = []
16
+ row_data << database['name']
17
+ row_data << database['username']
18
+ row_data << database['password']
19
+ row_data << database['host']
20
+ row_data << database['db_cluster']
21
+ row_data << database['instance_name']
22
+
23
+ row_data
20
24
  end
21
25
  end
22
26
 
@@ -36,8 +40,6 @@ module AcquiaToolbelt
36
40
  database = options[:database]
37
41
  add_database = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/dbs", 'POST', :db => "#{database}"
38
42
 
39
- puts "#{add_database}"
40
-
41
43
  if add_database['id']
42
44
  ui.success "Database '#{database}' has been successfully created."
43
45
  else
@@ -113,33 +115,45 @@ module AcquiaToolbelt
113
115
  subscription = AcquiaToolbelt::CLI::API.default_subscription
114
116
  end
115
117
 
118
+ ui.say
119
+
116
120
  database = options[:database]
117
121
  environment = options[:environment]
122
+ rows = []
123
+ headings = [
124
+ 'Name',
125
+ 'Username',
126
+ 'Password',
127
+ 'Host',
128
+ 'DB cluster',
129
+ 'Instance name'
130
+ ]
118
131
 
119
132
  # Output a single database where the name and environment are specified.
120
133
  if database && environment
121
134
  database = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/envs/#{environment}/dbs/#{database}"
122
- ui.say
123
- output_database_instance(database)
135
+ rows << database_details(database)
124
136
 
125
137
  # Only an environment was set so get all expanded data for the requested
126
138
  # environment.
127
139
  elsif environment
128
140
  databases = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/envs/#{environment}/dbs"
129
141
  databases.each do |db|
130
- ui.say
131
- ui.say "#{db['name']}"
132
- output_database_instance(db)
142
+ rows << database_details(db)
133
143
  end
134
144
 
135
- # Just a general listing of the databases, no in depth details.
145
+ # If no name or environment is passed, just throw back all the database
146
+ # names - no in depth details.
136
147
  else
148
+ # Only set the 'name' header as we don't need the rest of the headers.
149
+ headings = ['Name']
137
150
  databases = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/dbs"
138
- ui.say
139
151
  databases.each do |db|
140
- say "> #{db['name']}"
152
+ rows << [db['name']]
141
153
  end
142
154
  end
155
+
156
+ ui.output_table('', headings, rows)
143
157
  end
144
158
 
145
159
  # Public: Create a database instance backup.
@@ -187,16 +201,31 @@ module AcquiaToolbelt
187
201
  database = options[:database]
188
202
  environment = options[:environment]
189
203
  backups = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/envs/#{environment}/dbs/#{database}/backups"
204
+
205
+ ui.say
206
+
207
+ rows = []
208
+ headings = [
209
+ 'ID',
210
+ 'Checksum',
211
+ 'Type',
212
+ 'Path',
213
+ 'Start',
214
+ 'Completed'
215
+ ]
216
+
190
217
  backups.each do |backup|
191
- ui.say
192
- ui.say "> ID: #{backup['id']}"
193
- ui.say "> MD5: #{backup['checksum']}"
194
- ui.say "> Type: #{backup['type']}"
195
- ui.say "> Path: #{backup['path']}"
196
- ui.say "> Link: #{backup['link']}"
197
- ui.say "> Started: #{Time.at(backup['started'].to_i)}"
198
- ui.say "> Completed: #{Time.at(backup['completed'].to_i)}"
218
+ row_data = []
219
+ row_data << backup['id']
220
+ row_data << backup['checksum']
221
+ row_data << backup['type']
222
+ row_data << backup['path']
223
+ row_data << Time.at(backup['started'].to_i)
224
+ row_data << Time.at(backup['completed'].to_i)
225
+ rows << row_data
199
226
  end
227
+
228
+ ui.output_table('', headings, rows)
200
229
  end
201
230
 
202
231
  # Public: Restore a database backup.
@@ -43,15 +43,21 @@ module AcquiaToolbelt
43
43
  environments = AcquiaToolbelt::CLI::API.environments
44
44
  end
45
45
 
46
+ ui.say
47
+
48
+ rows = []
49
+ headings = ['Domain']
50
+
46
51
  environments.each do |environment|
47
52
  domains = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/envs/#{environment}/domains"
48
- ui.say
49
- ui.say "Environment: #{environment}" unless options[:environment]
50
-
51
53
  domains.each do |domain|
52
- ui.say "> #{domain['name']}"
54
+ row_data = []
55
+ row_data << domain['name']
56
+ rows << row_data
53
57
  end
54
58
  end
59
+
60
+ ui.output_table('', headings, rows)
55
61
  end
56
62
 
57
63
  # Public: Add a domain to the subscription.
@@ -110,7 +116,7 @@ module AcquiaToolbelt
110
116
  # Public: Purge a domains web cache.
111
117
  #
112
118
  # Returns a status message.
113
- desc 'purge', 'Purge a domain\'s web cache.'
119
+ desc 'purge', "Purge a domain's web cache."
114
120
  method_option :domain, :type => :string, :aliases => %w(-d),
115
121
  :desc => 'URL of the domain to purge.'
116
122
  def purge
@@ -23,15 +23,31 @@ module AcquiaToolbelt
23
23
  environments = AcquiaToolbelt::CLI::API.environments
24
24
  end
25
25
 
26
+ ui.say
27
+
28
+ rows = []
29
+ headings = [
30
+ 'Host',
31
+ 'Environment',
32
+ 'Current release',
33
+ 'Live development',
34
+ 'DB clusters',
35
+ 'Default domain'
36
+ ]
37
+
26
38
  environments.each do |env|
27
39
  env_info = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/envs/#{env}"
28
- ui.say
29
- ui.say "> Host: #{env_info['ssh_host']}"
30
- ui.say "> Environment: #{env_info['name']}"
31
- ui.say "> Current release: #{env_info['vcs_path']}"
32
- ui.say "> DB clusters: #{env_info['db_clusters'].join(', ')}"
33
- ui.say "> Default domain: #{env_info['default_domain']}"
40
+ row_data = []
41
+ row_data << env_info['ssh_host']
42
+ row_data << env_info['name']
43
+ row_data << env_info['vcs_path']
44
+ row_data << env_info['livedev'].capitalize
45
+ row_data << env_info['db_clusters'].join(', ')
46
+ row_data << env_info['default_domain']
47
+ rows << row_data
34
48
  end
49
+
50
+ ui.output_table('', headings, rows)
35
51
  end
36
52
 
37
53
  # Public: Toggle whether live development is enabled on an environment.
@@ -21,46 +21,66 @@ module AcquiaToolbelt
21
21
  # Loop over each environment and get all the associated server data.
22
22
  environments.each do |env|
23
23
  ui.say
24
- ui.say "Environment: #{env}"
24
+
25
+ rows = []
26
+ headings = [
27
+ 'FQDN',
28
+ 'Availability zone',
29
+ 'Type',
30
+ 'PHP processes',
31
+ 'Environment state',
32
+ 'Web state',
33
+ 'Varnish state',
34
+ 'External IP'
35
+ ]
25
36
 
26
37
  server_env = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/envs/#{env}/servers"
27
38
  server_env.each do |server|
28
- ui.say
29
- ui.say "> Host: #{server['fqdn']}"
30
- ui.say "> Region: #{server['ec2_region']}"
31
- ui.say "> Instance type: #{server['ami_type']}"
32
- ui.say "> Availability zone: #{server['ec2_availability_zone']}"
39
+ row_data = []
40
+ row_data << server['fqdn']
41
+ row_data << server['ec2_availability_zone']
42
+ row_data << server['ami_type']
33
43
 
34
44
  # Show how many PHP processes this node can have. Note, this is only
35
45
  # available on the web servers.
36
- if server['services'] && server['services']['php_max_procs']
37
- ui.say "> PHP max processes: #{server['services']['php_max_procs']}"
46
+ if server['services'] && server['services']['web']
47
+ row_data << server['services']['web']['php_max_procs']
48
+ else
49
+ row_data << 'n/a'
38
50
  end
39
51
 
40
- if server['services'] && server['services']['status']
41
- ui.say "> Status: #{server['services']['status']}"
52
+ if server['services'] && server['services']['web']
53
+ row_data << server['services']['web']['env_status']
54
+ else
55
+ row_data << 'n/a'
42
56
  end
43
57
 
44
58
  if server['services'] && server['services']['web']
45
- ui.say "> Web status: #{server['services']['web']['status']}"
59
+ row_data << server['services']['web']['status']
60
+ else
61
+ row_data << 'n/a'
46
62
  end
47
63
 
48
64
  # The state of varnish.
49
65
  if server['services'] && server['services']['varnish']
50
- ui.say "> Varnish status: #{server['services']['varnish']['status']}"
66
+ # Replace underscores with a space to make the output slightly
67
+ # nicer.
68
+ row_data << server['services']['varnish']['status'].sub('_', ' ')
69
+ else
70
+ row_data << 'n/a'
51
71
  end
52
72
 
53
73
  # Only load balancers will have the 'external IP' property.
54
74
  if server['services'] && server['services']['external_ip']
55
- ui.say "> External IP: #{server['services']['external_ip']}"
75
+ row_data << server['services']['external_ip']
76
+ else
77
+ row_data << 'n/a'
56
78
  end
57
79
 
58
- # If running a dedicated load balancer, there will be a ELB domain
59
- # associated with the load balancing tier.
60
- if server['services'] && server['services']['elb_domain_name']
61
- ui.say "> ELB hostname: #{server['services']['elb_domain_name']}"
62
- end
80
+ rows << row_data
63
81
  end
82
+
83
+ ui.output_table("Environment: #{env}", headings, rows)
64
84
  end
65
85
  end
66
86
  end
@@ -7,26 +7,31 @@ module AcquiaToolbelt
7
7
  desc 'list', 'List all subscriptions you have access to.'
8
8
  def list
9
9
  sites = AcquiaToolbelt::CLI::API.request 'sites'
10
+ ui.say
11
+
12
+ rows = []
13
+ headings = [
14
+ 'Subscription name',
15
+ 'Username',
16
+ 'Realm name',
17
+ 'UUID',
18
+ 'Production mode'
19
+ ]
10
20
 
11
21
  sites.each do |site|
12
- ui.say
13
22
  # Get the individual subscription information.
14
23
  site_data = AcquiaToolbelt::CLI::API.request "sites/#{site}"
15
24
 
16
- ui.say "#{site_data['title']}"
17
- ui.say "> Username: #{site_data['unix_username']}"
18
- ui.say "> Subscription: #{site_data['name']}"
19
-
20
- # If the VCS type is SVN, we want it in all uppercase, otherwise just
21
- # capitilise it.
22
- if site_data['vcs_type'] == 'svn'
23
- vcs_name = site_data['vcs_type'].upcase
24
- else
25
- vcs_name = site_data['vcs_type'].capitalize
26
- end
27
-
28
- ui.say "> #{vcs_name} URL: #{site_data['vcs_url']}"
25
+ row_data = []
26
+ row_data << site_data['title']
27
+ row_data << site_data['unix_username']
28
+ row_data << site_data['name']
29
+ row_data << site_data['uuid']
30
+ row_data << site_data['production_mode']
31
+ rows << row_data
29
32
  end
33
+
34
+ ui.output_table('', headings, rows)
30
35
  end
31
36
  end
32
37
  end
@@ -14,13 +14,29 @@ module AcquiaToolbelt
14
14
  subscription = AcquiaToolbelt::CLI::API.default_subscription
15
15
  end
16
16
 
17
+ ui.say
18
+
19
+ rows = []
20
+ headings = [
21
+ 'ID',
22
+ 'Nickname',
23
+ 'Fingerprint',
24
+ 'Shell access',
25
+ 'VCS access'
26
+ ]
27
+
17
28
  users = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/sshkeys"
18
29
  users.each do |user|
19
- say
20
- say "> ID: #{user['id']}"
21
- say "> Name: #{user['nickname']}"
22
- say "> Fingerprint: #{SSHKey.fingerprint user['ssh_pub_key']}"
30
+ row_data = []
31
+ row_data << user['id']
32
+ row_data << user['nickname']
33
+ row_data << SSHKey.fingerprint(user['ssh_pub_key'])
34
+ row_data << user['shell_access']
35
+ row_data << user['vcs_access']
36
+ rows << row_data
23
37
  end
38
+
39
+ ui.output_table('', headings, rows)
24
40
  end
25
41
 
26
42
  # Public: Delete a SSH key.
@@ -12,12 +12,23 @@ module AcquiaToolbelt
12
12
  subscription = AcquiaToolbelt::CLI::API.default_subscription
13
13
  end
14
14
 
15
+ ui.say
16
+
17
+ rows = []
18
+ headings = [
19
+ 'ID',
20
+ 'Name'
21
+ ]
22
+
15
23
  svn_users = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/svnusers"
16
24
  svn_users.each do |user|
17
- ui.say
18
- ui.say "> ID: #{user['id']}"
19
- ui.say "> Name: #{user['username']}"
25
+ row_data = []
26
+ row_data << user['id']
27
+ row_data << user['username']
28
+ rows << row_data
20
29
  end
30
+
31
+ ui.output_table('', headings, rows)
21
32
  end
22
33
 
23
34
  # Public: Create a new SVN user.
@@ -8,20 +8,23 @@ module AcquiaToolbelt
8
8
  # task.
9
9
  def output_task_item(task)
10
10
  completion_time = (task['completed'].to_i - task['started'].to_i) / 60
11
- ui.say
12
- ui.say "Task ID: #{task['id'].to_i}"
13
- ui.say "Description: #{task['description']}"
14
- ui.say "Status: #{task['state']}"
11
+ row_data = []
12
+ description = task['description'].scan(/.{1,50}[\w\=]/).map(&:strip)
13
+
14
+ row_data << task['id'].to_i
15
+ row_data << task['queue']
16
+ row_data << description.join("\n")
17
+ row_data << task['state'].capitalize
15
18
 
16
19
  # If the completion time is greater then 0, output it in minutes
17
20
  # otherwise just say it was less then a minute.
18
21
  if completion_time > 0
19
- ui.say "Completion time: About #{completion_time} minutes"
22
+ row_data << "About #{completion_time} minutes"
20
23
  else
21
- ui.say 'Completion time: Less than 1 minute'
24
+ row_data << 'Less than 1 minute'
22
25
  end
23
26
 
24
- ui.say "Queue: #{task['queue']}"
27
+ row_data
25
28
  end
26
29
  end
27
30
 
@@ -40,19 +43,27 @@ module AcquiaToolbelt
40
43
  subscription = AcquiaToolbelt::CLI::API.default_subscription
41
44
  end
42
45
 
43
- queue = options[:queue]
44
- count = options[:count]
46
+ ui.say
47
+
48
+ queue = options[:queue]
49
+ count = options[:count]
50
+ tasks = []
51
+ rows = []
52
+ headings = [
53
+ 'ID',
54
+ 'Queue',
55
+ 'Description',
56
+ 'State',
57
+ 'Completion time'
58
+ ]
45
59
 
46
60
  all_tasks = AcquiaToolbelt::CLI::API.request "sites/#{subscription}/tasks"
47
- tasks = []
48
61
 
49
62
  # Fetch a single queue from the tasks list if the queue parameter is set
50
63
  # otherwise just add all the tasks.
51
64
  if queue
52
65
  all_tasks.each do |task|
53
- if task['queue'] == queue
54
- tasks << task
55
- end
66
+ tasks << task if task['queue'] == queue
56
67
  end
57
68
  else
58
69
  all_tasks.each do |task|
@@ -64,8 +75,10 @@ module AcquiaToolbelt
64
75
  tasks = tasks.last(count.to_i) if count && tasks.any?
65
76
 
66
77
  tasks.each do |task|
67
- output_task_item(task)
78
+ rows << output_task_item(task)
68
79
  end
80
+
81
+ ui.output_table('', headings, rows)
69
82
  end
70
83
  end
71
84
  end
@@ -39,6 +39,26 @@ module AcquiaToolbelt
39
39
  def debug(text)
40
40
  puts "#{text}".foreground(:yellow)
41
41
  end
42
+
43
+ # Internal: Render a CLI table.
44
+ #
45
+ # title - The title to display at the top of the table.
46
+ # heading - Header rows for the table.
47
+ # rows - An array of the row data to output.
48
+ #
49
+ # Outputs a table to the end user.
50
+ def output_table(title = '', headings, rows)
51
+ table = Terminal::Table.new
52
+ table.title = title unless title.empty?
53
+ table.rows = rows
54
+ table.headings = headings
55
+ table.style = {
56
+ :padding_left => 1,
57
+ :padding_right => 1
58
+ }
59
+
60
+ puts table
61
+ end
42
62
  end
43
63
  end
44
64
  end
@@ -1,6 +1,7 @@
1
1
  require 'acquia_toolbelt'
2
2
  require 'acquia_toolbelt/error'
3
3
  require 'acquia_toolbelt/thor'
4
+ require 'terminal-table'
4
5
 
5
6
  module AcquiaToolbelt
6
7
  class CLI < AcquiaToolbelt::Thor
@@ -1,3 +1,3 @@
1
1
  module AcquiaToolbelt
2
- VERSION = '2.3.2'
2
+ VERSION = '2.4.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acquia_toolbelt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 2.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-10 00:00:00.000000000 Z
12
+ date: 2014-11-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -139,6 +139,22 @@ dependencies:
139
139
  - - '='
140
140
  - !ruby/object:Gem::Version
141
141
  version: 1.8.2
142
+ - !ruby/object:Gem::Dependency
143
+ name: terminal-table
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - '='
148
+ - !ruby/object:Gem::Version
149
+ version: 1.4.5
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - '='
156
+ - !ruby/object:Gem::Version
157
+ version: 1.4.5
142
158
  - !ruby/object:Gem::Dependency
143
159
  name: bundler
144
160
  requirement: !ruby/object:Gem::Requirement