Пример #1
0
 /**
  * List an organization's sites
  *
  * ## OPTIONS
  *
  * <add|remove|list>
  * : subfunction to run
  *
  * [--org=<id|name>]
  * : Organization UUID or name
  *
  * [--tag=<tag>]
  * : Tag name to filter sites list by
  *
  * [--site=<site>]
  * : Site to add to or remove from organization
  *
  * @subcommand sites
  *
  */
 public function sites($args, $assoc_args)
 {
     $action = array_shift($args);
     $org_id = Input::orgid($assoc_args, 'org', null, array('allow_none' => false));
     $orgs = new UserOrganizationMemberships();
     $org = $orgs->get($org_id);
     $org_info = $org->get('organization');
     $memberships = $org->site_memberships->all();
     switch ($action) {
         case 'add':
             if (isset($assoc_args['site'])) {
                 if ($this->siteIsMember($memberships, $assoc_args['site'])) {
                     $this->failure('{site} is already a member of {org}', array('site' => $assoc_args['site'], 'org' => $org_info->profile->name));
                 } else {
                     $site = $this->sites->get($assoc_args['site']);
                 }
             } else {
                 $site = $this->sites->get(Input::menu($this->getNonmemberSiteList($memberships), null, 'Choose site'));
             }
             Terminus::confirm('Are you sure you want to add %s to %s ?', array($site->get('name'), $org_info->profile->name));
             $workflow = $org->site_memberships->addMember($site);
             $workflow->wait();
             $this->workflowOutput($workflow);
             break;
         case 'remove':
             if (isset($assoc_args['site'])) {
                 if (!$this->siteIsMember($memberships, $assoc_args['site'])) {
                     $this->failure('{site} is not a member of {org}', array('site' => $assoc_args['site'], 'org' => $org_info->profile->name));
                 } else {
                     $site = $this->sites->get($assoc_args['site']);
                 }
             } else {
                 $site = $this->sites->get(Input::menu($this->getMemberSiteList($memberships), null, 'Choose site'));
             }
             $member = $org->site_memberships->get($site->get('id'));
             Terminus::confirm('Are you sure you want to remove %s from %s ?', array($site->get('name'), $org_info->profile->name));
             $workflow = $member->removeMember();
             $workflow->wait();
             $this->workflowOutput($workflow);
             break;
         case 'list':
         default:
             foreach ($memberships as $membership) {
                 if (isset($assoc_args['tag']) && !in_array($assoc_args['tag'], $membership->get('tags'))) {
                     continue;
                 }
                 $site = $membership->get('site');
                 $data_array = array('name' => null, 'id' => null, 'service_level' => null, 'framework' => null, 'created' => null, 'tags' => $membership->get('tags'));
                 foreach ($data_array as $key => $value) {
                     if ($value == null && isset($site->{$key})) {
                         $data_array[$key] = $site->{$key};
                     }
                 }
                 $data_array['created'] = date('Y-m-dTH:i:s', $data_array['created']);
                 $data[] = $data_array;
             }
             $this->output()->outputRecordList($data);
             break;
     }
 }
Пример #2
0
 /**
  * Helper function to get role
  *
  * @param [array]  $assoc_args Argument array passed from commands
  * @param [string] $message Prompt to STDOUT
  * @return [string] $role Name of role
  */
 public static function role($assoc_args, $message = 'Select a role for this member')
 {
     $roles = array('developer', 'team_member', 'admin');
     if (!isset($assoc_args['role']) || !in_array(strtolower($assoc_args['role']), $roles)) {
         $role = strtolower($roles[Input::menu($roles, null, 'Select a role for the new member')]);
     } else {
         $role = $assoc_args['role'];
     }
     return $role;
 }
