Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
| <?php | <?php | ||||
| abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow { | abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow { | ||||
| private $args; | private $args; | ||||
| private $repository; | private $repository; | ||||
| private $hasWriteAccess; | private $hasWriteAccess; | ||||
| private $proxyURI; | |||||
| public function getRepository() { | public function getRepository() { | ||||
| if (!$this->repository) { | if (!$this->repository) { | ||||
| throw new Exception(pht('Repository is not available yet!')); | throw new Exception(pht('Repository is not available yet!')); | ||||
| } | } | ||||
| return $this->repository; | return $this->repository; | ||||
| } | } | ||||
| Show All 28 Lines | abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow { | ||||
| abstract protected function identifyRepository(); | abstract protected function identifyRepository(); | ||||
| abstract protected function executeRepositoryOperations(); | abstract protected function executeRepositoryOperations(); | ||||
| protected function writeError($message) { | protected function writeError($message) { | ||||
| $this->getErrorChannel()->write($message); | $this->getErrorChannel()->write($message); | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| protected function shouldProxy() { | |||||
| return (bool)$this->proxyURI; | |||||
| } | |||||
| protected function getProxyCommand() { | |||||
| $uri = new PhutilURI($this->proxyURI); | |||||
| $username = PhabricatorEnv::getEnvConfig('cluster.instance'); | |||||
| if (!strlen($username)) { | |||||
| $username = PhabricatorEnv::getEnvConfig('diffusion.ssh-user'); | |||||
| if (!strlen($username)) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Unable to determine the username to connect with when trying '. | |||||
| 'to proxy an SSH request within the Phabricator cluster.')); | |||||
| } | |||||
| } | |||||
| $port = $uri->getPort(); | |||||
| $host = $uri->getDomain(); | |||||
| $key_path = AlmanacKeys::getKeyPath('device.key'); | |||||
| if (!Filesystem::pathExists($key_path)) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Unable to proxy this SSH request within the cluster: this device '. | |||||
| 'is not registered and has a missing device key (expected to '. | |||||
| 'find key at "%s").', | |||||
| $key_path)); | |||||
| } | |||||
| $options = array(); | |||||
| $options[] = '-o'; | |||||
| $options[] = 'StrictHostKeyChecking=no'; | |||||
| $options[] = '-o'; | |||||
| $options[] = 'UserKnownHostsFile=/dev/null'; | |||||
| // This is suppressing "added <address> to the list of known hosts" | |||||
| // messages, which are confusing and irrelevant when they arise from | |||||
| // proxied requests. It might also be suppressing lots of useful errors, | |||||
| // of course. Ideally, we would enforce host keys eventually. | |||||
| $options[] = '-o'; | |||||
| $options[] = 'LogLevel=quiet'; | |||||
| // NOTE: We prefix the command with "@username", which the far end of the | |||||
| // connection will parse in order to act as the specified user. This | |||||
| // behavior is only available to cluster requests signed by a trusted | |||||
| // device key. | |||||
| return csprintf( | |||||
| 'ssh %Ls -l %s -i %s -p %s %s -- %s %Ls', | |||||
| $options, | |||||
| $username, | |||||
| $key_path, | |||||
| $port, | |||||
| $host, | |||||
| '@'.$this->getUser()->getUsername(), | |||||
| $this->getOriginalArguments()); | |||||
| } | |||||
| final public function execute(PhutilArgumentParser $args) { | final public function execute(PhutilArgumentParser $args) { | ||||
| $this->args = $args; | $this->args = $args; | ||||
| $repository = $this->identifyRepository(); | $repository = $this->identifyRepository(); | ||||
| $this->setRepository($repository); | $this->setRepository($repository); | ||||
| // TODO: Here, we would make a proxying decision, had I implemented | $is_cluster_request = $this->getIsClusterRequest(); | ||||
| // proxying yet. | $uri = $repository->getAlmanacServiceURI( | ||||
| $this->getUser(), | |||||
| $is_cluster_request, | |||||
| array( | |||||
| 'ssh', | |||||
| )); | |||||
| if ($uri) { | |||||
| $this->proxyURI = $uri; | |||||
| } | |||||
| try { | try { | ||||
| return $this->executeRepositoryOperations(); | return $this->executeRepositoryOperations(); | ||||
| } catch (Exception $ex) { | } catch (Exception $ex) { | ||||
| $this->writeError(get_class($ex).': '.$ex->getMessage()); | $this->writeError(get_class($ex).': '.$ex->getMessage()); | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 85 Lines • Show Last 20 Lines | |||||