acquia_toolbelt 1.5.1 → 2.0.0
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.
- checksums.yaml +8 -8
- data/.ruby-version +1 -0
- data/Gemfile.lock +35 -0
- data/README.md +55 -27
- data/acquia_toolbelt.gemspec +2 -0
- data/bin/acquia +6 -565
- data/lib/acquia_toolbelt/cli.rb +102 -0
- data/lib/acquia_toolbelt/cli/api.rb +106 -0
- data/lib/acquia_toolbelt/cli/auth.rb +31 -0
- data/lib/acquia_toolbelt/cli/database.rb +208 -0
- data/lib/acquia_toolbelt/cli/deploy.rb +30 -0
- data/lib/acquia_toolbelt/cli/domain.rb +166 -0
- data/lib/acquia_toolbelt/cli/environment.rb +38 -0
- data/lib/acquia_toolbelt/cli/file.rb +23 -0
- data/lib/acquia_toolbelt/cli/server.rb +61 -0
- data/lib/acquia_toolbelt/cli/site.rb +28 -0
- data/lib/acquia_toolbelt/cli/ssh.rb +69 -0
- data/lib/acquia_toolbelt/cli/svn.rb +65 -0
- data/lib/acquia_toolbelt/cli/task.rb +71 -0
- data/lib/acquia_toolbelt/cli/ui.rb +29 -0
- data/lib/acquia_toolbelt/error.rb +4 -0
- data/lib/acquia_toolbelt/thor.rb +95 -0
- data/lib/acquia_toolbelt/version.rb +1 -1
- data/lib/vendor/thor/CHANGELOG.md +139 -0
- data/lib/vendor/thor/Gemfile +20 -0
- data/lib/vendor/thor/LICENSE.md +20 -0
- data/lib/vendor/thor/README.md +35 -0
- data/lib/vendor/thor/lib/thor.rb +474 -0
- data/lib/vendor/thor/lib/thor/actions.rb +318 -0
- data/lib/vendor/thor/lib/thor/actions/create_file.rb +105 -0
- data/lib/vendor/thor/lib/thor/actions/create_link.rb +60 -0
- data/lib/vendor/thor/lib/thor/actions/directory.rb +119 -0
- data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +137 -0
- data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +317 -0
- data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +109 -0
- data/lib/vendor/thor/lib/thor/base.rb +654 -0
- data/lib/vendor/thor/lib/thor/command.rb +136 -0
- data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +80 -0
- data/lib/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
- data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/vendor/thor/lib/thor/error.rb +32 -0
- data/lib/vendor/thor/lib/thor/group.rb +282 -0
- data/lib/vendor/thor/lib/thor/invocation.rb +172 -0
- data/lib/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/vendor/thor/lib/thor/parser/argument.rb +74 -0
- data/lib/vendor/thor/lib/thor/parser/arguments.rb +171 -0
- data/lib/vendor/thor/lib/thor/parser/option.rb +121 -0
- data/lib/vendor/thor/lib/thor/parser/options.rb +218 -0
- data/lib/vendor/thor/lib/thor/rake_compat.rb +72 -0
- data/lib/vendor/thor/lib/thor/runner.rb +322 -0
- data/lib/vendor/thor/lib/thor/shell.rb +88 -0
- data/lib/vendor/thor/lib/thor/shell/basic.rb +422 -0
- data/lib/vendor/thor/lib/thor/shell/color.rb +148 -0
- data/lib/vendor/thor/lib/thor/shell/html.rb +127 -0
- data/lib/vendor/thor/lib/thor/util.rb +270 -0
- data/lib/vendor/thor/lib/thor/version.rb +3 -0
- data/lib/vendor/thor/spec/actions/create_file_spec.rb +170 -0
- data/lib/vendor/thor/spec/actions/create_link_spec.rb +95 -0
- data/lib/vendor/thor/spec/actions/directory_spec.rb +169 -0
- data/lib/vendor/thor/spec/actions/empty_directory_spec.rb +129 -0
- data/lib/vendor/thor/spec/actions/file_manipulation_spec.rb +382 -0
- data/lib/vendor/thor/spec/actions/inject_into_file_spec.rb +135 -0
- data/lib/vendor/thor/spec/actions_spec.rb +331 -0
- data/lib/vendor/thor/spec/base_spec.rb +291 -0
- data/lib/vendor/thor/spec/command_spec.rb +80 -0
- data/lib/vendor/thor/spec/core_ext/hash_with_indifferent_access_spec.rb +48 -0
- data/lib/vendor/thor/spec/core_ext/ordered_hash_spec.rb +115 -0
- data/lib/vendor/thor/spec/exit_condition_spec.rb +19 -0
- data/lib/vendor/thor/spec/fixtures/application.rb +2 -0
- data/lib/vendor/thor/spec/fixtures/app{1}/README +3 -0
- data/lib/vendor/thor/spec/fixtures/bundle/execute.rb +6 -0
- data/lib/vendor/thor/spec/fixtures/bundle/main.thor +1 -0
- data/lib/vendor/thor/spec/fixtures/command.thor +10 -0
- data/lib/vendor/thor/spec/fixtures/doc/%file_name%.rb.tt +1 -0
- data/lib/vendor/thor/spec/fixtures/doc/COMMENTER +11 -0
- data/lib/vendor/thor/spec/fixtures/doc/README +3 -0
- data/lib/vendor/thor/spec/fixtures/doc/block_helper.rb +3 -0
- data/lib/vendor/thor/spec/fixtures/doc/components/.empty_directory +0 -0
- data/lib/vendor/thor/spec/fixtures/doc/config.rb +1 -0
- data/lib/vendor/thor/spec/fixtures/doc/config.yaml.tt +1 -0
- data/lib/vendor/thor/spec/fixtures/doc/excluding/%file_name%.rb.tt +1 -0
- data/lib/vendor/thor/spec/fixtures/enum.thor +10 -0
- data/lib/vendor/thor/spec/fixtures/group.thor +128 -0
- data/lib/vendor/thor/spec/fixtures/invoke.thor +118 -0
- data/lib/vendor/thor/spec/fixtures/path with spaces b/data/lib/vendor/thor/spec/fixtures/path with → spaces +0 -0
- data/lib/vendor/thor/spec/fixtures/preserve/script.sh +3 -0
- data/lib/vendor/thor/spec/fixtures/script.thor +220 -0
- data/lib/vendor/thor/spec/fixtures/subcommand.thor +17 -0
- data/lib/vendor/thor/spec/group_spec.rb +222 -0
- data/lib/vendor/thor/spec/helper.rb +67 -0
- data/lib/vendor/thor/spec/invocation_spec.rb +108 -0
- data/lib/vendor/thor/spec/parser/argument_spec.rb +53 -0
- data/lib/vendor/thor/spec/parser/arguments_spec.rb +66 -0
- data/lib/vendor/thor/spec/parser/option_spec.rb +202 -0
- data/lib/vendor/thor/spec/parser/options_spec.rb +400 -0
- data/lib/vendor/thor/spec/rake_compat_spec.rb +72 -0
- data/lib/vendor/thor/spec/register_spec.rb +197 -0
- data/lib/vendor/thor/spec/runner_spec.rb +241 -0
- data/lib/vendor/thor/spec/shell/basic_spec.rb +330 -0
- data/lib/vendor/thor/spec/shell/color_spec.rb +95 -0
- data/lib/vendor/thor/spec/shell/html_spec.rb +31 -0
- data/lib/vendor/thor/spec/shell_spec.rb +47 -0
- data/lib/vendor/thor/spec/subcommand_spec.rb +30 -0
- data/lib/vendor/thor/spec/thor_spec.rb +499 -0
- data/lib/vendor/thor/spec/util_spec.rb +196 -0
- data/lib/vendor/thor/thor.gemspec +24 -0
- data/spec/auth_spec.rb +8 -0
- data/spec_helper.rb +6 -0
- metadata +135 -4
- data/tests/example_test.rb +0 -5
checksums.yaml
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
!binary "U0hBMQ==":
|
|
3
3
|
metadata.gz: !binary |-
|
|
4
|
-
|
|
4
|
+
NzQxOTk4OGFhZDkzMmEwYzBmZDMzN2NmZDc4YWY4YTA0N2Q5YjUxZA==
|
|
5
5
|
data.tar.gz: !binary |-
|
|
6
|
-
|
|
6
|
+
NjhjZGNiNGUxMDg4ZDczMTQzMWMzNjQwYmEwZWNiZTc3N2Y1ODFlNg==
|
|
7
7
|
!binary "U0hBNTEy":
|
|
8
8
|
metadata.gz: !binary |-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
MGMxMzc5ZmEyOTUwZTVkNjA0MDk5ZjE5YWY0Y2U2ODdlMzY0NTJlNTNjZTFj
|
|
10
|
+
ZWFiMWI1ODg4MjU4ZDhjZTI1N2ZkNjAzZTY2MmMyYjZlNmY2ZjA4M2I0MDI0
|
|
11
|
+
NjFiNjM1MGEwZTYxZDMzNzViYjAzMWIyNjQxMjQ2ZmY1MjdjYzU=
|
|
12
12
|
data.tar.gz: !binary |-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
MDY1YTM2ZWIxODJjNjE4MzI5MjVmNzE5OWU1YmI2MGRmMjMxZTkwZDQwNDRi
|
|
14
|
+
NWRlM2I0YjIyODQ0OGQ4YTc1YmUyMzExNmJlY2VlMzJjZTBlY2Q5ZWJlZmEy
|
|
15
|
+
MGQ2OTEyMmNjZjhjMmUwYTIwYzRmZWRkZjJiMTIxMWQ3MzhkNjE=
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.9.3-p327
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
acquia_toolbelt (1.5.1)
|
|
5
|
+
faraday (= 0.8.8)
|
|
6
|
+
highline (= 1.6.19)
|
|
7
|
+
json (= 1.8.0)
|
|
8
|
+
netrc (= 0.7.7)
|
|
9
|
+
rainbow (= 1.1.4)
|
|
10
|
+
sshkey (= 1.6.0)
|
|
11
|
+
thor (= 0.18.1)
|
|
12
|
+
|
|
13
|
+
GEM
|
|
14
|
+
remote: https://rubygems.org/
|
|
15
|
+
specs:
|
|
16
|
+
faraday (0.8.8)
|
|
17
|
+
multipart-post (~> 1.2.0)
|
|
18
|
+
highline (1.6.19)
|
|
19
|
+
json (1.8.0)
|
|
20
|
+
minitest (5.0.8)
|
|
21
|
+
multipart-post (1.2.0)
|
|
22
|
+
netrc (0.7.7)
|
|
23
|
+
rainbow (1.1.4)
|
|
24
|
+
rake (10.1.0)
|
|
25
|
+
sshkey (1.6.0)
|
|
26
|
+
thor (0.18.1)
|
|
27
|
+
|
|
28
|
+
PLATFORMS
|
|
29
|
+
ruby
|
|
30
|
+
|
|
31
|
+
DEPENDENCIES
|
|
32
|
+
acquia_toolbelt!
|
|
33
|
+
bundler (~> 1.3)
|
|
34
|
+
minitest
|
|
35
|
+
rake
|
data/README.md
CHANGED
|
@@ -15,44 +15,62 @@ $ gem install acquia_toolbelt
|
|
|
15
15
|
Once installed, the toolbelt is accessible via invoking `acquia` within the command line.
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
18
|
-
|
|
19
|
-
You can see all available commands by running `acquia` without any commands or parameters. Additonally, more information on each command is available via `acquia help [COMMAND]`.
|
|
18
|
+
You can see all available commands by running `acquia help`. Additonally, more information on each command is available via `acquia [COMMAND] help`.
|
|
20
19
|
|
|
21
20
|
```
|
|
22
|
-
$ acquia
|
|
21
|
+
$ acquia help
|
|
22
|
+
|
|
23
|
+
Type 'acquia [COMMAND] help' for more details on subcommands or to show example usage.
|
|
23
24
|
|
|
24
25
|
Commands:
|
|
25
|
-
acquia
|
|
26
|
-
acquia
|
|
27
|
-
acquia
|
|
28
|
-
acquia
|
|
29
|
-
acquia
|
|
30
|
-
acquia
|
|
31
|
-
acquia
|
|
32
|
-
acquia
|
|
33
|
-
acquia
|
|
34
|
-
acquia
|
|
35
|
-
acquia
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
26
|
+
acquia auth
|
|
27
|
+
acquia databases
|
|
28
|
+
acquia deploy
|
|
29
|
+
acquia domains
|
|
30
|
+
acquia environments
|
|
31
|
+
acquia files
|
|
32
|
+
acquia servers
|
|
33
|
+
acquia sites
|
|
34
|
+
acquia ssh
|
|
35
|
+
acquia svn
|
|
36
|
+
acquia tasks
|
|
37
|
+
|
|
38
|
+
Options:
|
|
39
|
+
-s, [--subscription=SUBSCRIPTION] # Name of a subscription you would like to target.
|
|
40
|
+
-e, [--environment=ENVIRONMENT] # Environment to target for commands.
|
|
41
|
+
-v, [--verbose] # Increase the verbose output from the commands.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### Example commands
|
|
45
|
+
|
|
46
|
+
Without parameters
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
$ acquia database:list
|
|
50
|
+
|
|
51
|
+
> mydb
|
|
52
|
+
> mydb2
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
With parameters
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
$ acquia database:list -e dev -d mydb
|
|
59
|
+
|
|
60
|
+
> Username: exampledb
|
|
61
|
+
> Password: h5hKN4v2nc*1nd
|
|
62
|
+
> Host: staging-1234
|
|
63
|
+
> DB cluster: 1111
|
|
64
|
+
> Instance name: mydb8717
|
|
47
65
|
```
|
|
48
66
|
|
|
49
67
|
## Getting started
|
|
50
68
|
|
|
51
|
-
Before you can start using any commands, you need to first run `acquia login`. This will write your login details to a local netrc file so that you won't be prompted for login details every time a request is made. After that, the sky is the limit!
|
|
69
|
+
Before you can start using any commands, you need to first run `acquia auth:login`. This will write your login details to a local netrc file so that you won't be prompted for login details every time a request is made. After that, the sky is the limit!
|
|
52
70
|
|
|
53
71
|
## FAQ
|
|
54
72
|
|
|
55
|
-
**Q
|
|
73
|
+
**Q: Is there support for proxies and corporate firewalls? **
|
|
56
74
|
|
|
57
75
|
**A:** By god yes. Proxies and corporate firewalls are the bane of my existence so there was no way this toolbelt _wasn't_ going to support it. To use a proxy, all you need to do is set your HTTPS_PROXY environment variable to the required value. Example:
|
|
58
76
|
|
|
@@ -67,6 +85,16 @@ $ echo $HTTPS_PROXY
|
|
|
67
85
|
$ http://myproxy.url.internal:1234
|
|
68
86
|
```
|
|
69
87
|
|
|
88
|
+
**Q: Is there somewhere I can see all the commands with required parameters? **
|
|
89
|
+
|
|
90
|
+
**A:** Yep. Check out the [commands listing](https://github.com/jacobbednarz/acquia-toolbelt/wiki/Commands) in the [wiki](https://github.com/jacobbednarz/acquia-toolbelt/wiki).
|
|
91
|
+
|
|
92
|
+
## Running tests
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
bundle exec ruby spec_helper.rb
|
|
96
|
+
```
|
|
97
|
+
|
|
70
98
|
## Contributing
|
|
71
99
|
|
|
72
100
|
1. Fork it
|
data/acquia_toolbelt.gemspec
CHANGED
|
@@ -24,7 +24,9 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
spec.add_runtime_dependency "faraday", "0.8.8"
|
|
25
25
|
spec.add_runtime_dependency "json", "1.8.0"
|
|
26
26
|
spec.add_runtime_dependency "rainbow", "1.1.4"
|
|
27
|
+
spec.add_runtime_dependency "sshkey", "1.6.0"
|
|
27
28
|
|
|
28
29
|
spec.add_development_dependency "bundler", "~> 1.3"
|
|
29
30
|
spec.add_development_dependency "rake"
|
|
31
|
+
spec.add_development_dependency "minitest"
|
|
30
32
|
end
|
data/bin/acquia
CHANGED
|
@@ -1,568 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
|
3
|
+
require 'acquia_toolbelt/cli'
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
require "json"
|
|
8
|
-
require "rainbow"
|
|
9
|
-
|
|
10
|
-
class Acquia < Thor
|
|
11
|
-
# A no_commands block is designed to show the methods that cannot be invoked
|
|
12
|
-
# and as such, do not have a description.
|
|
13
|
-
no_commands {
|
|
14
|
-
# Internal: Used for outputting a pretty success message.
|
|
15
|
-
#
|
|
16
|
-
# Returns the coloured and formatted string.
|
|
17
|
-
def success(text)
|
|
18
|
-
puts "#{text}".foreground(:green)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Internal: Used for outputting a pretty error message.
|
|
22
|
-
#
|
|
23
|
-
# Returns the coloured and formatted string.
|
|
24
|
-
def fail(text)
|
|
25
|
-
puts "#{text}".foreground(:red)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Internal: Used for outputting a pretty info message.
|
|
29
|
-
#
|
|
30
|
-
# Returns the coloured and formatted string.
|
|
31
|
-
def info(text)
|
|
32
|
-
puts "#{text}".foreground(:cyan)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Internal: Create a request to the Acquia API.
|
|
36
|
-
#
|
|
37
|
-
# The request generated contains all the correct user authentication and
|
|
38
|
-
# headers.
|
|
39
|
-
#
|
|
40
|
-
# Returns a JSON string of the body.
|
|
41
|
-
def acquia_api_call(resource, method = "GET", data = {})
|
|
42
|
-
n = Netrc.read
|
|
43
|
-
@acquia_user, @acquia_password = n["cloudapi.acquia.com"]
|
|
44
|
-
|
|
45
|
-
# Check if the user is behind a proxy and add the proxy settings if found.
|
|
46
|
-
if using_proxy?
|
|
47
|
-
conn = Faraday.new(:proxy => ENV["HTTPS_PROXY"])
|
|
48
|
-
else
|
|
49
|
-
conn = Faraday.new
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
conn.basic_auth(@acquia_user, @acquia_password)
|
|
53
|
-
|
|
54
|
-
case method
|
|
55
|
-
when "GET"
|
|
56
|
-
response = conn.get "https://cloudapi.acquia.com/v1/#{resource}.json"
|
|
57
|
-
JSON.parse response.body
|
|
58
|
-
when "POST"
|
|
59
|
-
response = conn.post "https://cloudapi.acquia.com/v1/#{resource}.json", data.to_json
|
|
60
|
-
JSON.parse response.body
|
|
61
|
-
when "CODE-DEPLOY-POST"
|
|
62
|
-
response = conn.post "https://cloudapi.acquia.com/v1/#{resource}.json?path=#{data[:release]}"
|
|
63
|
-
JSON.parse response.body
|
|
64
|
-
when "DELETE"
|
|
65
|
-
response = conn.delete "https://cloudapi.acquia.com/v1/#{resource}.json"
|
|
66
|
-
JSON.parse response.body
|
|
67
|
-
else
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Internal: Get defined subscription environments.
|
|
72
|
-
#
|
|
73
|
-
# This is a helper method that fetches all the available environments for a
|
|
74
|
-
# subscription and returns them for use in other methods.
|
|
75
|
-
#
|
|
76
|
-
# Returns an array of environments.
|
|
77
|
-
def get_acquia_environments(subscription)
|
|
78
|
-
env_data = acquia_api_call "sites/#{subscription}/envs"
|
|
79
|
-
|
|
80
|
-
envs = []
|
|
81
|
-
env_data.each do |env|
|
|
82
|
-
envs << env["name"]
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
envs
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Internal: Truncate a SSH key to a secure and recognisable size.
|
|
89
|
-
#
|
|
90
|
-
# Displaying whole SSH keys is probably a bad idea so instead we are getting
|
|
91
|
-
# the first 30 characters and the last 100 characters of the key and
|
|
92
|
-
# separating them with an ellipis. This allows you to recognise the
|
|
93
|
-
# important parts of the key instead of the whole thing.
|
|
94
|
-
#
|
|
95
|
-
# Returns string.
|
|
96
|
-
def truncate_ssh_key(ssh_key)
|
|
97
|
-
front_part = ssh_key[0...30]
|
|
98
|
-
back_part = ssh_key[-50, 50]
|
|
99
|
-
new_ssh_key = "#{front_part}...#{back_part}"
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# Internal: Send a request to purge a domain's cache.
|
|
103
|
-
#
|
|
104
|
-
# Purge the web cache via an API call.
|
|
105
|
-
#
|
|
106
|
-
# Returns a status message.
|
|
107
|
-
def purge_acquia_domain(subscription, environment, domain)
|
|
108
|
-
# Ensure all the required fields are available.
|
|
109
|
-
if subscription.nil? || environment.nil? || domain.nil?
|
|
110
|
-
fail "Purge request is missing a required parameter."
|
|
111
|
-
return
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
purge_request = acquia_api_call "sites/#{subscription}/envs/#{environment}/domains/#{domain}/cache", "DELETE"
|
|
115
|
-
success "#{domain} has been successfully purged." if purge_request["id"]
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Internal: Check whether a proxy is in use.
|
|
119
|
-
#
|
|
120
|
-
# Return boolean based on whether HTTPS_PROXY is set.
|
|
121
|
-
def using_proxy?
|
|
122
|
-
if ENV["HTTPS_PROXY"]
|
|
123
|
-
true
|
|
124
|
-
else
|
|
125
|
-
false
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# Internal: Output information on a database instance.
|
|
130
|
-
def output_database_instance(database)
|
|
131
|
-
say "> Username: #{database["username"]}"
|
|
132
|
-
say "> Password: #{database["password"]}"
|
|
133
|
-
say "> Host: #{database["host"]}"
|
|
134
|
-
say "> DB cluster: #{database["db_cluster"]}"
|
|
135
|
-
say "> Instance name: #{database["instance_name"]}"
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# Internal: Output information for a single task item.
|
|
139
|
-
def output_task_item(task)
|
|
140
|
-
completion_time = (task["completed"].to_i - task["started"].to_i) / 60
|
|
141
|
-
say
|
|
142
|
-
say "Task ID: #{task["id"].to_i}"
|
|
143
|
-
say "Description: #{task["description"]}"
|
|
144
|
-
say "Status: #{task["state"]}"
|
|
145
|
-
|
|
146
|
-
# If the completion time is greater then 0, output it in minutes otherwise
|
|
147
|
-
# just say it was less then a minute.
|
|
148
|
-
if completion_time > 0
|
|
149
|
-
say "Compeletion time: About #{completion_time} minutes"
|
|
150
|
-
else
|
|
151
|
-
say "Compeletion time: Less than 1 minute"
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
say "Queue: #{task["queue"]}"
|
|
155
|
-
end
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
# Public: Log into the Acquia Cloud API.
|
|
159
|
-
#
|
|
160
|
-
# This sets up the user account within the netrc file so that subsequent
|
|
161
|
-
# calls can reuse the authentication without the user being prompted for it.
|
|
162
|
-
#
|
|
163
|
-
# Returns the status of your login attempt.
|
|
164
|
-
desc "login", "Login to your Acquia account."
|
|
165
|
-
def login
|
|
166
|
-
user = ask "Enter your username:"
|
|
167
|
-
password = ask "Enter your password:"
|
|
168
|
-
|
|
169
|
-
# Update (or create if needed) the netrc file that will contain the user
|
|
170
|
-
# authentication details.
|
|
171
|
-
n = Netrc.read
|
|
172
|
-
n.new_item_prefix = "# This entry was added for connecting to the Acquia Cloud API\n"
|
|
173
|
-
n["cloudapi.acquia.com"] = user, password
|
|
174
|
-
n.save
|
|
175
|
-
|
|
176
|
-
success "Your user credentials have been successfully set."
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
# Public: Display an overview of the subscriptions.
|
|
180
|
-
#
|
|
181
|
-
# Returns all subscriptions with their respective data.
|
|
182
|
-
desc "list-subscriptions", "Find all subscriptions that you have access to."
|
|
183
|
-
def list_subscriptions
|
|
184
|
-
subscriptions = acquia_api_call "sites"
|
|
185
|
-
|
|
186
|
-
subscriptions.each do |subscription|
|
|
187
|
-
say
|
|
188
|
-
# Get the individual subscription information.
|
|
189
|
-
subscription_info = acquia_api_call "sites/#{subscription}"
|
|
190
|
-
say "#{subscription_info["title"]}"
|
|
191
|
-
say "> Username: #{subscription_info["unix_username"]}"
|
|
192
|
-
say "> Subscription: #{subscription_info["name"]}"
|
|
193
|
-
|
|
194
|
-
# If the VCS type is SVN, we want it in all uppercase, otherwise just
|
|
195
|
-
# capitilise it.
|
|
196
|
-
if subscription_info["vcs_type"] == 'svn'
|
|
197
|
-
say "> #{subscription_info["vcs_type"].upcase} URL: #{subscription_info["vcs_url"]}"
|
|
198
|
-
else
|
|
199
|
-
say "> #{subscription_info["vcs_type"].capitalize} URL: #{subscription_info["vcs_url"]}"
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
# Public: Provide an overview of the environments in your subscription.
|
|
205
|
-
#
|
|
206
|
-
# Returns the environment data in a pretty format.
|
|
207
|
-
desc "list-environments <subscription>", "Provide an overview of the environments in your subscription."
|
|
208
|
-
option :environment, :aliases => "-e"
|
|
209
|
-
def list_environments(subscription)
|
|
210
|
-
# If the environment option is set, just fetch a single environment.
|
|
211
|
-
if options[:environment]
|
|
212
|
-
subscription_envs = [options[:environment]]
|
|
213
|
-
else
|
|
214
|
-
subscription_envs = get_acquia_environments(subscription)
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
subscription_envs.each do |environment|
|
|
218
|
-
env_info = acquia_api_call "sites/#{subscription}/envs/#{environment}"
|
|
219
|
-
say
|
|
220
|
-
say "> Host: #{env_info["ssh_host"]}"
|
|
221
|
-
say "> Environment: #{env_info["name"]}"
|
|
222
|
-
say "> Current release: #{env_info["vcs_path"]}"
|
|
223
|
-
say "> DB clusters: #{env_info["db_clusters"].to_s unless env_info["db_clusters"].nil?}"
|
|
224
|
-
say "> Default domain: #{env_info["default_domain"]}"
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
# Public: Get server specs and information from an environment.
|
|
229
|
-
#
|
|
230
|
-
# This allows the ability to get all the server data from all server types
|
|
231
|
-
# that are available within the subscription's environments.
|
|
232
|
-
#
|
|
233
|
-
# Returns server information on a per environment basis.
|
|
234
|
-
desc "list-servers <subscription>", "Get a list of servers specifications for an environment."
|
|
235
|
-
option :environment, :aliases => "-e"
|
|
236
|
-
def list_servers(subscription)
|
|
237
|
-
# Determine if we want just a single environment, or all of them at once.
|
|
238
|
-
if options[:environment]
|
|
239
|
-
subscription_envs = [options[:environment]]
|
|
240
|
-
else
|
|
241
|
-
subscription_envs = get_acquia_environments(subscription)
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
# Loop over each environment and get all the associated server data.
|
|
245
|
-
subscription_envs.each do |environment|
|
|
246
|
-
if options[:environment].nil?
|
|
247
|
-
say
|
|
248
|
-
say "Environment: #{environment}"
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
server_env = acquia_api_call "sites/#{subscription}/envs/#{environment}/servers"
|
|
252
|
-
server_env.each do |server|
|
|
253
|
-
say
|
|
254
|
-
say "> Host: #{server["fqdn"]}"
|
|
255
|
-
say "> EC2 region: #{server["ec2_region"]}"
|
|
256
|
-
say "> Availability zone: #{server["ec2_availability_zone"]}"
|
|
257
|
-
say "> EC2 instance type: #{server["ami_type"]}"
|
|
258
|
-
|
|
259
|
-
# Show how many PHP processes this node can have. Note, this is only
|
|
260
|
-
# available on the web servers.
|
|
261
|
-
if server["services"] && server["services"]["php_max_procs"]
|
|
262
|
-
say "> PHP max processes: #{server["services"]["php_max_procs"]}"
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
if server["services"] && server["services"]["status"]
|
|
266
|
-
say "> Status: #{server["services"]["status"]}"
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
if server["services"] && server["services"]["web"]
|
|
270
|
-
say "> Web status: #{server["services"]["web"]["status"]}"
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
# The state of varnish.
|
|
274
|
-
if server["services"] && server["services"]["varnish"]
|
|
275
|
-
say "> Varnish status: #{server["services"]["varnish"]["status"]}"
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
# Only load balancers will have the "external IP" property.
|
|
279
|
-
if server["services"] && server["services"]["external_ip"]
|
|
280
|
-
say "> External IP: #{server["services"]["external_ip"]}"
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
# Public: Get information regarding the database instances.
|
|
287
|
-
#
|
|
288
|
-
# Within this method we have a few different options to get the information we
|
|
289
|
-
# require. If just an environment is passed, only the names are returned. Pass
|
|
290
|
-
# the environment param and the username, pasword, host, db cluster and
|
|
291
|
-
# instance name are returned for each database available. Passing a database
|
|
292
|
-
# name and the environment will only return that particular database.
|
|
293
|
-
#
|
|
294
|
-
# Returns database information.
|
|
295
|
-
desc "list-databases <subscription>", "See information about the databases within a subscription."
|
|
296
|
-
option :environment, :aliases => "-e"
|
|
297
|
-
option :database, :aliases => "-d"
|
|
298
|
-
def list_databases(subscription)
|
|
299
|
-
# If we have both the database name and environment, only fetch a single
|
|
300
|
-
# result.
|
|
301
|
-
if options[:database] && options[:environment]
|
|
302
|
-
database = acquia_api_call "sites/#{subscription}/envs/#{options[:environment]}/dbs/#{options[:database]}"
|
|
303
|
-
say
|
|
304
|
-
output_database_instance(database)
|
|
305
|
-
return
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
# Fetch all the databases in a specific environment.
|
|
309
|
-
if options[:environment]
|
|
310
|
-
databases = acquia_api_call "sites/#{subscription}/envs/#{options[:environment]}/dbs"
|
|
311
|
-
databases.each do |db|
|
|
312
|
-
say
|
|
313
|
-
say "#{db["name"]}"
|
|
314
|
-
output_database_instance(db)
|
|
315
|
-
end
|
|
316
|
-
else
|
|
317
|
-
subscription_envs = [options[:environment]]
|
|
318
|
-
databases = acquia_api_call "sites/#{subscription}/dbs"
|
|
319
|
-
|
|
320
|
-
say
|
|
321
|
-
databases.each do |db|
|
|
322
|
-
say "> #{db["name"]}"
|
|
323
|
-
end
|
|
324
|
-
end
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
# Public: List all backups for a database instance.
|
|
328
|
-
#
|
|
329
|
-
# Fetching all database backups for an instance is a pretty heavy call as the
|
|
330
|
-
# data isn't restricted in any way by time, id's, etc.
|
|
331
|
-
#
|
|
332
|
-
# Returns a database backup listing.
|
|
333
|
-
desc "list-database-backups <subscription> <environment> <database>", "Get all backups for a database instance."
|
|
334
|
-
def list_database_backups(subscription, environment, database)
|
|
335
|
-
backups = acquia_api_call "sites/#{subscription}/envs/#{environment}/dbs/#{database}/backups"
|
|
336
|
-
backups.each do |backup|
|
|
337
|
-
say
|
|
338
|
-
say "> ID: #{backup["id"]}"
|
|
339
|
-
say "> MD5: #{backup["checksum"]}"
|
|
340
|
-
say "> Type: #{backup["type"]}"
|
|
341
|
-
say "> Path: #{backup["path"]}"
|
|
342
|
-
say "> Link: #{backup["link"]}"
|
|
343
|
-
say "> Started: #{Time.at(backup["started"].to_i)}"
|
|
344
|
-
say "> Completed: #{Time.at(backup["completed"].to_i)}"
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
# Public: Create a new database instance.
|
|
349
|
-
#
|
|
350
|
-
# Returns a success message upon creation.
|
|
351
|
-
desc "add-database <subscription> <database>", "Create a new database instance."
|
|
352
|
-
def add_database(subscription, database)
|
|
353
|
-
add_database = acquia_api_call "sites/#{subscription}/dbs", "POST", :db => "#{database}"
|
|
354
|
-
success "A new database has been created." if add_database["id"]
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
# Public: Delete a database instance.
|
|
358
|
-
#
|
|
359
|
-
# Returns a status message based on the task completion.
|
|
360
|
-
desc "delete-database <subscription> <database>", "Remove all instances of a database."
|
|
361
|
-
def delete_database(subscription, database)
|
|
362
|
-
delete_db = acquia_api_call "sites/#{subscription}/dbs/#{database}?backup=0", "DELETE"
|
|
363
|
-
success "Database has been successfully deleted." if delete_db["id"]
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
# Public: Copy a database from one environment to another.
|
|
367
|
-
#
|
|
368
|
-
# Returns the status message.
|
|
369
|
-
desc "copy-database <subscription> <database> <source> <destination>", "Copy a database one from environment to another."
|
|
370
|
-
def copy_database(subscription, database, source, destination)
|
|
371
|
-
copy_database = acquia_api_call "sites/#{subscription}/dbs/#{database}/db-copy/#{source}/#{destination}", "POST"
|
|
372
|
-
success "Database #{database} has been copied from #{source} to #{destination}." if copy_database["id"]
|
|
373
|
-
end
|
|
374
|
-
|
|
375
|
-
# Public: Restore a previous database backup to a site.
|
|
376
|
-
#
|
|
377
|
-
# Returns a status message.
|
|
378
|
-
desc "restore-database-backup <subscription> <environment> <database> <backup_id>", "Restore a database backup."
|
|
379
|
-
def restore_database_backup(subscription, environment, database, backup_id)
|
|
380
|
-
restore_db = acquia_api_call "sites/#{subscription}/envs/#{environment}/dbs/#{database}/backups/#{backup_id}/restore", "POST"
|
|
381
|
-
success "Database backup #{backup_id} has been restored to #{database} in #{environment}." if restore_db["id"]
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
# Public: Show all the available domains for a subscription.
|
|
385
|
-
#
|
|
386
|
-
# Returns a list of the domains available.
|
|
387
|
-
desc "list-domains <subscription>", "Show all available domains for a subscription."
|
|
388
|
-
option :environment, :aliases => "-e"
|
|
389
|
-
def list_domains(subscription)
|
|
390
|
-
if options[:environment]
|
|
391
|
-
subscription_envs = [options[:environment]]
|
|
392
|
-
else
|
|
393
|
-
subscription_envs = get_acquia_environments(subscription)
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
subscription_envs.each do |environment|
|
|
397
|
-
domains = acquia_api_call "sites/#{subscription}/envs/#{environment}/domains"
|
|
398
|
-
# Got top padding?
|
|
399
|
-
if options[:environment]
|
|
400
|
-
say
|
|
401
|
-
else
|
|
402
|
-
say
|
|
403
|
-
say "Environment: #{environment}"
|
|
404
|
-
end
|
|
405
|
-
domains.each do |domain|
|
|
406
|
-
say "> #{domain["name"]}"
|
|
407
|
-
end
|
|
408
|
-
end
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
# Public: Add a domain to an environment.
|
|
412
|
-
#
|
|
413
|
-
# Returns a status message on successful addition.
|
|
414
|
-
desc "add-domain <subscription> <environment> <domain>", "Add a domain to an environment."
|
|
415
|
-
def add_domain(subscription, environment, domain)
|
|
416
|
-
add_domain = acquia_api_call "/sites/#{subscription}/envs/#{environment}/domains/#{domain}", "POST"
|
|
417
|
-
success "Domain #{domain} has been successfully added to #{environment}." if add_domain["id"]
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
# Public: Remove a domain from an environment.
|
|
421
|
-
#
|
|
422
|
-
# Returns a status message on successful deletion.
|
|
423
|
-
desc "delete-domain <subscription> <environment> <domain>", "Delete a domain from an environment."
|
|
424
|
-
def delete_domain(subscription, environment, domain)
|
|
425
|
-
delete_domain = acquia_api_call "/sites/#{subscription}/envs/#{environment}/domains/#{domain}", "DELETE"
|
|
426
|
-
success "Domain #{domain} has been successfully deleted from #{environment}." if delete_domain["id"]
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
# Public: Clear a web cache on a domain.
|
|
430
|
-
#
|
|
431
|
-
# Send off a DELETE request to clear the web cache for a particular domain or
|
|
432
|
-
# environment.
|
|
433
|
-
#
|
|
434
|
-
# Note: Clearing a whole environment is pretty performance heavy - use with
|
|
435
|
-
# caution!
|
|
436
|
-
#
|
|
437
|
-
# Returns a status message form the purge request.
|
|
438
|
-
desc "purge-domain <subscription> <environment>", "Clear the web cache of an environment or domain."
|
|
439
|
-
option :domain, :aliases => "-d"
|
|
440
|
-
def purge_domain(subscription, environment)
|
|
441
|
-
domain = options[:domain]
|
|
442
|
-
|
|
443
|
-
# If the domain is not defined, we are going to clear a whole environment.
|
|
444
|
-
# This can have severe performance impacts on your environments. We need to
|
|
445
|
-
# be sure this is definitely what you want to do.
|
|
446
|
-
if domain
|
|
447
|
-
purge_acquia_domain(subscription, environment, domain)
|
|
448
|
-
else
|
|
449
|
-
all_env_clear = ask "You are about to clear all domains in the #{environment} environment. Are you sure? (y/n)"
|
|
450
|
-
# Last chance to bail out.
|
|
451
|
-
if all_env_clear == "y"
|
|
452
|
-
domains = acquia_api_call "sites/#{subscription}/envs/#{environment}/domains"
|
|
453
|
-
domains.each do |domain|
|
|
454
|
-
purge_acquia_domain("#{subscription}", "#{environment}", "#{domain["name"]}")
|
|
455
|
-
end
|
|
456
|
-
else
|
|
457
|
-
info "Ok, no action has been taken."
|
|
458
|
-
end
|
|
459
|
-
end
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
# Public: Get all the SVN users.
|
|
463
|
-
#
|
|
464
|
-
# Returns a list of the SVN users.
|
|
465
|
-
desc "list-svn-users <subscription>", "See all the SVN users on a subscription."
|
|
466
|
-
def list_svn_users(subscription)
|
|
467
|
-
svn_users = acquia_api_call "sites/#{subscription}/svnusers"
|
|
468
|
-
|
|
469
|
-
svn_users.each do |user|
|
|
470
|
-
say
|
|
471
|
-
say "> ID: #{user["id"]}"
|
|
472
|
-
say "> Name: #{user["username"]}"
|
|
473
|
-
end
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
desc "delete-svn-user <subscription> <userid>", "Delete a SVN user."
|
|
477
|
-
def delete_svn_user(subscription, userid)
|
|
478
|
-
svn_user_removal = acquia_api_call "sites/#{subscription}/svnusers/#{userid}", "DELETE"
|
|
479
|
-
success "#{userid} has been removed from the SVN users." if svn_user_removal["id"]
|
|
480
|
-
end
|
|
481
|
-
|
|
482
|
-
# Public: Get users on the subscription.
|
|
483
|
-
#
|
|
484
|
-
# Display a user listing with a truncated SSH key for security and ease of
|
|
485
|
-
# use.
|
|
486
|
-
#
|
|
487
|
-
# Returns a list of users and truncated SSH keys.
|
|
488
|
-
desc "list-ssh-users <subscription>", "Find out who has access and SSH keys."
|
|
489
|
-
def list_ssh_users(subscription)
|
|
490
|
-
users = acquia_api_call "sites/#{subscription}/sshkeys"
|
|
491
|
-
|
|
492
|
-
users.each do |user|
|
|
493
|
-
say
|
|
494
|
-
say "> ID: #{user["id"]}"
|
|
495
|
-
say "> Name: #{user["nickname"]}"
|
|
496
|
-
say "> Key: #{truncate_ssh_key user["ssh_pub_key"]}"
|
|
497
|
-
end
|
|
498
|
-
end
|
|
499
|
-
|
|
500
|
-
# Public: Delete a SSH key from the subscription.
|
|
501
|
-
#
|
|
502
|
-
# Returns a status message.
|
|
503
|
-
desc "delete-ssh-user <subscription> <id>", "Delete a SSH key from the subscription."
|
|
504
|
-
def delete_ssh_user(subscription, id)
|
|
505
|
-
delete_ssh_request = acquia_api_call "sites/#{subscription}/sshkeys/#{id}", "DELETE"
|
|
506
|
-
success "SSH key #{id} has been successfully removed." if delete_ssh_request["id"]
|
|
507
|
-
end
|
|
508
|
-
|
|
509
|
-
# Public: Copy files from one environment to another.
|
|
510
|
-
#
|
|
511
|
-
# Returns a status message.
|
|
512
|
-
desc "copy-files <subscription> <source> <destination>", "Copy files from one environment to another."
|
|
513
|
-
def copy_files(subscription, source, destination)
|
|
514
|
-
file_copy = acquia_api_call "/sites/#{subscription}/files-copy/#{source}/#{target}", "POST"
|
|
515
|
-
success "File copy from #{source} to #{destination} has started." if file_copy["id"]
|
|
516
|
-
end
|
|
517
|
-
|
|
518
|
-
# Public: Deploy a VCS branch or tag to an environment.
|
|
519
|
-
#
|
|
520
|
-
# NB: Unfortunately the API endpoint for this functionality is formed a little
|
|
521
|
-
# differently to the others. It requires that the VCS path is appended to the
|
|
522
|
-
# URL compared to plain old POST request with parameters as a payload. To
|
|
523
|
-
# combat this, a pseudo request is made. It is a POST request at heart, just
|
|
524
|
-
# named differently to allow this functionality to be separated out.
|
|
525
|
-
#
|
|
526
|
-
# Returns a status message string.
|
|
527
|
-
desc "deploy-code <subscription> <environment> <release>", "Deploy a specific VCS branch or tag to an environment."
|
|
528
|
-
def deploy_code(subscription, environment, release)
|
|
529
|
-
deploy_code = acquia_api_call "sites/#{subscription}/envs/#{environment}/code-deploy", "CODE-DEPLOY-POST", :release => "#{release}"
|
|
530
|
-
success "#{release} has been deployed to #{environment}." if deploy_code["id"]
|
|
531
|
-
end
|
|
532
|
-
|
|
533
|
-
# Public: Show tasks for a subscription.
|
|
534
|
-
#
|
|
535
|
-
# Returns a listing of tasks for a subscription.
|
|
536
|
-
desc "list-tasks <subscription>", "Display tasks associated with a subscription."
|
|
537
|
-
option :count, :aliases => "-c"
|
|
538
|
-
option :queue, :aliases => "-q"
|
|
539
|
-
def list_tasks(subscription)
|
|
540
|
-
all_tasks = acquia_api_call "sites/#{subscription}/tasks"
|
|
541
|
-
tasks = []
|
|
542
|
-
|
|
543
|
-
# Fetch a single queue from the tasks list if the queue parameter is set
|
|
544
|
-
# otherwise just add all the tasks.
|
|
545
|
-
if options[:queue]
|
|
546
|
-
all_tasks.each do |task|
|
|
547
|
-
if task["queue"] == options[:queue]
|
|
548
|
-
tasks << task
|
|
549
|
-
end
|
|
550
|
-
end
|
|
551
|
-
else
|
|
552
|
-
all_tasks.each do |task|
|
|
553
|
-
tasks << task
|
|
554
|
-
end
|
|
555
|
-
end
|
|
556
|
-
|
|
557
|
-
# If there is a count to return, restrict it to that required amount.
|
|
558
|
-
if options[:count] && tasks.any?
|
|
559
|
-
tasks = tasks.last(options[:count].to_i)
|
|
560
|
-
end
|
|
561
|
-
|
|
562
|
-
tasks.each do |task|
|
|
563
|
-
output_task_item(task)
|
|
564
|
-
end
|
|
565
|
-
end
|
|
5
|
+
begin
|
|
6
|
+
AcquiaToolbelt::CLI.start
|
|
7
|
+
rescue
|
|
8
|
+
exit(1)
|
|
566
9
|
end
|
|
567
|
-
|
|
568
|
-
Acquia.start
|