Page MenuHomePhabricator

D16565.id39874.diff
No OneTemporary

D16565.id39874.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -920,6 +920,7 @@
'DrydockAuthorizationListView' => 'applications/drydock/view/DrydockAuthorizationListView.php',
'DrydockAuthorizationPHIDType' => 'applications/drydock/phid/DrydockAuthorizationPHIDType.php',
'DrydockAuthorizationQuery' => 'applications/drydock/query/DrydockAuthorizationQuery.php',
+ 'DrydockAuthorizationSearchConduitAPIMethod' => 'applications/drydock/conduit/DrydockAuthorizationSearchConduitAPIMethod.php',
'DrydockAuthorizationSearchEngine' => 'applications/drydock/query/DrydockAuthorizationSearchEngine.php',
'DrydockAuthorizationViewController' => 'applications/drydock/controller/DrydockAuthorizationViewController.php',
'DrydockBlueprint' => 'applications/drydock/storage/DrydockBlueprint.php',
@@ -937,6 +938,7 @@
'DrydockBlueprintNameNgrams' => 'applications/drydock/storage/DrydockBlueprintNameNgrams.php',
'DrydockBlueprintPHIDType' => 'applications/drydock/phid/DrydockBlueprintPHIDType.php',
'DrydockBlueprintQuery' => 'applications/drydock/query/DrydockBlueprintQuery.php',
+ 'DrydockBlueprintSearchConduitAPIMethod' => 'applications/drydock/conduit/DrydockBlueprintSearchConduitAPIMethod.php',
'DrydockBlueprintSearchEngine' => 'applications/drydock/query/DrydockBlueprintSearchEngine.php',
'DrydockBlueprintTransaction' => 'applications/drydock/storage/DrydockBlueprintTransaction.php',
'DrydockBlueprintTransactionQuery' => 'applications/drydock/query/DrydockBlueprintTransactionQuery.php',
@@ -945,13 +947,16 @@
'DrydockCommandError' => 'applications/drydock/exception/DrydockCommandError.php',
'DrydockCommandInterface' => 'applications/drydock/interface/command/DrydockCommandInterface.php',
'DrydockCommandQuery' => 'applications/drydock/query/DrydockCommandQuery.php',
+ 'DrydockConduitAPIMethod' => 'applications/drydock/conduit/DrydockConduitAPIMethod.php',
'DrydockConsoleController' => 'applications/drydock/controller/DrydockConsoleController.php',
'DrydockConstants' => 'applications/drydock/constants/DrydockConstants.php',
'DrydockController' => 'applications/drydock/controller/DrydockController.php',
'DrydockCreateBlueprintsCapability' => 'applications/drydock/capability/DrydockCreateBlueprintsCapability.php',
+ 'DrydockCreateLeaseConduitAPIMethod' => 'applications/drydock/conduit/DrydockCreateLeaseConduitAPIMethod.php',
'DrydockDAO' => 'applications/drydock/storage/DrydockDAO.php',
'DrydockDefaultEditCapability' => 'applications/drydock/capability/DrydockDefaultEditCapability.php',
'DrydockDefaultViewCapability' => 'applications/drydock/capability/DrydockDefaultViewCapability.php',
+ 'DrydockDestroyLeaseConduitAPIMethod' => 'applications/drydock/conduit/DrydockDestroyLeaseConduitAPIMethod.php',
'DrydockFilesystemInterface' => 'applications/drydock/interface/filesystem/DrydockFilesystemInterface.php',
'DrydockInterface' => 'applications/drydock/interface/DrydockInterface.php',
'DrydockLandRepositoryOperation' => 'applications/drydock/operation/DrydockLandRepositoryOperation.php',
@@ -973,6 +978,7 @@
'DrydockLeaseReclaimLogType' => 'applications/drydock/logtype/DrydockLeaseReclaimLogType.php',
'DrydockLeaseReleaseController' => 'applications/drydock/controller/DrydockLeaseReleaseController.php',
'DrydockLeaseReleasedLogType' => 'applications/drydock/logtype/DrydockLeaseReleasedLogType.php',
+ 'DrydockLeaseSearchConduitAPIMethod' => 'applications/drydock/conduit/DrydockLeaseSearchConduitAPIMethod.php',
'DrydockLeaseSearchEngine' => 'applications/drydock/query/DrydockLeaseSearchEngine.php',
'DrydockLeaseStatus' => 'applications/drydock/constants/DrydockLeaseStatus.php',
'DrydockLeaseUpdateWorker' => 'applications/drydock/worker/DrydockLeaseUpdateWorker.php',
@@ -1008,6 +1014,7 @@
'DrydockRepositoryOperationType' => 'applications/drydock/operation/DrydockRepositoryOperationType.php',
'DrydockRepositoryOperationUpdateWorker' => 'applications/drydock/worker/DrydockRepositoryOperationUpdateWorker.php',
'DrydockRepositoryOperationViewController' => 'applications/drydock/controller/DrydockRepositoryOperationViewController.php',
+ 'DrydockRequestAuthorizationConduitAPIMethod' => 'applications/drydock/conduit/DrydockRequestAuthorizationConduitAPIMethod.php',
'DrydockResource' => 'applications/drydock/storage/DrydockResource.php',
'DrydockResourceActivationFailureLogType' => 'applications/drydock/logtype/DrydockResourceActivationFailureLogType.php',
'DrydockResourceActivationYieldLogType' => 'applications/drydock/logtype/DrydockResourceActivationYieldLogType.php',
@@ -5441,12 +5448,14 @@
'DrydockAuthorization' => array(
'DrydockDAO',
'PhabricatorPolicyInterface',
+ 'PhabricatorConduitResultInterface',
),
'DrydockAuthorizationAuthorizeController' => 'DrydockController',
'DrydockAuthorizationListController' => 'DrydockController',
'DrydockAuthorizationListView' => 'AphrontView',
'DrydockAuthorizationPHIDType' => 'PhabricatorPHIDType',
'DrydockAuthorizationQuery' => 'DrydockQuery',
+ 'DrydockAuthorizationSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'DrydockAuthorizationSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DrydockAuthorizationViewController' => 'DrydockController',
'DrydockBlueprint' => array(
@@ -5456,6 +5465,7 @@
'PhabricatorCustomFieldInterface',
'PhabricatorNgramsInterface',
'PhabricatorProjectInterface',
+ 'PhabricatorConduitResultInterface',
),
'DrydockBlueprintController' => 'DrydockController',
'DrydockBlueprintCoreCustomField' => array(
@@ -5474,6 +5484,7 @@
'DrydockBlueprintNameNgrams' => 'PhabricatorSearchNgrams',
'DrydockBlueprintPHIDType' => 'PhabricatorPHIDType',
'DrydockBlueprintQuery' => 'DrydockQuery',
+ 'DrydockBlueprintSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'DrydockBlueprintSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DrydockBlueprintTransaction' => 'PhabricatorApplicationTransaction',
'DrydockBlueprintTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@@ -5485,19 +5496,23 @@
'DrydockCommandError' => 'Phobject',
'DrydockCommandInterface' => 'DrydockInterface',
'DrydockCommandQuery' => 'DrydockQuery',
+ 'DrydockConduitAPIMethod' => 'ConduitAPIMethod',
'DrydockConsoleController' => 'DrydockController',
'DrydockConstants' => 'Phobject',
'DrydockController' => 'PhabricatorController',
'DrydockCreateBlueprintsCapability' => 'PhabricatorPolicyCapability',
+ 'DrydockCreateLeaseConduitAPIMethod' => 'DrydockConduitAPIMethod',
'DrydockDAO' => 'PhabricatorLiskDAO',
'DrydockDefaultEditCapability' => 'PhabricatorPolicyCapability',
'DrydockDefaultViewCapability' => 'PhabricatorPolicyCapability',
+ 'DrydockDestroyLeaseConduitAPIMethod' => 'DrydockConduitAPIMethod',
'DrydockFilesystemInterface' => 'DrydockInterface',
'DrydockInterface' => 'Phobject',
'DrydockLandRepositoryOperation' => 'DrydockRepositoryOperationType',
'DrydockLease' => array(
'DrydockDAO',
'PhabricatorPolicyInterface',
+ 'PhabricatorConduitResultInterface',
),
'DrydockLeaseAcquiredLogType' => 'DrydockLogType',
'DrydockLeaseActivatedLogType' => 'DrydockLogType',
@@ -5516,6 +5531,7 @@
'DrydockLeaseReclaimLogType' => 'DrydockLogType',
'DrydockLeaseReleaseController' => 'DrydockLeaseController',
'DrydockLeaseReleasedLogType' => 'DrydockLogType',
+ 'DrydockLeaseSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'DrydockLeaseSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DrydockLeaseStatus' => 'DrydockConstants',
'DrydockLeaseUpdateWorker' => 'DrydockWorker',
@@ -5557,6 +5573,7 @@
'DrydockRepositoryOperationType' => 'Phobject',
'DrydockRepositoryOperationUpdateWorker' => 'DrydockWorker',
'DrydockRepositoryOperationViewController' => 'DrydockRepositoryOperationController',
+ 'DrydockRequestAuthorizationConduitAPIMethod' => 'DrydockConduitAPIMethod',
'DrydockResource' => array(
'DrydockDAO',
'PhabricatorPolicyInterface',
diff --git a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php
--- a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php
+++ b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php
@@ -15,6 +15,27 @@
abstract public function getBlueprintName();
abstract public function getDescription();
+ public function getSummary() {
+ return $this->getDescription();
+ }
+
+ public function getLeaseAttributesSpecification() {
+ return null;
+ }
+
+ public function getLeaseAttributesDescriptions() {
+ throw new PhutilMethodNotImplementedException();
+ }
+
+ public function validateLeaseAttributes(array $lease_attributes) {
+ $attribute_spec = $this->getLeaseAttributesSpecification();
+ PhutilTypeSpec::checkMap($lease_attributes, $attribute_spec);
+ }
+
+ public function getLeaseAttributesDataExample() {
+ return null;
+ }
+
public function getBlueprintIcon() {
return 'fa-map-o';
}
diff --git a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
--- a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
+++ b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
@@ -23,6 +23,37 @@
return pht('Allows Drydock to check out working copies of repositories.');
}
+ public function getLeaseAttributesSpecification() {
+ return array(
+ 'repositories.map' => 'map<string, map<string, wild>>',
+ 'repositories.strict' => 'optional bool',
+ );
+ }
+
+ public function getLeaseAttributesDescriptions() {
+ return array(
+ 'repositories.map' => pht(
+ 'Maps clone folder names to information about what repositories they '.
+ 'should contain and what state those repositories should be in.'),
+ 'repositories.strict' => pht(
+ 'Set to true in order to force the working copy to contain only '.
+ 'the repositories specified.'),
+ );
+ }
+
+ public function getLeaseAttributesDataExample() {
+ return array(
+ 'repositories.map' => array(
+ 'janitorial-services' => array(
+ 'phid' => 'PHID-REPO-gb3x27pjw4wffij3od44',
+ 'default' => true,
+ 'commit' => '3a66dac400a50632f442aed6cb8cf65c80e5ae70',
+ ),
+ ),
+ 'repositories.strict' => true,
+ );
+ }
+
public function canAnyBlueprintEverAllocateResourceForLease(
DrydockLease $lease) {
return true;
diff --git a/src/applications/drydock/conduit/DrydockAuthorizationSearchConduitAPIMethod.php b/src/applications/drydock/conduit/DrydockAuthorizationSearchConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/conduit/DrydockAuthorizationSearchConduitAPIMethod.php
@@ -0,0 +1,18 @@
+<?php
+
+final class DrydockAuthorizationSearchConduitAPIMethod
+ extends PhabricatorSearchEngineAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'drydock.authorization.search';
+ }
+
+ public function newSearchEngine() {
+ return new DrydockAuthorizationSearchEngine();
+ }
+
+ public function getMethodSummary() {
+ return pht('Retrieve information about Drydock authorizations.');
+ }
+
+}
diff --git a/src/applications/drydock/conduit/DrydockBlueprintSearchConduitAPIMethod.php b/src/applications/drydock/conduit/DrydockBlueprintSearchConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/conduit/DrydockBlueprintSearchConduitAPIMethod.php
@@ -0,0 +1,18 @@
+<?php
+
+final class DrydockBlueprintSearchConduitAPIMethod
+ extends PhabricatorSearchEngineAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'drydock.blueprint.search';
+ }
+
+ public function newSearchEngine() {
+ return new DrydockBlueprintSearchEngine();
+ }
+
+ public function getMethodSummary() {
+ return pht('Retrieve information about Drydock blueprints.');
+ }
+
+}
diff --git a/src/applications/drydock/conduit/DrydockConduitAPIMethod.php b/src/applications/drydock/conduit/DrydockConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/conduit/DrydockConduitAPIMethod.php
@@ -0,0 +1,18 @@
+<?php
+
+abstract class DrydockConduitAPIMethod extends ConduitAPIMethod {
+
+ final public function getApplication() {
+ return PhabricatorApplication::getByClass(
+ 'PhabricatorDrydockApplication');
+ }
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodStatusDescription() {
+ return pht('All Drydock APIs are new and subject to change.');
+ }
+
+}
diff --git a/src/applications/drydock/conduit/DrydockCreateLeaseConduitAPIMethod.php b/src/applications/drydock/conduit/DrydockCreateLeaseConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/conduit/DrydockCreateLeaseConduitAPIMethod.php
@@ -0,0 +1,171 @@
+<?php
+
+final class DrydockCreateLeaseConduitAPIMethod
+ extends DrydockConduitAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'drydock.createlease';
+ }
+
+ public function getMethodSummary() {
+ return pht('Lease a Drydock resource.');
+ }
+
+ public function getMethodDescription() {
+ $implementations =
+ DrydockBlueprintImplementation::getAllBlueprintImplementations();
+ $implementations = mfilter($implementations, 'isEnabled');
+
+ $head_class = pht('Class');
+ $head_type = pht('Type');
+ $head_name = pht('Name');
+ $head_desc = pht('Summary');
+
+ $out = array();
+ $out[] = pht(
+ 'This method leases a Drydock resource using an existing Drydock '.
+ 'blueprint. Before using a blueprint here, you must obtain '.
+ 'authorization for its use. You can request authorizations by calling '.
+ '`drydock.requestauthorization`.');
+ $out[] = null;
+ $out[] = pht(
+ 'When leasing a resource via a blueprint, the implementation class for '.
+ 'that blueprint determines what type of resource is leased. The '.
+ 'following blueprint implementation classes are supported:');
+
+ $out[] = "| {$head_class} | {$head_type} | {$head_name} | {$head_desc} |";
+ $out[] = '|---------------|--------------|--------------|--------------|';
+ foreach ($implementations as $class => $implementation) {
+ $type = $implementation->getType();
+ $name = $implementation->getBlueprintName();
+ $desc = $implementation->getSummary();
+ $out[] = "| `{$class}` | `{$type}` | **{$name}** | {$desc} |";
+ }
+
+ $out[] = null;
+ $out[] = pht(
+ 'Some blueprint implementations also define attributes which should '.
+ 'be provided when leasing resources. You should provide these '.
+ 'attributes using the `leaseAttributes` parameter when calling '.
+ 'this method. The attributes you provide depend on the implementation '.
+ 'class for the blueprint you are using.');
+
+ $head_key = pht('Key');
+
+ foreach ($implementations as $class => $implementation) {
+ $type = $implementation->getType();
+ $name = $implementation->getBlueprintName();
+
+ $out[] = "== {$name} ==";
+ $out[] = null;
+ $out[] = $implementation->getDescription();
+ $out[] = null;
+ $out[] = pht(
+ 'Blueprints with implementations of class `%s` will lease '.
+ 'resources of the `%s` type.',
+ $class,
+ $type);
+ $out[] = null;
+
+ $spec = $implementation->getLeaseAttributesSpecification();
+ if (!$spec) {
+ $out[] = pht(
+ '//(This implementation does not specify any lease attributes)//');
+ $out[] = null;
+ continue;
+ }
+
+ $desc = $implementation->getLeaseAttributesDescriptions();
+ $out[] = "| {$head_key} | {$head_type} | {$head_desc} |";
+ $out[] = '|-------------|--------------|--------------|';
+ foreach ($spec as $key => $key_type) {
+ $key_desc = idx($desc, $key);
+ $out[] = "| `{$key}` | //{$key_type}// | {$key_desc} |";
+ }
+
+ $example = $implementation->getLeaseAttributesDataExample();
+ if ($example !== null) {
+ $json = new PhutilJSON();
+ $rendered = $json->encodeFormatted($example);
+
+ $out[] = pht('For example:');
+ $out[] = '```lang=json';
+ $out[] = $rendered;
+ $out[] = '```';
+ }
+ }
+
+ return implode("\n", $out);
+ }
+
+ protected function defineParamTypes() {
+ return array(
+ 'blueprintPHID' => 'required phid',
+ 'leaseAttributes' => 'optional map<string, wild>',
+ );
+ }
+
+ protected function defineErrorTypes() {
+ return array(
+ 'ERR_NO_BLUEPRINT' => pht(
+ 'No active blueprint exists with the specified PHID.'),
+ 'ERR_NOT_AUTHORIZED' => pht(
+ 'You are not authorized to use this blueprint.'),
+ );
+ }
+
+ protected function defineReturnType() {
+ return 'wild';
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $viewer = $request->getUser();
+ $blueprint_phid = $request->getValue('blueprintPHID');
+ $blueprint = id(new DrydockBlueprintQuery())
+ ->setViewer($viewer)
+ ->withDisabled(false)
+ ->withPHIDs(array($blueprint_phid))
+ ->executeOne();
+ if (!$blueprint) {
+ throw new ConduitException('ERR_NO_BLUEPRINT');
+ }
+
+ $authorization = id(new DrydockAuthorizationQuery())
+ ->setViewer($viewer)
+ ->withBlueprintPHIDs(array($blueprint_phid))
+ ->withObjectPHIDs(array($viewer->getPHID()))
+ ->withBlueprintStates(array(
+ DrydockAuthorization::BLUEPRINTAUTH_AUTHORIZED,
+ ))
+ ->withObjectStates(array(DrydockAuthorization::OBJECTAUTH_ACTIVE))
+ ->executeOne();
+ if (!$authorization) {
+ throw new ConduitException('ERR_NOT_AUTHORIZED');
+ }
+
+ $implementation = $blueprint->getImplementation();
+ $lease = id(new DrydockLease())
+ ->setOwnerPHID($viewer->getPHID())
+ ->setResourceType($implementation->getType())
+ ->setAuthorizingPHID($viewer->getPHID())
+ ->setAllowedBlueprintPHIDs(array($blueprint_phid));
+
+ $lease_attributes = $request->getValue('leaseAttributes', array());
+ $implementation->validateLeaseAttributes($lease_attributes);
+ foreach ($lease_attributes as $key => $value) {
+ $lease->setAttribute($key, $value);
+ }
+
+ $lease->queueForActivation();
+
+ $search = id(new ConduitCall('drydock.lease.search', array(
+ 'constraints' => array(
+ 'phids' => array($lease->getPHID()),
+ ),
+ )))
+ ->setUser($viewer)
+ ->execute();
+ return idxv($search, array('data', 0));
+ }
+
+}
diff --git a/src/applications/drydock/conduit/DrydockDestroyLeaseConduitAPIMethod.php b/src/applications/drydock/conduit/DrydockDestroyLeaseConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/conduit/DrydockDestroyLeaseConduitAPIMethod.php
@@ -0,0 +1,63 @@
+<?php
+
+final class DrydockDestroyLeaseConduitAPIMethod
+ extends DrydockConduitAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'drydock.destroylease';
+ }
+
+ public function getMethodDescription() {
+ return pht('Destroy a Drydock lease.');
+ }
+
+ protected function defineParamTypes() {
+ return array(
+ 'leasePHID' => 'required phid',
+ );
+ }
+
+ protected function defineErrorTypes() {
+ return array(
+ 'ERR_NO_LEASE' => pht('No active lease exists with this ID.'),
+ 'ERR_NOT_AUTHORIZED' => pht(
+ 'You are not authorized to destroy this lease.'),
+ );
+ }
+
+ protected function defineReturnType() {
+ return 'map<string, wild>';
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $viewer = $request->getUser();
+ $lease = id(new DrydockLeaseQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($request->getValue('leasePHID')))
+ ->executeOne();
+ if (!$lease) {
+ throw new ConduitException('ERR_NO_LEASE');
+ }
+
+ if ($lease->getOwnerPHID() !== $viewer->getPHID()) {
+ throw new ConduitException('ERR_NOT_AUTHORIZED');
+ }
+
+ $command = DrydockCommand::initializeNewCommand($viewer)
+ ->setTargetPHID($lease->getPHID())
+ ->setCommand(DrydockCommand::COMMAND_RELEASE)
+ ->save();
+
+ $lease->scheduleUpdate();
+
+ $search = id(new ConduitCall('drydock.lease.search', array(
+ 'constraints' => array(
+ 'phids' => array($lease->getPHID()),
+ ),
+ )))
+ ->setUser($viewer)
+ ->execute();
+ return idxv($search, array('data', 0));
+ }
+
+}
diff --git a/src/applications/drydock/conduit/DrydockLeaseSearchConduitAPIMethod.php b/src/applications/drydock/conduit/DrydockLeaseSearchConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/conduit/DrydockLeaseSearchConduitAPIMethod.php
@@ -0,0 +1,18 @@
+<?php
+
+final class DrydockLeaseSearchConduitAPIMethod
+ extends PhabricatorSearchEngineAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'drydock.lease.search';
+ }
+
+ public function newSearchEngine() {
+ return new DrydockLeaseSearchEngine();
+ }
+
+ public function getMethodSummary() {
+ return pht('Retrieve information about Drydock leases.');
+ }
+
+}
diff --git a/src/applications/drydock/conduit/DrydockRequestAuthorizationConduitAPIMethod.php b/src/applications/drydock/conduit/DrydockRequestAuthorizationConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/conduit/DrydockRequestAuthorizationConduitAPIMethod.php
@@ -0,0 +1,73 @@
+<?php
+
+final class DrydockRequestAuthorizationConduitAPIMethod
+ extends DrydockConduitAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'drydock.requestauthorization';
+ }
+
+ public function getMethodDescription() {
+ return pht('Request permission to use a Drydock blueprint.');
+ }
+
+ protected function defineParamTypes() {
+ return array(
+ 'blueprintPHID' => 'required phid',
+ );
+ }
+
+ protected function defineErrorTypes() {
+ return array(
+ 'ERR_NO_BLUEPRINT' => pht(
+ 'No active blueprint exists with the specified PHID.'),
+ );
+ }
+
+ protected function defineReturnType() {
+ return 'map<string, wild>';
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $viewer = $request->getUser();
+ $blueprint_phid = $request->getValue('blueprintPHID');
+ $blueprint = id(new DrydockBlueprintQuery())
+ ->setViewer($viewer)
+ ->withDisabled(false)
+ ->withPHIDs(array($blueprint_phid))
+ ->executeOne();
+ if (!$blueprint) {
+ throw new ConduitException('ERR_NO_BLUEPRINT');
+ }
+
+ $authorizations = id(new DrydockAuthorizationQuery())
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($viewer->getPHID()))
+ ->withBlueprintStates(array(
+ DrydockAuthorization::BLUEPRINTAUTH_AUTHORIZED,
+ ))
+ ->withObjectStates(array(DrydockAuthorization::OBJECTAUTH_ACTIVE))
+ ->execute();
+ $authorizations = mpull($authorizations, null, 'getBlueprintPHID');
+ $old = array_keys($authorizations);
+ if (!in_array($blueprint_phid, $old)) {
+ $new = array_mergev(array($old, array($blueprint_phid)));
+ DrydockAuthorization::applyAuthorizationChanges(
+ $viewer,
+ $viewer->getPHID(),
+ $old,
+ $new);
+ }
+
+ $search = id(new ConduitCall('drydock.authorization.search', array(
+ 'constraints' => array(
+ 'objectPHIDs' => array($viewer->getPHID()),
+ 'blueprintPHIDs' => array($blueprint_phid),
+ ),
+ )))
+ ->setUser($viewer)
+ ->execute();
+ return idxv($search, array('data', 0));
+ }
+
+}
diff --git a/src/applications/drydock/query/DrydockAuthorizationSearchEngine.php b/src/applications/drydock/query/DrydockAuthorizationSearchEngine.php
--- a/src/applications/drydock/query/DrydockAuthorizationSearchEngine.php
+++ b/src/applications/drydock/query/DrydockAuthorizationSearchEngine.php
@@ -30,7 +30,9 @@
$query = new DrydockAuthorizationQuery();
$blueprint = $this->getBlueprint();
- $query->withBlueprintPHIDs(array($blueprint->getPHID()));
+ if ($blueprint) {
+ $query->withBlueprintPHIDs(array($blueprint->getPHID()));
+ }
return $query;
}
@@ -38,15 +40,46 @@
protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();
+ if ($map['blueprintPHIDs']) {
+ $query->withBlueprintPHIDs($map['blueprintPHIDs']);
+ }
+
+ if ($map['objectPHIDs']) {
+ $query->withObjectPHIDs($map['objectPHIDs']);
+ }
+
return $query;
}
protected function buildCustomSearchFields() {
- return array();
+ return array(
+ id(new PhabricatorSearchDatasourceField())
+ ->setLabel(pht('Blueprints'))
+ ->setKey('blueprintPHIDs')
+ ->setConduitParameterType(new ConduitPHIDListParameterType())
+ ->setDescription(pht('Search authorizations for specific blueprints.'))
+ ->setAliases(array('blueprint', 'blueprints'))
+ ->setDatasource(new DrydockBlueprintDatasource()),
+ id(new PhabricatorPHIDsSearchField())
+ ->setLabel(pht('Objects'))
+ ->setKey('objectPHIDs')
+ ->setDescription(pht('Search authorizations from specific objects.'))
+ ->setAliases(array('object', 'objects')),
+ );
+ }
+
+ protected function getHiddenFields() {
+ return array(
+ 'blueprintPHIDs',
+ 'objectPHIDs',
+ );
}
protected function getURI($path) {
$blueprint = $this->getBlueprint();
+ if (!$blueprint) {
+ throw new PhutilInvalidStateException('setBlueprint');
+ }
$id = $blueprint->getID();
return "/drydock/blueprint/{$id}/authorizations/".$path;
}
diff --git a/src/applications/drydock/query/DrydockLeaseQuery.php b/src/applications/drydock/query/DrydockLeaseQuery.php
--- a/src/applications/drydock/query/DrydockLeaseQuery.php
+++ b/src/applications/drydock/query/DrydockLeaseQuery.php
@@ -5,6 +5,7 @@
private $ids;
private $phids;
private $resourcePHIDs;
+ private $ownerPHIDs;
private $statuses;
private $datasourceQuery;
private $needUnconsumedCommands;
@@ -24,6 +25,11 @@
return $this;
}
+ public function withOwnerPHIDs(array $phids) {
+ $this->ownerPHIDs = $phids;
+ return $this;
+ }
+
public function withStatuses(array $statuses) {
$this->statuses = $statuses;
return $this;
@@ -105,6 +111,13 @@
$this->resourcePHIDs);
}
+ if ($this->ownerPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'ownerPHID IN (%Ls)',
+ $this->ownerPHIDs);
+ }
+
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
diff --git a/src/applications/drydock/query/DrydockLeaseSearchEngine.php b/src/applications/drydock/query/DrydockLeaseSearchEngine.php
--- a/src/applications/drydock/query/DrydockLeaseSearchEngine.php
+++ b/src/applications/drydock/query/DrydockLeaseSearchEngine.php
@@ -40,6 +40,10 @@
$query->withStatuses($map['statuses']);
}
+ if ($map['ownerPHIDs']) {
+ $query->withOwnerPHIDs($map['ownerPHIDs']);
+ }
+
return $query;
}
@@ -49,6 +53,13 @@
->setLabel(pht('Statuses'))
->setKey('statuses')
->setOptions(DrydockLeaseStatus::getStatusMap()),
+ id(new PhabricatorSearchDatasourceField())
+ ->setLabel(pht('Owners'))
+ ->setKey('ownerPHIDs')
+ ->setDescription(pht('Search leases by owner.'))
+ ->setAliases(array('owner', 'owners'))
+ ->setConduitParameterType(new ConduitPHIDListParameterType())
+ ->setDatasource(new PhabricatorPeopleUserFunctionDatasource()),
);
}
diff --git a/src/applications/drydock/storage/DrydockAuthorization.php b/src/applications/drydock/storage/DrydockAuthorization.php
--- a/src/applications/drydock/storage/DrydockAuthorization.php
+++ b/src/applications/drydock/storage/DrydockAuthorization.php
@@ -2,7 +2,8 @@
final class DrydockAuthorization extends DrydockDAO
implements
- PhabricatorPolicyInterface {
+ PhabricatorPolicyInterface,
+ PhabricatorConduitResultInterface {
const OBJECTAUTH_ACTIVE = 'active';
const OBJECTAUTH_INACTIVE = 'inactive';
@@ -204,4 +205,52 @@
}
+/* -( PhabricatorConduitResultInterface )---------------------------------- */
+
+
+ public function getFieldSpecificationsForConduit() {
+ return array(
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('blueprintPHID')
+ ->setType('phid')
+ ->setDescription(pht(
+ 'PHID of the blueprint this request was made for.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('blueprintAuthorizationState')
+ ->setType('map<string, wild>')
+ ->setDescription(pht('Authorization state of this request.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('objectPHID')
+ ->setType('phid')
+ ->setDescription(pht(
+ 'PHID of the object which requested authorization.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('objectAuthorizationState')
+ ->setType('map<string, wild>')
+ ->setDescription(pht('Authorization state of the requesting object.')),
+ );
+ }
+
+ public function getFieldValuesForConduit() {
+ $blueprint_state = $this->getBlueprintAuthorizationState();
+ $object_state = $this->getObjectAuthorizationState();
+ return array(
+ 'blueprintPHID' => $this->getBlueprintPHID(),
+ 'blueprintAuthorizationState' => array(
+ 'value' => $blueprint_state,
+ 'name' => self::getBlueprintStateName($blueprint_state),
+ ),
+ 'objectPHID' => $this->getObjectPHID(),
+ 'objectAuthorizationState' => array(
+ 'value' => $object_state,
+ 'name' => self::getObjectStateName($object_state),
+ ),
+ );
+ }
+
+ public function getConduitSearchAttachments() {
+ return array(
+ );
+ }
+
}
diff --git a/src/applications/drydock/storage/DrydockBlueprint.php b/src/applications/drydock/storage/DrydockBlueprint.php
--- a/src/applications/drydock/storage/DrydockBlueprint.php
+++ b/src/applications/drydock/storage/DrydockBlueprint.php
@@ -10,7 +10,8 @@
PhabricatorPolicyInterface,
PhabricatorCustomFieldInterface,
PhabricatorNgramsInterface,
- PhabricatorProjectInterface {
+ PhabricatorProjectInterface,
+ PhabricatorConduitResultInterface {
protected $className;
protected $blueprintName;
@@ -360,4 +361,38 @@
);
}
+
+/* -( PhabricatorConduitResultInterface )---------------------------------- */
+
+
+ public function getFieldSpecificationsForConduit() {
+ return array(
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('name')
+ ->setType('string')
+ ->setDescription(pht('The name of this blueprint.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('type')
+ ->setType('string')
+ ->setDescription(pht('The type of resource this blueprint provides.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('class')
+ ->setType('string')
+ ->setDescription(pht('The implementation class for this blueprint.')),
+ );
+ }
+
+ public function getFieldValuesForConduit() {
+ return array(
+ 'name' => $this->getBlueprintName(),
+ 'type' => $this->getImplementation()->getType(),
+ 'class' => $this->getClassName(),
+ );
+ }
+
+ public function getConduitSearchAttachments() {
+ return array(
+ );
+ }
+
}
diff --git a/src/applications/drydock/storage/DrydockLease.php b/src/applications/drydock/storage/DrydockLease.php
--- a/src/applications/drydock/storage/DrydockLease.php
+++ b/src/applications/drydock/storage/DrydockLease.php
@@ -1,7 +1,9 @@
<?php
final class DrydockLease extends DrydockDAO
- implements PhabricatorPolicyInterface {
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorConduitResultInterface {
protected $resourcePHID;
protected $resourceType;
@@ -83,6 +85,9 @@
'key_resource' => array(
'columns' => array('resourcePHID', 'status'),
),
+ 'key_owner' => array(
+ 'columns' => array('ownerPHID'),
+ ),
),
) + parent::getConfiguration();
}
@@ -497,4 +502,65 @@
return pht('Leases inherit policies from the resources they lease.');
}
+
+/* -( PhabricatorConduitResultInterface )---------------------------------- */
+
+
+ public function getFieldSpecificationsForConduit() {
+ return array(
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('resourcePHID')
+ ->setType('phid?')
+ ->setDescription(pht('PHID of the leased resource, if any.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('resourceType')
+ ->setType('string')
+ ->setDescription(pht('Type of resource being leased.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('until')
+ ->setType('int?')
+ ->setDescription(pht('Epoch at which this lease expires, if any.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('ownerPHID')
+ ->setType('phid?')
+ ->setDescription(pht('The PHID of the object that owns this lease.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('authorizingPHID')
+ ->setType('phid')
+ ->setDescription(pht(
+ 'The PHID of the object that authorized this lease.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('attributes')
+ ->setType('map<string, wild>')
+ ->setDescription(pht(
+ 'Implementation specific attributes for this lease.')),
+ id(new PhabricatorConduitSearchFieldSpecification())
+ ->setKey('status')
+ ->setType('map<string, wild>')
+ ->setDescription(pht(
+ "The string constant and name of this lease's status.")),
+ );
+ }
+
+ public function getFieldValuesForConduit() {
+ $status = $this->getStatus();
+ return array(
+ 'resourcePHID' => $this->getResourcePHID(),
+ 'resourceType' => $this->getResourceType(),
+ 'until' => $this->getUntil(),
+ 'ownerPHID' => $this->getOwnerPHID(),
+ 'authorizingPHID' => $this->getAuthorizingPHID(),
+ 'attributes' => $this->getAttributes(),
+ 'status' => array(
+ 'value' => $status,
+ 'name' => DrydockLeaseStatus::getNameForStatus($status),
+ ),
+ );
+ }
+
+ public function getConduitSearchAttachments() {
+ return array(
+ );
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 26, 3:06 PM (3 w, 11 h ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/gj/dq/a3hpgohptiajwk3i
Default Alt Text
D16565.id39874.diff (34 KB)

Event Timeline