1
0
Fork 0
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:
epriestley 2014-12-12 12:07:11 -08:00
parent 2b99b4add8
commit 4505724cc4
6 changed files with 96 additions and 18 deletions

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_repository.repository
ADD almanacServicePHID VARBINARY(64);

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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 )------------------------------------------- */

View file

@ -62,12 +62,61 @@ abstract class DiffusionQuery extends PhabricatorQuery {
$params = $params + $core_params;
return id(new ConduitCall(
$method,
$params
))
->setUser($user)
->execute();
$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() {

View file

@ -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,