Пример #3
0
 /**
  * Manage site organization tags
  *
  * ## OPTIONS
  *
  * <add|remove|list>
  * : subfunction to run
  *
  * [--site=<site>]
  * : Site's name
  *
  * [--org=<name|id>]
  * : Organization to apply tag with
  *
  * [--tag=<tag>]
  * : Tag to add or remove
  *
  * @subcommand tags
  */
 public function tags($args, $assoc_args)
 {
     $action = array_shift($args);
     $site = $this->sites->get(Input::sitename($assoc_args));
     $org = Input::orgid($assoc_args, 'org');
     if ($site->organizationIsMember($org)) {
         switch ($action) {
             case 'add':
                 $tag = Input::string($assoc_args, 'tag', 'Enter a tag to add');
                 $response = $site->addTag($tag, $org);
                 $context = array('tag' => $tag, 'site' => $site->get('name'));
                 if ($response['status_code'] == 200) {
                     $this->log()->info('Tag "{tag}" has been added to {site}', $context);
                 } else {
                     $this->failure('Tag "{tag}" could not be added to {site}', $context);
                 }
                 break;
             case 'remove':
                 $tags = $site->getTags($org);
                 if (count($tags) === 0) {
                     $message = 'This organization does not have any tags associated';
                     $message .= ' with this site.';
                     $this->failure($message);
                 } elseif (!isset($assoc_args['tag']) || !in_array($assoc_args['tag'], $tags)) {
                     $tag = $tags[Input::menu($tags, null, 'Select a tag to delete')];
                 } else {
                     $tag = $assoc_args['tag'];
                 }
                 $response = $site->removeTag($tag, $org);
                 $context = array('tag' => $tag, 'site' => $site->get('name'));
                 if ($response['status_code'] == 200) {
                     $this->log()->info('Tag "{tag}" has been removed from {site}', $context);
                 } else {
                     $this->failure('Tag "{tag}" could not be removed from {site}', $context);
                 }
                 break;
             case 'list':
             default:
                 $tags = $site->getTags($org);
                 $this->output()->outputRecord(compact('tags'));
                 break;
         }
     } else {
         $message = '{site} is not a member of an organization,';
         $message .= ' which is necessary to associate a tag with a site.';
         $this->failure($message, array('site' => $site->get('name')));
     }
 }
