mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Allow repositories to be bound to an AlmanacService
Summary: Ref T2783. This is primarily exploratory and just figuring out what we're blocked on: - Allow a Repository to be bound to a Service. The Service may eventually define multiple read/write nodes, etc. - There's no UI to do this binding yet, you have to touch the database manually. - If a repository is bound to a Service, effect Conduit calls via calls to the remote service instead of executing them in-process. - These don't actually work yet since there's no authentication (see T5955). Test Plan: - Made a nice Service with a nice Binding to a nice Interface on a nice Device. - Force-associated a repository with the service using a raw MySQL query. - Saw Phabricator try to make a remote call to the service (on localhost) and fail because of missing auth stuff. - Also ran `almanac.queryservices`. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T2783 Differential Revision: https://secure.phabricator.com/D10982
This commit is contained in:
parent
2b99b4add8
commit
4505724cc4
6 changed files with 96 additions and 18 deletions
2
resources/sql/autopatches/20141210.reposervice.sql
Normal file
2
resources/sql/autopatches/20141210.reposervice.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_repository.repository
|
||||
ADD almanacServicePHID VARBINARY(64);
|
|
@ -31,7 +31,8 @@ final class AlmanacQueryServicesConduitAPIMethod
|
|||
$viewer = $request->getUser();
|
||||
|
||||
$query = id(new AlmanacServiceQuery())
|
||||
->setViewer($viewer);
|
||||
->setViewer($viewer)
|
||||
->needBindings(true);
|
||||
|
||||
$ids = $request->getValue('ids');
|
||||
if ($ids !== null) {
|
||||
|
@ -52,16 +53,6 @@ final class AlmanacQueryServicesConduitAPIMethod
|
|||
|
||||
$services = $query->executeWithCursorPager($pager);
|
||||
|
||||
if ($services) {
|
||||
$bindings = id(new AlmanacBindingQuery())
|
||||
->setViewer($viewer)
|
||||
->withServicePHIDs(mpull($services, 'getPHID'))
|
||||
->execute();
|
||||
$bindings = mgroup($bindings, 'getServicePHID');
|
||||
} else {
|
||||
$bindings = array();
|
||||
}
|
||||
|
||||
$data = array();
|
||||
foreach ($services as $service) {
|
||||
$phid = $service->getPHID();
|
||||
|
@ -69,7 +60,7 @@ final class AlmanacQueryServicesConduitAPIMethod
|
|||
$properties = $service->getAlmanacProperties();
|
||||
$properties = mpull($properties, 'getFieldValue', 'getFieldName');
|
||||
|
||||
$service_bindings = idx($bindings, $phid, array());
|
||||
$service_bindings = $service->getBindings();
|
||||
$service_bindings = array_values($service_bindings);
|
||||
foreach ($service_bindings as $key => $service_binding) {
|
||||
$service_bindings[$key] = $this->getBindingDictionary($service_binding);
|
||||
|
|
|
@ -6,6 +6,7 @@ final class AlmanacServiceQuery
|
|||
private $ids;
|
||||
private $phids;
|
||||
private $names;
|
||||
private $needBindings;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
|
@ -22,6 +23,11 @@ final class AlmanacServiceQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function needBindings($need_bindings) {
|
||||
$this->needBindings = $need_bindings;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new AlmanacService();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
@ -71,4 +77,22 @@ final class AlmanacServiceQuery
|
|||
return $this->formatWhereClause($where);
|
||||
}
|
||||
|
||||
protected function didFilterPage(array $services) {
|
||||
if ($this->needBindings) {
|
||||
$service_phids = mpull($services, 'getPHID');
|
||||
$bindings = id(new AlmanacBindingQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withServicePHIDs($service_phids)
|
||||
->execute();
|
||||
$bindings = mgroup($bindings, 'getServicePHID');
|
||||
|
||||
foreach ($services as $service) {
|
||||
$service_bindings = idx($bindings, $service->getPHID(), array());
|
||||
$service->attachBindings($service_bindings);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::didFilterPage($services);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ final class AlmanacService
|
|||
|
||||
private $customFields = self::ATTACHABLE;
|
||||
private $almanacProperties = self::ATTACHABLE;
|
||||
private $bindings = self::ATTACHABLE;
|
||||
|
||||
public static function initializeNewService() {
|
||||
return id(new AlmanacService())
|
||||
|
@ -65,6 +66,15 @@ final class AlmanacService
|
|||
return '/almanac/service/view/'.$this->getName().'/';
|
||||
}
|
||||
|
||||
public function getBindings() {
|
||||
return $this->assertAttached($this->bindings);
|
||||
}
|
||||
|
||||
public function attachBindings(array $bindings) {
|
||||
$this->bindings = $bindings;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/* -( AlmanacPropertyInterface )------------------------------------------- */
|
||||
|
||||
|
|
|
@ -62,14 +62,63 @@ abstract class DiffusionQuery extends PhabricatorQuery {
|
|||
|
||||
$params = $params + $core_params;
|
||||
|
||||
return id(new ConduitCall(
|
||||
$method,
|
||||
$params
|
||||
))
|
||||
$service_phid = $repository->getAlmanacServicePHID();
|
||||
if ($service_phid === null) {
|
||||
return id(new ConduitCall($method, $params))
|
||||
->setUser($user)
|
||||
->execute();
|
||||
}
|
||||
|
||||
$service = id(new AlmanacServiceQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withPHIDs(array($service_phid))
|
||||
->needBindings(true)
|
||||
->executeOne();
|
||||
if (!$service) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'The Alamnac service for this repository is invalid or could not '.
|
||||
'be loaded.'));
|
||||
}
|
||||
|
||||
$bindings = $service->getBindings();
|
||||
if (!$bindings) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'The Alamanc service for this repository is not bound to any '.
|
||||
'interfaces.'));
|
||||
}
|
||||
|
||||
$uris = array();
|
||||
foreach ($bindings as $binding) {
|
||||
$iface = $binding->getInterface();
|
||||
|
||||
$protocol = $binding->getAlmanacPropertyValue('protocol');
|
||||
if ($protocol === 'http') {
|
||||
$uris[] = 'http://'.$iface->renderDisplayAddress().'/';
|
||||
} else if ($protocol === 'https' || $protocol === null) {
|
||||
$uris[] = 'https://'.$iface->renderDisplayAddress().'/';
|
||||
} else {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'The Almanac service for this repository has a binding to an '.
|
||||
'invalid interface with an unknown protocol ("%s").',
|
||||
$protocol));
|
||||
}
|
||||
}
|
||||
|
||||
shuffle($uris);
|
||||
$uri = head($uris);
|
||||
|
||||
$domain = id(new PhutilURI(PhabricatorEnv::getURI('/')))->getDomain();
|
||||
|
||||
// TODO: This call needs authentication, which is blocked by T5955.
|
||||
|
||||
return id(new ConduitClient($uri))
|
||||
->setHost($domain)
|
||||
->callMethodSynchronous($method, $params);
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
return $this->executeQuery();
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
|||
protected $versionControlSystem;
|
||||
protected $details = array();
|
||||
protected $credentialPHID;
|
||||
protected $almanacServicePHID;
|
||||
|
||||
private $commitCount = self::ATTACHABLE;
|
||||
private $mostRecentCommit = self::ATTACHABLE;
|
||||
|
@ -86,6 +87,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
|||
'uuid' => 'text64?',
|
||||
'pushPolicy' => 'policy',
|
||||
'credentialPHID' => 'phid?',
|
||||
'almanacServicePHID' => 'phid?',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_phid' => null,
|
||||
|
|
Loading…
Reference in a new issue