1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-27 23:18:20 +01:00
phorge-phorge/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
epriestley f74e6bbf8d Make "phabricator.silent" disable build steps which rely on external services
Summary:
Depends on D19084. Fixes T13078. When `phabricator.silent` is enabled, immediately fail the "HTTP Request", "CircleCI" and "Buildkite" build steps.

This doesn't feel quite as clean as most of the other behavior of `phabricator.silent`, since these calls are not exactly notifications in the same way that email is, and failing to make these calls means that builds run differently (whereas failing to deliver email doesn't really do anything).

However, I suspect that this behavior is almost always reasonable/correct, and that we can probably get away with it until this grey area between "notifications" and "external service calls" is more clearly defined.

Test Plan:
  - Created a build with HTTP, CircleCI, and Buildkite steps.
  - Put install in `phabricator.silent` mode: all three steps failed with "declining, because silent" messages.
  - Put install back in normal mode: all three steps made HTTP requests.
  - Read updated documentation.

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13078

Differential Revision: https://secure.phabricator.com/D19085
2018-02-14 11:41:47 -08:00

116 lines
2.9 KiB
PHP

<?php
final class HarbormasterHTTPRequestBuildStepImplementation
extends HarbormasterBuildStepImplementation {
public function getName() {
return pht('Make HTTP Request');
}
public function getGenericDescription() {
return pht('Make an HTTP request.');
}
public function getBuildStepGroupKey() {
return HarbormasterExternalBuildStepGroup::GROUPKEY;
}
public function getDescription() {
$domain = null;
$uri = $this->getSetting('uri');
if ($uri) {
$domain = id(new PhutilURI($uri))->getDomain();
}
$method = $this->formatSettingForDescription('method', 'POST');
$domain = $this->formatValueForDescription($domain);
if ($this->getSetting('credential')) {
return pht(
'Make an authenticated HTTP %s request to %s.',
$method,
$domain);
} else {
return pht(
'Make an HTTP %s request to %s.',
$method,
$domain);
}
}
public function execute(
HarbormasterBuild $build,
HarbormasterBuildTarget $build_target) {
$viewer = PhabricatorUser::getOmnipotentUser();
if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
$this->logSilencedCall($build, $build_target, pht('HTTP Request'));
throw new HarbormasterBuildFailureException();
}
$settings = $this->getSettings();
$variables = $build_target->getVariables();
$uri = $this->mergeVariables(
'vurisprintf',
$settings['uri'],
$variables);
$method = nonempty(idx($settings, 'method'), 'POST');
$future = id(new HTTPSFuture($uri))
->setMethod($method)
->setTimeout(60);
$credential_phid = $this->getSetting('credential');
if ($credential_phid) {
$key = PassphrasePasswordKey::loadFromPHID(
$credential_phid,
$viewer);
$future->setHTTPBasicAuthCredentials(
$key->getUsernameEnvelope()->openEnvelope(),
$key->getPasswordEnvelope());
}
$this->resolveFutures(
$build,
$build_target,
array($future));
$this->logHTTPResponse($build, $build_target, $future, $uri);
list($status) = $future->resolve();
if ($status->isError()) {
throw new HarbormasterBuildFailureException();
}
}
public function getFieldSpecifications() {
return array(
'uri' => array(
'name' => pht('URI'),
'type' => 'text',
'required' => true,
),
'method' => array(
'name' => pht('HTTP Method'),
'type' => 'select',
'options' => array_fuse(array('POST', 'GET', 'PUT', 'DELETE')),
),
'credential' => array(
'name' => pht('Credentials'),
'type' => 'credential',
'credential.type'
=> PassphrasePasswordCredentialType::CREDENTIAL_TYPE,
'credential.provides'
=> PassphrasePasswordCredentialType::PROVIDES_TYPE,
),
);
}
public function supportsWaitForMessage() {
return true;
}
}