Пример #4
0
 /**
  * Get, load, create, or list backup information
  *
  * ## OPTIONS
  *
  * <get|load|create|list>
  * : function to run - get, load, create, or list
  *
  * [--site=<site>]
  * : Site to load
  *
  * [--env=<env>]
  * : Environment to load
  *
  * [--element=<code|files|db|all>]
  * : Element to download or create. *all* only used for the 'create'
  *
  * [--to-directory=<directory>]
  * : Download the file if set
  *
  * [--latest]
  * : if set no the latest backup will be selected automatically
  *
  * [--keep-for]
  * : number of days to keep this backup. 
  *
  * @subcommand backup
  *
  */
 public function backup($args, $assoc_args)
 {
     $action = array_shift($args);
     $site = SiteFactory::instance(Input::site($assoc_args));
     $env = Input::env($assoc_args, 'env');
     switch ($action) {
         case 'get':
             // prompt for backup type
             if (!($element = @$assoc_args['element'])) {
                 $element = Terminus::menu(array('code', 'files', 'database'), null, "Select type backup", TRUE);
             }
             if (!in_array($element, array('code', 'files', 'database'))) {
                 Terminus::error("Invalid backup element specified.");
             }
             $latest = Input::optional('latest', $assoc_args, false);
             $backups = $site->environment($env)->backups($element, $latest);
             if (empty($backups)) {
                 \Terminus::error('No backups available.');
             }
             $menu = $folders = array();
             // build a menu for selecting back ups
             foreach ($backups as $folder => $backup) {
                 if (!isset($backup->filename)) {
                     continue;
                 }
                 if (!isset($backup->folder)) {
                     $backup->folder = $folder;
                 }
                 $buckets[] = $backup->folder;
                 $menu[] = $backup->filename;
             }
             if (empty($menu)) {
                 Terminus::error("No backups available. Create one with `terminus site backup create --site=%s --env=%s`", array($site->getName(), $env));
             }
             $index = 0;
             if (!$latest) {
                 $index = Terminus::menu($menu, null, "Select backup");
             }
             $bucket = $buckets[$index];
             $filename = $menu[$index];
             $url = $site->environment($env)->backupUrl($bucket, $element);
             if (isset($assoc_args['to-directory'])) {
                 Terminus::line("Downloading ... please wait ...");
                 $filename = \Terminus\Utils\get_filename_from_url($url->url);
                 $target = sprintf("%s/%s", $assoc_args['to-directory'], $filename);
                 if (Terminus_Command::download($url->url, $target)) {
                     Terminus::success("Downloaded %s", $target);
                     return $target;
                 } else {
                     Terminus::error("Could not download file");
                 }
             }
             echo $url->url;
             return $url->url;
             break;
         case 'load':
             $assoc_args['to-directory'] = '/tmp';
             $assoc_args['element'] = 'database';
             $database = @$assoc_args['database'] ?: false;
             $username = @$assoc_args['username'] ?: false;
             $password = @$assoc_args['password'] ?: false;
             exec("mysql -e 'show databases'", $stdout, $exit);
             if (0 != $exit) {
                 Terminus::error("MySQL does not appear to be installed on your server.");
             }
             $assoc_args['env'] = $env;
             $target = $this->backup(array('get'), $assoc_args);
             $target = \Terminus\Utils\get_filename_from_url($target);
             $target = "/tmp/{$target}";
             if (!file_exists($target)) {
                 Terminus::error("Can't read database file %s", array($target));
             }
             Terminus::line("Unziping database");
             exec("gunzip {$target}", $stdout, $exit);
             // trim the gz of the target
             $target = Terminus\Utils\sql_from_zip($target);
             $target = escapeshellarg($target);
             if (!$database) {
                 $database = escapeshellarg(Terminus::prompt("Name of database to import to"));
             }
             if (!$username) {
                 $username = escapeshellarg(Terminus::prompt("Username"));
             }
             if (!$password) {
                 $password = escapeshellarg(Terminus::prompt("Password"));
             }
             exec("mysql {$database} -u {$username} -p'{$password}' < {$target}", $stdout, $exit);
             if (0 != $exit) {
                 Terminus::error("Could not import database");
             }
             Terminus::success("%s successfuly imported to %s", array($target, $database));
             return true;
             break;
         case 'create':
             if (!array_key_exists('element', $assoc_args)) {
                 $assoc_args['element'] = Input::menu(array('code', 'db', 'files', 'all'), 'all', "Select element");
             }
             $result = $site->environment($env)->createBackup($assoc_args);
             if ($result) {
                 Terminus::success("Created backup");
             } else {
                 Terminus::error("Couldn't create backup.");
             }
             break;
         case 'list':
         case 'default':
             $backups = $site->environment($env)->backups();
             $element = @$assoc_args['element'];
             $data = array();
             foreach ($backups as $id => $backup) {
                 if (!isset($backup->filename)) {
                     continue;
                 }
                 $data[] = array($backup->filename, sprintf("%dMB", $backup->size / 1024 / 1024), date("Y-m-d H:i:s", $backup->finish_time));
             }
             if (empty($backups)) {
                 \Terminus::error("No backups found.");
                 return false;
             } else {
                 //munging data
                 $this->handleDisplay($data, $args, array('File', 'Size', 'Date'));
                 return $data;
             }
             break;
     }
 }
