bin/acquia in acquia_toolbelt-1.5.1 vs bin/acquia in acquia_toolbelt-2.0.0
- old
+ new
@@ -1,568 +1,9 @@
#!/usr/bin/env ruby
+$:.unshift(File.expand_path('../../lib', __FILE__))
+require 'acquia_toolbelt/cli'
-require "thor"
-require "netrc"
-require "highline/import"
-require "faraday"
-require "json"
-require "rainbow"
-
-class Acquia < Thor
- # A no_commands block is designed to show the methods that cannot be invoked
- # and as such, do not have a description.
- no_commands {
- # Internal: Used for outputting a pretty success message.
- #
- # Returns the coloured and formatted string.
- def success(text)
- puts "#{text}".foreground(:green)
- end
-
- # Internal: Used for outputting a pretty error message.
- #
- # Returns the coloured and formatted string.
- def fail(text)
- puts "#{text}".foreground(:red)
- end
-
- # Internal: Used for outputting a pretty info message.
- #
- # Returns the coloured and formatted string.
- def info(text)
- puts "#{text}".foreground(:cyan)
- end
-
- # Internal: Create a request to the Acquia API.
- #
- # The request generated contains all the correct user authentication and
- # headers.
- #
- # Returns a JSON string of the body.
- def acquia_api_call(resource, method = "GET", data = {})
- n = Netrc.read
- @acquia_user, @acquia_password = n["cloudapi.acquia.com"]
-
- # Check if the user is behind a proxy and add the proxy settings if found.
- if using_proxy?
- conn = Faraday.new(:proxy => ENV["HTTPS_PROXY"])
- else
- conn = Faraday.new
- end
-
- conn.basic_auth(@acquia_user, @acquia_password)
-
- case method
- when "GET"
- response = conn.get "https://cloudapi.acquia.com/v1/#{resource}.json"
- JSON.parse response.body
- when "POST"
- response = conn.post "https://cloudapi.acquia.com/v1/#{resource}.json", data.to_json
- JSON.parse response.body
- when "CODE-DEPLOY-POST"
- response = conn.post "https://cloudapi.acquia.com/v1/#{resource}.json?path=#{data[:release]}"
- JSON.parse response.body
- when "DELETE"
- response = conn.delete "https://cloudapi.acquia.com/v1/#{resource}.json"
- JSON.parse response.body
- else
- end
- end
-
- # Internal: Get defined subscription environments.
- #
- # This is a helper method that fetches all the available environments for a
- # subscription and returns them for use in other methods.
- #
- # Returns an array of environments.
- def get_acquia_environments(subscription)
- env_data = acquia_api_call "sites/#{subscription}/envs"
-
- envs = []
- env_data.each do |env|
- envs << env["name"]
- end
-
- envs
- end
-
- # Internal: Truncate a SSH key to a secure and recognisable size.
- #
- # Displaying whole SSH keys is probably a bad idea so instead we are getting
- # the first 30 characters and the last 100 characters of the key and
- # separating them with an ellipis. This allows you to recognise the
- # important parts of the key instead of the whole thing.
- #
- # Returns string.
- def truncate_ssh_key(ssh_key)
- front_part = ssh_key[0...30]
- back_part = ssh_key[-50, 50]
- new_ssh_key = "#{front_part}...#{back_part}"
- end
-
- # Internal: Send a request to purge a domain's cache.
- #
- # Purge the web cache via an API call.
- #
- # Returns a status message.
- def purge_acquia_domain(subscription, environment, domain)
- # Ensure all the required fields are available.
- if subscription.nil? || environment.nil? || domain.nil?
- fail "Purge request is missing a required parameter."
- return
- end
-
- purge_request = acquia_api_call "sites/#{subscription}/envs/#{environment}/domains/#{domain}/cache", "DELETE"
- success "#{domain} has been successfully purged." if purge_request["id"]
- end
-
- # Internal: Check whether a proxy is in use.
- #
- # Return boolean based on whether HTTPS_PROXY is set.
- def using_proxy?
- if ENV["HTTPS_PROXY"]
- true
- else
- false
- end
- end
-
- # Internal: Output information on a database instance.
- def output_database_instance(database)
- say "> Username: #{database["username"]}"
- say "> Password: #{database["password"]}"
- say "> Host: #{database["host"]}"
- say "> DB cluster: #{database["db_cluster"]}"
- say "> Instance name: #{database["instance_name"]}"
- end
-
- # Internal: Output information for a single task item.
- def output_task_item(task)
- completion_time = (task["completed"].to_i - task["started"].to_i) / 60
- say
- say "Task ID: #{task["id"].to_i}"
- say "Description: #{task["description"]}"
- say "Status: #{task["state"]}"
-
- # If the completion time is greater then 0, output it in minutes otherwise
- # just say it was less then a minute.
- if completion_time > 0
- say "Compeletion time: About #{completion_time} minutes"
- else
- say "Compeletion time: Less than 1 minute"
- end
-
- say "Queue: #{task["queue"]}"
- end
- }
-
- # Public: Log into the Acquia Cloud API.
- #
- # This sets up the user account within the netrc file so that subsequent
- # calls can reuse the authentication without the user being prompted for it.
- #
- # Returns the status of your login attempt.
- desc "login", "Login to your Acquia account."
- def login
- user = ask "Enter your username:"
- password = ask "Enter your password:"
-
- # Update (or create if needed) the netrc file that will contain the user
- # authentication details.
- n = Netrc.read
- n.new_item_prefix = "# This entry was added for connecting to the Acquia Cloud API\n"
- n["cloudapi.acquia.com"] = user, password
- n.save
-
- success "Your user credentials have been successfully set."
- end
-
- # Public: Display an overview of the subscriptions.
- #
- # Returns all subscriptions with their respective data.
- desc "list-subscriptions", "Find all subscriptions that you have access to."
- def list_subscriptions
- subscriptions = acquia_api_call "sites"
-
- subscriptions.each do |subscription|
- say
- # Get the individual subscription information.
- subscription_info = acquia_api_call "sites/#{subscription}"
- say "#{subscription_info["title"]}"
- say "> Username: #{subscription_info["unix_username"]}"
- say "> Subscription: #{subscription_info["name"]}"
-
- # If the VCS type is SVN, we want it in all uppercase, otherwise just
- # capitilise it.
- if subscription_info["vcs_type"] == 'svn'
- say "> #{subscription_info["vcs_type"].upcase} URL: #{subscription_info["vcs_url"]}"
- else
- say "> #{subscription_info["vcs_type"].capitalize} URL: #{subscription_info["vcs_url"]}"
- end
- end
- end
-
- # Public: Provide an overview of the environments in your subscription.
- #
- # Returns the environment data in a pretty format.
- desc "list-environments <subscription>", "Provide an overview of the environments in your subscription."
- option :environment, :aliases => "-e"
- def list_environments(subscription)
- # If the environment option is set, just fetch a single environment.
- if options[:environment]
- subscription_envs = [options[:environment]]
- else
- subscription_envs = get_acquia_environments(subscription)
- end
-
- subscription_envs.each do |environment|
- env_info = acquia_api_call "sites/#{subscription}/envs/#{environment}"
- say
- say "> Host: #{env_info["ssh_host"]}"
- say "> Environment: #{env_info["name"]}"
- say "> Current release: #{env_info["vcs_path"]}"
- say "> DB clusters: #{env_info["db_clusters"].to_s unless env_info["db_clusters"].nil?}"
- say "> Default domain: #{env_info["default_domain"]}"
- end
- end
-
- # Public: Get server specs and information from an environment.
- #
- # This allows the ability to get all the server data from all server types
- # that are available within the subscription's environments.
- #
- # Returns server information on a per environment basis.
- desc "list-servers <subscription>", "Get a list of servers specifications for an environment."
- option :environment, :aliases => "-e"
- def list_servers(subscription)
- # Determine if we want just a single environment, or all of them at once.
- if options[:environment]
- subscription_envs = [options[:environment]]
- else
- subscription_envs = get_acquia_environments(subscription)
- end
-
- # Loop over each environment and get all the associated server data.
- subscription_envs.each do |environment|
- if options[:environment].nil?
- say
- say "Environment: #{environment}"
- end
-
- server_env = acquia_api_call "sites/#{subscription}/envs/#{environment}/servers"
- server_env.each do |server|
- say
- say "> Host: #{server["fqdn"]}"
- say "> EC2 region: #{server["ec2_region"]}"
- say "> Availability zone: #{server["ec2_availability_zone"]}"
- say "> EC2 instance type: #{server["ami_type"]}"
-
- # Show how many PHP processes this node can have. Note, this is only
- # available on the web servers.
- if server["services"] && server["services"]["php_max_procs"]
- say "> PHP max processes: #{server["services"]["php_max_procs"]}"
- end
-
- if server["services"] && server["services"]["status"]
- say "> Status: #{server["services"]["status"]}"
- end
-
- if server["services"] && server["services"]["web"]
- say "> Web status: #{server["services"]["web"]["status"]}"
- end
-
- # The state of varnish.
- if server["services"] && server["services"]["varnish"]
- say "> Varnish status: #{server["services"]["varnish"]["status"]}"
- end
-
- # Only load balancers will have the "external IP" property.
- if server["services"] && server["services"]["external_ip"]
- say "> External IP: #{server["services"]["external_ip"]}"
- end
- end
- end
- end
-
- # Public: Get information regarding the database instances.
- #
- # Within this method we have a few different options to get the information we
- # require. If just an environment is passed, only the names are returned. Pass
- # the environment param and the username, pasword, host, db cluster and
- # instance name are returned for each database available. Passing a database
- # name and the environment will only return that particular database.
- #
- # Returns database information.
- desc "list-databases <subscription>", "See information about the databases within a subscription."
- option :environment, :aliases => "-e"
- option :database, :aliases => "-d"
- def list_databases(subscription)
- # If we have both the database name and environment, only fetch a single
- # result.
- if options[:database] && options[:environment]
- database = acquia_api_call "sites/#{subscription}/envs/#{options[:environment]}/dbs/#{options[:database]}"
- say
- output_database_instance(database)
- return
- end
-
- # Fetch all the databases in a specific environment.
- if options[:environment]
- databases = acquia_api_call "sites/#{subscription}/envs/#{options[:environment]}/dbs"
- databases.each do |db|
- say
- say "#{db["name"]}"
- output_database_instance(db)
- end
- else
- subscription_envs = [options[:environment]]
- databases = acquia_api_call "sites/#{subscription}/dbs"
-
- say
- databases.each do |db|
- say "> #{db["name"]}"
- end
- end
- end
-
- # Public: List all backups for a database instance.
- #
- # Fetching all database backups for an instance is a pretty heavy call as the
- # data isn't restricted in any way by time, id's, etc.
- #
- # Returns a database backup listing.
- desc "list-database-backups <subscription> <environment> <database>", "Get all backups for a database instance."
- def list_database_backups(subscription, environment, database)
- backups = acquia_api_call "sites/#{subscription}/envs/#{environment}/dbs/#{database}/backups"
- backups.each do |backup|
- say
- say "> ID: #{backup["id"]}"
- say "> MD5: #{backup["checksum"]}"
- say "> Type: #{backup["type"]}"
- say "> Path: #{backup["path"]}"
- say "> Link: #{backup["link"]}"
- say "> Started: #{Time.at(backup["started"].to_i)}"
- say "> Completed: #{Time.at(backup["completed"].to_i)}"
- end
- end
-
- # Public: Create a new database instance.
- #
- # Returns a success message upon creation.
- desc "add-database <subscription> <database>", "Create a new database instance."
- def add_database(subscription, database)
- add_database = acquia_api_call "sites/#{subscription}/dbs", "POST", :db => "#{database}"
- success "A new database has been created." if add_database["id"]
- end
-
- # Public: Delete a database instance.
- #
- # Returns a status message based on the task completion.
- desc "delete-database <subscription> <database>", "Remove all instances of a database."
- def delete_database(subscription, database)
- delete_db = acquia_api_call "sites/#{subscription}/dbs/#{database}?backup=0", "DELETE"
- success "Database has been successfully deleted." if delete_db["id"]
- end
-
- # Public: Copy a database from one environment to another.
- #
- # Returns the status message.
- desc "copy-database <subscription> <database> <source> <destination>", "Copy a database one from environment to another."
- def copy_database(subscription, database, source, destination)
- copy_database = acquia_api_call "sites/#{subscription}/dbs/#{database}/db-copy/#{source}/#{destination}", "POST"
- success "Database #{database} has been copied from #{source} to #{destination}." if copy_database["id"]
- end
-
- # Public: Restore a previous database backup to a site.
- #
- # Returns a status message.
- desc "restore-database-backup <subscription> <environment> <database> <backup_id>", "Restore a database backup."
- def restore_database_backup(subscription, environment, database, backup_id)
- restore_db = acquia_api_call "sites/#{subscription}/envs/#{environment}/dbs/#{database}/backups/#{backup_id}/restore", "POST"
- success "Database backup #{backup_id} has been restored to #{database} in #{environment}." if restore_db["id"]
- end
-
- # Public: Show all the available domains for a subscription.
- #
- # Returns a list of the domains available.
- desc "list-domains <subscription>", "Show all available domains for a subscription."
- option :environment, :aliases => "-e"
- def list_domains(subscription)
- if options[:environment]
- subscription_envs = [options[:environment]]
- else
- subscription_envs = get_acquia_environments(subscription)
- end
-
- subscription_envs.each do |environment|
- domains = acquia_api_call "sites/#{subscription}/envs/#{environment}/domains"
- # Got top padding?
- if options[:environment]
- say
- else
- say
- say "Environment: #{environment}"
- end
- domains.each do |domain|
- say "> #{domain["name"]}"
- end
- end
- end
-
- # Public: Add a domain to an environment.
- #
- # Returns a status message on successful addition.
- desc "add-domain <subscription> <environment> <domain>", "Add a domain to an environment."
- def add_domain(subscription, environment, domain)
- add_domain = acquia_api_call "/sites/#{subscription}/envs/#{environment}/domains/#{domain}", "POST"
- success "Domain #{domain} has been successfully added to #{environment}." if add_domain["id"]
- end
-
- # Public: Remove a domain from an environment.
- #
- # Returns a status message on successful deletion.
- desc "delete-domain <subscription> <environment> <domain>", "Delete a domain from an environment."
- def delete_domain(subscription, environment, domain)
- delete_domain = acquia_api_call "/sites/#{subscription}/envs/#{environment}/domains/#{domain}", "DELETE"
- success "Domain #{domain} has been successfully deleted from #{environment}." if delete_domain["id"]
- end
-
- # Public: Clear a web cache on a domain.
- #
- # Send off a DELETE request to clear the web cache for a particular domain or
- # environment.
- #
- # Note: Clearing a whole environment is pretty performance heavy - use with
- # caution!
- #
- # Returns a status message form the purge request.
- desc "purge-domain <subscription> <environment>", "Clear the web cache of an environment or domain."
- option :domain, :aliases => "-d"
- def purge_domain(subscription, environment)
- domain = options[:domain]
-
- # If the domain is not defined, we are going to clear a whole environment.
- # This can have severe performance impacts on your environments. We need to
- # be sure this is definitely what you want to do.
- if domain
- purge_acquia_domain(subscription, environment, domain)
- else
- all_env_clear = ask "You are about to clear all domains in the #{environment} environment. Are you sure? (y/n)"
- # Last chance to bail out.
- if all_env_clear == "y"
- domains = acquia_api_call "sites/#{subscription}/envs/#{environment}/domains"
- domains.each do |domain|
- purge_acquia_domain("#{subscription}", "#{environment}", "#{domain["name"]}")
- end
- else
- info "Ok, no action has been taken."
- end
- end
- end
-
- # Public: Get all the SVN users.
- #
- # Returns a list of the SVN users.
- desc "list-svn-users <subscription>", "See all the SVN users on a subscription."
- def list_svn_users(subscription)
- svn_users = acquia_api_call "sites/#{subscription}/svnusers"
-
- svn_users.each do |user|
- say
- say "> ID: #{user["id"]}"
- say "> Name: #{user["username"]}"
- end
- end
-
- desc "delete-svn-user <subscription> <userid>", "Delete a SVN user."
- def delete_svn_user(subscription, userid)
- svn_user_removal = acquia_api_call "sites/#{subscription}/svnusers/#{userid}", "DELETE"
- success "#{userid} has been removed from the SVN users." if svn_user_removal["id"]
- end
-
- # Public: Get users on the subscription.
- #
- # Display a user listing with a truncated SSH key for security and ease of
- # use.
- #
- # Returns a list of users and truncated SSH keys.
- desc "list-ssh-users <subscription>", "Find out who has access and SSH keys."
- def list_ssh_users(subscription)
- users = acquia_api_call "sites/#{subscription}/sshkeys"
-
- users.each do |user|
- say
- say "> ID: #{user["id"]}"
- say "> Name: #{user["nickname"]}"
- say "> Key: #{truncate_ssh_key user["ssh_pub_key"]}"
- end
- end
-
- # Public: Delete a SSH key from the subscription.
- #
- # Returns a status message.
- desc "delete-ssh-user <subscription> <id>", "Delete a SSH key from the subscription."
- def delete_ssh_user(subscription, id)
- delete_ssh_request = acquia_api_call "sites/#{subscription}/sshkeys/#{id}", "DELETE"
- success "SSH key #{id} has been successfully removed." if delete_ssh_request["id"]
- end
-
- # Public: Copy files from one environment to another.
- #
- # Returns a status message.
- desc "copy-files <subscription> <source> <destination>", "Copy files from one environment to another."
- def copy_files(subscription, source, destination)
- file_copy = acquia_api_call "/sites/#{subscription}/files-copy/#{source}/#{target}", "POST"
- success "File copy from #{source} to #{destination} has started." if file_copy["id"]
- end
-
- # Public: Deploy a VCS branch or tag to an environment.
- #
- # NB: Unfortunately the API endpoint for this functionality is formed a little
- # differently to the others. It requires that the VCS path is appended to the
- # URL compared to plain old POST request with parameters as a payload. To
- # combat this, a pseudo request is made. It is a POST request at heart, just
- # named differently to allow this functionality to be separated out.
- #
- # Returns a status message string.
- desc "deploy-code <subscription> <environment> <release>", "Deploy a specific VCS branch or tag to an environment."
- def deploy_code(subscription, environment, release)
- deploy_code = acquia_api_call "sites/#{subscription}/envs/#{environment}/code-deploy", "CODE-DEPLOY-POST", :release => "#{release}"
- success "#{release} has been deployed to #{environment}." if deploy_code["id"]
- end
-
- # Public: Show tasks for a subscription.
- #
- # Returns a listing of tasks for a subscription.
- desc "list-tasks <subscription>", "Display tasks associated with a subscription."
- option :count, :aliases => "-c"
- option :queue, :aliases => "-q"
- def list_tasks(subscription)
- all_tasks = acquia_api_call "sites/#{subscription}/tasks"
- tasks = []
-
- # Fetch a single queue from the tasks list if the queue parameter is set
- # otherwise just add all the tasks.
- if options[:queue]
- all_tasks.each do |task|
- if task["queue"] == options[:queue]
- tasks << task
- end
- end
- else
- all_tasks.each do |task|
- tasks << task
- end
- end
-
- # If there is a count to return, restrict it to that required amount.
- if options[:count] && tasks.any?
- tasks = tasks.last(options[:count].to_i)
- end
-
- tasks.each do |task|
- output_task_item(task)
- end
- end
+begin
+ AcquiaToolbelt::CLI.start
+rescue
+ exit(1)
end
-
-Acquia.start