/** * List an organization's sites * * ## OPTIONS * * [--org=<id>] * : Organization id * * [--tag=<tag>] * : Tag name to filter sites list by * * [--add=<site>] * : Site to add to organization * * [--remove=<site>] * : Site to remove from organization * * @subcommand sites * */ public function sites($args, $assoc_args) { $org_id = Input::orgid($assoc_args, 'org', null, array('allow_none' => false)); $org = new Organization($org_id); if (isset($assoc_args['add'])) { $add = SiteFactory::instance(Input::sitename($assoc_args, 'add')); Terminus::confirm("Are you sure you want to add %s to %s ?", $assoc_args, array($add->getName(), $org->name)); $org->addSite($add); Terminus::success("Added site!"); return true; } if (isset($assoc_args['remove'])) { $remove = SiteFactory::instance(Input::sitename($assoc_args, 'remove')); Terminus::confirm("Are you sure you want to remove %s to %s ?", $assoc_args, array($remove->getName(), $org->name)); $org->removeSite($remove); Terminus::success("Removed site!"); return true; } $org->siteMemberships->fetch(); $memberships = $org->siteMemberships->all(); foreach ($memberships as $membership) { if (isset($assoc_args['tag']) && !in_array($assoc_args['tag'], $membership->get('tags'))) { continue; } $site = $membership->get('site'); $data[] = array('name' => $site->name, 'id' => $site->id, 'service_level' => $site->service_level, 'framework' => $site->framework, 'created' => date('Y-m-d H:i:s', $site->created), 'tags' => $membership->get('tags')); } $this->handleDisplay($data); }
/** * List an organizations sites * * ## OPTIONS * * [--org=<org>] * : Organization name or Id * * [--add=<site>] * : Site to add to organization * * [--remove=<site>] * : Site to remove from organization * * @subcommand sites * */ public function sites($args, $assoc_args) { $orgs = array(); $user = new User(); foreach ($user->organizations() as $id => $org) { $orgs[$id] = $org->name; } if (!isset($assoc_args['org']) or empty($assoc_args['org'])) { $selected_org = Terminus::menu($orgs, false, "Choose an organization"); } else { $selected_org = $assoc_args['org']; } $org = new Organization($selected_org); if (isset($assoc_args['add'])) { $add = SiteFactory::instance(Input::site($assoc_args, 'add')); Terminus::confirm("Are you sure you want to add %s to %s ?", $assoc_args, array($add->getName(), $org->name)); $org->addSite($add); Terminus::success("Added site!"); return true; } if (isset($assoc_args['remove'])) { $remove = SiteFactory::instance(Input::site($assoc_args, 'remove')); Terminus::confirm("Are you sure you want to remove %s to %s ?", $assoc_args, array($remove->getName(), $org->name)); $org->removeSite($remove); Terminus::success("Removed site!"); return true; } $sites = $org->getSites(); $data = array(); foreach ($sites as $site) { $data[] = array('name' => $site->site->name, 'service level' => isset($site->site->service_level) ? $site->site->service_level : '', 'framework' => isset($site->site->framework) ? $site->site->framework : '', 'created' => date('Y-m-d H:i:s', $site->site->created)); } $this->handleDisplay($data); }
/** * @vcr site_attributes */ function testAttributes() { $site = SiteFactory::instance('phpunittest'); $data = $site->attributes(); $this->assertNotEmpty($data); $this->assertInstanceOf('stdClass', $data); $this->assertObjectHasAttribute('label', $data); }
function testSiteWorkflowCreate() { $site = SiteFactory::instance('phpunittest'); $workflow = SiteWorkflow::createWorkflow('update_site_organization_membership', $site); $this->assertInstanceOf('Terminus\\SiteWorkflow', $workflow); $this->assertInstanceOf('Terminus\\Site', $workflow->site); $this->assertNull($workflow->status()); $workflow->start(); }
/** * @vcr sitefactory_instance */ function testInstance() { $sites = SiteFactory::instance(); $this->assertTrue(is_array($sites)); $this->assertNotEmpty($sites); $this->assertArrayHasKey('phpunittest', $sites); unset($sites); $site = SiteFactory::instance('phpunittest'); $this->assertInstanceOf('\\Terminus\\Site', $site); $this->assertObjectHasAttribute("id", $site); $this->assertObjectHasAttribute("information", $site); $this->assertObjectHasAttribute("workflows", $site); $this->assertObjectHasAttribute("environments", $site); $this->assertObjectHasAttribute("id", $site); }
/** * Invoke `wp` commands on a Pantheon development site * * <commands>... * : The WP-CLI commands you intend to run. * * [--<flag>=<value>] * : Additional WP-CLI flag(s) to pass in to the command. * * --site=<site> * : The name (DNS shortname) of your site on Pantheon. * * [--env=<environment>] * : Your Pantheon environment. Default: dev * */ function __invoke($args, $assoc_args) { $site_name = $assoc_args['site']; if (isset($assoc_args['env'])) { $environment = $assoc_args['env']; } else { $environment = 'dev'; } $site = SiteFactory::instance($site_name); if (!$site) { Terminus::error("Command could not be completed."); exit; } # see https://github.com/pantheon-systems/titan-mt/blob/master/dashboardng/app/workshops/site/models/environment.coffee $server = array('user' => "{$environment}.{$site->getId()}", 'host' => "appserver.{$environment}.{$site->getId()}.drush.in", 'port' => '2222'); if (strpos(TERMINUS_HOST, 'onebox') !== FALSE) { $server['user'] = "******"; $server['host'] = TERMINUS_HOST; } # Sanitize assoc args so we don't try to pass our own flags. # TODO: DRY this out? unset($assoc_args['site']); if (isset($assoc_args['env'])) { unset($assoc_args['env']); } # Create user-friendly output $command = implode($args, ' '); $flags = ''; foreach ($assoc_args as $k => $v) { if (isset($v) && (string) $v != '') { $flags .= "--{$k}=" . escapeshellarg($v) . ' '; } else { $flags .= "--{$k} "; } } Terminus::line("Running wp %s %s on %s-%s", array($command, $flags, $site->getName(), $environment)); $this->send_command($server, 'wp', $args, $assoc_args); }
/** * @vcr input_helper_org_helpers */ function testOrgHelpers() { $site = SiteFactory::instance("phpunittest"); $orglist = Input::orglist(); $this->assertInternalType('array', $orglist); $this->assertArrayHasKey('-', $orglist); $this->assertArrayHasKey('d59379eb-0c23-429c-a7bc-ff51e0a960c2', $orglist); // test normal usage $args = array('org' => 'Terminus Testing'); $org = Input::orgname($args, 'org'); $this->assertEquals('Terminus Testing', $org); // test case where an orgid is sent and a name should be returned $args = array('org' => 'd59379eb-0c23-429c-a7bc-ff51e0a960c2'); $org = Input::orgname($args, 'org'); $this->assertEquals('Terminus Testing', $org); // test case where an orgid is sent and a name should be returned $args = array('org' => 'd59379eb-0c23-429c-a7bc-ff51e0a960c2'); $org = Input::orgid($args, 'org'); $this->assertEquals('d59379eb-0c23-429c-a7bc-ff51e0a960c2', $org); $args = array('org' => 'Terminus Testing'); $org = Input::orgid($args, 'org'); $this->assertEquals('d59379eb-0c23-429c-a7bc-ff51e0a960c2', $org); }
/** * Invoke `drush` commands on a Pantheon development site * * <commands>... * : The Drush commands you intend to run. * * [--<flag>=<value>] * : Additional Drush flag(s) to pass in to the command. * * --site=<site> * : The name (DNS shortname) of your site on Pantheon. * * [--env=<environment>] * : Your Pantheon environment. Default: dev * */ function __invoke($args, $assoc_args) { $site_name = $assoc_args['site']; if (isset($assoc_args['env'])) { $environment = $assoc_args['env']; } else { $environment = 'dev'; } $site = SiteFactory::instance($site_name); if (!$site) { Terminus::error("Command could not be completed."); exit; } $server = array('user' => "{$environment}.{$site->getId()}", 'host' => "appserver.{$environment}.{$site->getId()}.drush.in", 'port' => '2222'); if (strpos(TERMINUS_HOST, 'onebox') !== FALSE) { $server['user'] = "******"; $server['host'] = TERMINUS_HOST; } # Sanitize assoc args so we don't try to pass our own flags. # TODO: DRY this out? unset($assoc_args['site']); if (isset($assoc_args['env'])) { unset($assoc_args['env']); } # Create user-friendly output $command = implode($args, ' '); $flags = ''; foreach ($assoc_args as $k => $v) { if (isset($v) && (string) $v != '') { $flags .= "--{$k}={$v} "; } else { $flags .= "--{$k} "; } } Terminus::line("Running drush %s %s on %s-%s", array($command, $flags, $site->getName(), $environment)); $this->send_command($server, 'drush', $args, $assoc_args); }
/** * Update alls dev sites with an available upstream update. * * ## OPTIONS * * [--report] * : If set output will contain list of sites and whether they are up-to-date * * [--upstream=<upstream>] * : Specify a specific upstream to check for updating. * * [--no-updatedb] * : Use flag to skip running update.php after the update has applied * * [--xoption=<theirs|ours>] * : Corresponds to git's -X option, set to 'theirs' by default -- https://www.kernel.org/pub/software/scm/git/docs/git-merge.html * * @subcommand mass-update */ public function mass_update($args, $assoc_args) { $sites = SiteFactory::instance(); $env = 'dev'; $upstream = Input::optional('upstream', $assoc_args, false); $data = array(); $report = Input::optional('report', $assoc_args, false); $confirm = Input::optional('confirm', $assoc_args, false); // Start status messages. if ($upstream) { Terminus::line('Looking for sites using ' . $upstream . '.'); } foreach ($sites as $site) { $updates = $site->getUpstreamUpdates(); if (!isset($updates->behind)) { // No updates, go back to start. continue; } // Check for upstream argument and site upstream URL match. $siteUpstream = $site->info('upstream'); if ($upstream and isset($siteUpstream->url)) { if ($siteUpstream->url != $upstream) { // Uptream doesn't match, go back to start. continue; } } if ($updates->behind > 0) { $data[$site->getName()] = array('site' => $site->getName(), 'status' => "Needs update"); $noupdatedb = Input::optional($assoc_args, 'updatedb', false); $update = $noupdatedb ? false : true; $xoption = Input::optional($assoc_args, 'xoption', 'theirs'); if (!$report) { $confirmed = Input::yesno("Apply upstream updatefs to %s ( run update.php:%s, xoption:%s ) ", array($site->getName(), var_export($update, 1), var_export($xoption, 1))); if (!$confirmed) { continue; } // Suer says No, go back to start. // Backup the DB so the client can restore if something goes wrong. Terminus::line('Backing up ' . $site->getName() . '.'); $backup = $site->environment('dev')->createBackup(array('element' => 'all')); // Only continue if the backup was successful. if ($backup) { Terminus::success("Backup of " . $site->getName() . " created."); Terminus::line('Updating ' . $site->getName() . '.'); // Apply the update, failure here would trigger a guzzle exception so no need to validate success. $response = $site->applyUpstreamUpdates($env, $update, $xoption); $data[$site->getName()]['status'] = 'Updated'; Terminus::success($site->getName() . ' is updated.'); } else { $data[$site->getName()]['status'] = 'Backup failed'; Terminus::error('There was a problem backing up ' . $site->getName() . '. Update aborted.'); } } } else { if (isset($assoc_args['report'])) { $data[$site->getName()] = array('site' => $site->getName(), 'status' => "Up to date"); } } } if (!empty($data)) { sort($data); $this->handleDisplay($data); } else { Terminus::line('No sites in need up updating.'); } }
/** * Complete wipe and reset a site * * ## OPTIONS * * [--site=<site>] * : Site to use * * [--env=<env>] * : Specify environment, default = dev */ public function wipe($args, $assoc_args) { try { $env = @$assoc_args['env'] ?: 'dev'; $site = SiteFactory::instance(Input::site($assoc_args)); $site_id = $site->getId(); $env = Input::env($assoc_args, 'env'); Terminus::line("Wiping %s %s", array($site_id, $env)); $resp = $site->environment($env)->wipe(); if ($resp) { $this->waitOnWorkflow('sites', $site_id, $resp['data']->id); Terminus::success("Successfully wiped %s -- %s", array($site->getName(), $env)); } } catch (Exception $e) { Terminus::error("%s", array($e->getMessage())); } }
/** * List a site's workflows * * ## OPTIONS * [--site=<site>] * : Site to check * * @subcommand workflows */ public function workflows($args, $assoc_args) { $site = SiteFactory::instance(Input::sitename($assoc_args)); $workflows = $site->getWorkflows(); $data = array(); foreach ($workflows as $workflow) { $user = '******'; if (isset($workflow->get('user')->email)) { $user = $workflow->get('user')->email; } $data[] = array('workflow' => $workflow->get('description'), 'user' => $user, 'status' => $workflow->get('phase'), 'last_update' => date('Y-m-dTH:i:s', $workflow->get('created_at') + $workflow->get('total_time')), 'tasks/complete' => $workflow->get('step') . '/' . $workflow->get('number_of_tasks')); } if (count($data) > 0) { $this->constructTableForResponse($data); } else { Terminus::error('No workflows have been run on ' . $site->getName()); } }
/** * Delete a site from pantheon * * ## OPTIONS * --site=<site> * : Id of the site you want to delete * * [--all] * : Just kidding ... we won't let you do that. * * [--force] * : to skip the confirmations * */ function delete($args, $assoc_args) { $site_to_delete = SiteFactory::instance(@$assoc_args['site']); if (!$site_to_delete) { foreach (SiteFactory::instance() as $id => $site) { $site->id = $id; $sites[] = $site; $menu[] = $site->information->name; } $index = Terminus::menu($menu, null, "Select a site to delete"); $site_to_delete = $sites[$index]; } if (!isset($assoc_args['force']) and !Terminus::get_config('yes')) { // if the force option isn't used we'll ask you some annoying questions Terminus::confirm(sprintf("Are you sure you want to delete %s?", $site_to_delete->information->name)); Terminus::confirm("Are you really sure?"); } Terminus::line(sprintf("Deleting %s ...", $site_to_delete->information->name)); $response = \Terminus_Command::request('sites', $site_to_delete->id, '', 'DELETE'); Terminus::success("Deleted %s!", $site_to_delete->information->name); }
/** * Input helper that provides interactive site list * * @param [array] $args The args passed in from argv * @param [string] $key Args key to search for * @param [string] $label Prompt for STDOUT * @return [string] Site name */ public static function site($args = array(), $key = 'site', $label = 'Choose site') { // early return if a valid site has been offered if (isset($args[$key])) { if ($site = SiteFactory::instance($args[$key])) { $site_name = $site->getName(); return $site_name; } } $sites = SiteFactory::instance(); $choices = array(); foreach ($sites as $site) { $choices[$site->information->name] = $site->information->name; } $menu = self::menu($choices, $default = null, $label); return $menu; }