Пример #5
0
 /**
  * Import a zip archive == see this article for more info:
  * http://helpdesk.getpantheon.com/customer/portal/articles/1458058-importing-a-wordpress-site
  *
  * ## OPTIONS
  *
  * [--site=<site>]
  * : Site to use
  *
  * [--url=<url>]
  * : URL of archive to import
  *
  * [--element=<element>]
  * : Site element to import (i.e. code, files, db, or all)
  *
  * @subcommand import
  */
 public function import($args, $assoc_args)
 {
     $site = SiteFactory::instance(Input::site($assoc_args));
     $url = Input::string($assoc_args, 'url', "URL of archive to import");
     if (!$url) {
         Terminus::error("Please enter a URL.");
     }
     if (!isset($assoc_args['element'])) {
         $element_options = array('code', 'database', 'files', 'all');
         $element_key = Input::menu($element_options, 'all', 'Which element are you importing?');
         $element = $element_options[$element_key];
     } else {
         $element = $assoc_args['element'];
     }
     $import = $site->import($url, $element);
     if ($import) {
         Terminus::line('Import started, you can now safely kill this script without interfering.');
         $result = $this->waitOnWorkflow('sites', $site->getId(), $import->id);
         if ($result->result !== 'succeeded') {
             Terminus::error($result->reason);
         } else {
             Terminus::success("Import complete");
         }
     }
 }
Пример #6
0
 function testMenuSingleOptionReturningIndex()
 {
     $only_option_index = Input::menu(array('choices' => array('Pick me!')));
     $this->assertInternalType('integer', $only_option_index);
     $this->assertEquals(0, $only_option_index);
 }
Пример #7
0
 /**
  * Manage site organization tags
  *
  * ## OPTIONS
  *
  * <add|remove>
  * : subfunction to run
  *
  * [--site=<site>]
  * : Site's name
  *
  * [--org=<name|id>]
  * : Organization to apply tag with
  *
  * [--tag=<tag>]
  * : Tag to add or remove
  *
  * @subcommand tags
  */
 public function tags($args, $assoc_args)
 {
     $action = array_shift($args);
     $site = SiteFactory::instance(Input::sitename($assoc_args));
     $org = Input::orgid($assoc_args, 'org');
     if ($site->organizationIsMember($org)) {
         $data = array();
         switch ($action) {
             case 'add':
                 $verb = 'added to';
                 $tag = Input::string($assoc_args, 'tag', 'Enter a tag to add');
                 $response = $site->addTag($tag, $org);
                 break;
             case 'remove':
                 $verb = 'removed from';
                 $tags = $site->getTags($org);
                 if (count($tags) === 0) {
                     Terminus::error('This organization does not have any tags' . ' associated with this site.');
                 } elseif (!isset($assoc_args['tag']) || !in_array($assoc_args['tag'], $tags)) {
                     $tag = $tags[Input::menu($tags, null, 'Select a tag to delete')];
                 } else {
                     $tag = $assoc_args['tag'];
                 }
                 $response = $site->removeTag($tag, $org);
                 break;
         }
         $message = 'Tag %s %s %s %s';
         $messages = array('success' => sprintf($message, '"' . $tag . '"', 'has been', $verb, $site->getName()), 'failure' => sprintf($message, '"' . $tag . '"', 'could not be', $verb, $site->getName()));
         $this->responseOutput($response, $messages);
     } else {
         Terminus::error($site->getName() . ' is not a member of an organization, ' . 'which is necessary to associate a tag with a site.');
     }
 }
Пример #8
0
 /**
  * Helper function to select Site Workflow
  *
  * @param [array<Workflow>] $workflows Array of workflows to list
  * @param [array]           $args      Args to parse value from
  * @param [string]          $key       Index to search for in args
  *
  * @return [Workflow] $workflow
  */
 public static function workflow($workflows, $args, $key = 'workflow_id')
 {
     if (isset($args['workflow_id'])) {
         $workflow_id = $args[$key];
     } else {
         $workflow_menu_args = array();
         foreach ($workflows as $workflow) {
             if ($workflow->get('environment')) {
                 $environment = $workflow->get('environment');
             } else {
                 $environment = 'None';
             }
             $created_at = date('Y-m-d H:i:s', $workflow->get('created_at'));
             $workflow_description = sprintf("%s - %s - %s - %s", $environment, $workflow->get('description'), $created_at, $workflow->id);
             $workflow_menu_args[$workflow->id] = $workflow_description;
         }
         $workflow_id = Input::menu($workflow_menu_args, null, 'Choose workflow');
     }
     $filtered_workflow = array_filter($workflows, function ($workflow) use($workflow_id) {
         return $workflow->id == $workflow_id;
     });
     if (count($filtered_workflow) > 0) {
         $workflow = array_values($filtered_workflow)[0];
         return $workflow;
     } else {
         throw new TerminusException('Could not find workflow "{id}"', array('id' => $id), 1);
     }
 }
Пример #9
0
 /**
  * Helper function to select Site Workflow
  *
  * @param [Site]   $site Site from which to fetch workflows
  * @param [array]  $args Args to parse value from
  * @param [string] $key  Index to search for in args
  *
  * @return [Workflow] $workflow
  */
 public static function workflow($site, $args, $key = 'workflow_id')
 {
     if (isset($args['workflow_id'])) {
         $workflow_id = $args[$key];
     } else {
         // Only retrieve the most-recent 100 workflows
         $site->workflows->fetch(array('paged' => false));
         $workflow_menu_args = array();
         foreach ($site->workflows->all() as $workflow) {
             if ($workflow->get('environment')) {
                 $environment = $workflow->get('environment');
             } else {
                 $environment = 'None';
             }
             $created_at = date('Y-m-d H:i:s', $workflow->get('created_at'));
             $workflow_description = sprintf("%s - %s - %s - %s", $environment, $workflow->get('description'), $created_at, $workflow->id);
             $workflow_menu_args[$workflow->id] = $workflow_description;
         }
         $workflow_id = Input::menu($workflow_menu_args, null, 'Choose workflow');
     }
     $workflow = $site->workflows->get($workflow_id);
     return $workflow;
 }
Пример #10
0
 /**
  * Change the site payment instrument
  *
  * ## OPTIONS
  *
  * [--site=<site>]
  * : Site to use
  *
  * [--instrument=<UUID>]
  * : Change the instrument by setting the ID
  *
  * ## EXAMPLES
  *
  *  terminus site instrument --site=sitename
  */
 public function instrument($args, $assoc_args)
 {
     $user = new User();
     $instruments = $user->instruments()->all();
     foreach ($instruments as $instrument) {
         $data[$instrument->get('id')] = $instrument->get('label');
     }
     //If site is not set, show all user's payment instruments
     if (!isset($assoc_args['site'])) {
         $this->handleDisplay($data, array(), array('UUID', 'Label'));
     } else {
         array_unshift($data, 'none');
         $site = SiteFactory::instance($assoc_args['site']);
         //If instrument is not present, show the site's current instrument
         if (!isset($assoc_args['instrument'])) {
             $instrument_uuid = $site->get('instrument');
             if ($instrument_uuid == null) {
                 \Terminus::line($site->get('name') . ' does not have an attached payment instrument.');
             } else {
                 \Terminus::line($site->get('name') . ' is being charged to ' . $data[$instrument_uuid] . ', UUID: ' . $instrument_uuid);
             }
         } else {
             //Both are present. Ensure sure UUID is valid.
             //This attempts to prevent users from selecting instruments which do not belong to them.
             $instrument_id = $assoc_args['instrument'];
             if (!isset($data[$instrument_id])) {
                 $location = array_search($instrument_id, $data);
                 if ($location !== false) {
                     $instrument_id = $location;
                 } else {
                     $uuids = array_keys($data);
                     $instrument_id = Input::menu($data, null, 'Select a payment instrument');
                 }
             }
             //Change the instrument once we have a valid instrument.
             if ($instrument_id == 0) {
                 $workflow = $site->removeInstrument();
             } else {
                 $workflow = $site->addInstrument($instrument_id);
             }
             $workflow->wait();
             \Terminus::line("Successfully updated payment instrument to {$instrument_id}.");
         }
     }
 }
Пример #11
0
 /**
  * List an organization's sites
  *
  * ## OPTIONS
  *
  * <add|remove|list>
  * : subfunction to run
  *
  * [--org=<id|name>]
  * : Organization UUID or name
  *
  * [--tag=<tag>]
  * : Tag name to filter sites list by
  *
  * [--site=<site>]
  * : Site to add to or remove from organization
  *
  * @subcommand sites
  */
 public function sites($args, $assoc_args)
 {
     $action = array_shift($args);
     $org_id = Input::orgId(array('args' => $assoc_args, 'allow_none' => false));
     // TODO: clarify that these are OrganizationMemberships, not Organization models
     $orgs = new UserOrganizationMemberships();
     $org = $orgs->get($org_id);
     $org_info = $org->get('organization');
     $org_model = new Organization($org_info);
     $memberships = $org->site_memberships->all();
     switch ($action) {
         case 'add':
             if (isset($assoc_args['site'])) {
                 if ($this->siteIsMember($memberships, $assoc_args['site'])) {
                     $this->failure('{site} is already a member of {org}', array('site' => $assoc_args['site'], 'org' => $org_info->profile->name));
                 } else {
                     $site = $this->sites->get($assoc_args['site']);
                 }
             } else {
                 $site = $this->sites->get(Input::menu(array('choices' => $this->getNonmemberSiteList($memberships), 'message' => 'Choose site')));
             }
             Input::confirm(array('message' => 'Are you sure you want to add %s to %s ?', 'context' => array($site->get('name'), $org_info->profile->name)));
             $workflow = $org_model->site_memberships->addMember($site);
             $workflow->wait();
             $this->workflowOutput($workflow);
             break;
         case 'remove':
             if (isset($assoc_args['site'])) {
                 if (!$this->siteIsMember($memberships, $assoc_args['site'])) {
                     $this->failure('{site} is not a member of {org}', array('site' => $assoc_args['site'], 'org' => $org_info->profile->name));
                 } else {
                     $site = $this->sites->get($assoc_args['site']);
                 }
             } else {
                 $site = $this->sites->get(Input::menu(array('choices' => $this->getMemberSiteList($memberships), 'message' => 'Choose site')));
             }
             $member = $org_model->site_memberships->get($site->get('id'));
             Input::confirm(array('message' => 'Are you sure you want to remove %s from %s ?', 'context' => array($site->get('name'), $org_info->profile->name)));
             $workflow = $member->removeMember();
             $workflow->wait();
             $this->workflowOutput($workflow);
             break;
         case 'list':
         default:
             $data = [];
             foreach ($memberships as $membership) {
                 if (isset($assoc_args['tag']) && !in_array($assoc_args['tag'], $membership->get('tags'))) {
                     continue;
                 }
                 $site = $membership->get('site');
                 $data_array = array('name' => null, 'id' => null, 'service_level' => null, 'framework' => null, 'created' => null, 'tags' => $membership->get('tags'));
                 foreach ($data_array as $key => $value) {
                     if ($value == null && isset($site->{$key})) {
                         $data_array[$key] = $site->{$key};
                     }
                 }
                 $data_array['created'] = date('Y-m-dTH:i:s', strtotime($data_array['created']));
                 $data[] = $data_array;
             }
             if (empty($data)) {
                 $message = 'No sites match your ';
                 if (empty($assoc_args) || count($assoc_args) == 1 && isset($assoc_args['org'])) {
                     $message .= 'criterion.';
                 } else {
                     $message .= 'criteria.';
                 }
                 $this->log()->info($message);
             }
             $this->output()->outputRecordList($data);
             break;
     }
 }
Пример #12
0
 /**
  * Creates a backup
  *
  * @params [array] $assoc_args Parameters and flags from the command line
  * @return [Workflow[ $workflow
  */
 private function createBackup($assoc_args)
 {
     $site = $this->sites->get(Input::sitename($assoc_args));
     $env = $site->environments->get(Input::env(array('args' => $assoc_args, 'site' => $site)));
     if (!array_key_exists('element', $assoc_args)) {
         $options = array('code', 'db', 'files', 'all');
         $assoc_args['element'] = $options[Input::menu($options, 'all', 'Select element')];
     }
     $workflow = $env->createBackup($assoc_args);
     return $workflow;
 }