Find this useful? Enter your email to receive occasional updates for securing PHP code.

Signing you up...

Thank you for signing up!

PHP Decode

<?php final class DrydockAlmanacServiceHostBlueprintImplementation extends DrydockBluep..

Decoded Output download

<?php

final class DrydockAlmanacServiceHostBlueprintImplementation
  extends DrydockBlueprintImplementation {

  private $services;
  private $freeBindings;

  public function isEnabled() {
    $almanac_app = 'PhabricatorAlmanacApplication';
    return PhabricatorApplication::isClassInstalled($almanac_app);
  }

  public function getBlueprintName() {
    return pht('Almanac Hosts');
  }

  public function getBlueprintIcon() {
    return 'fa-server';
  }

  public function getDescription() {
    return pht(
      'Allows Drydock to lease existing hosts defined in an Almanac service '.
      'pool.');
  }

  public function canAnyBlueprintEverAllocateResourceForLease(
    DrydockLease $lease) {
    return true;
  }

  public function canEverAllocateResourceForLease(
    DrydockBlueprint $blueprint,
    DrydockLease $lease) {
    $services = $this->loadServices($blueprint);
    $bindings = $this->getActiveBindings($services);

    if (!$bindings) {
      // If there are no devices bound to the services for this blueprint,
      // we can not allocate resources.
      return false;
    }

    return true;
  }

  public function shouldAllocateSupplementalResource(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {
    // We want to use every host in an Almanac service, since the amount of
    // hardware is fixed and there's normally no value in packing leases onto a
    // subset of it. Always build a new supplemental resource if we can.
    return true;
  }

  public function canAllocateResourceForLease(
    DrydockBlueprint $blueprint,
    DrydockLease $lease) {

    // We will only allocate one resource per unique device bound to the
    // services for this blueprint. Make sure we have a free device somewhere.
    $free_bindings = $this->loadFreeBindings($blueprint);
    if (!$free_bindings) {
      return false;
    }

    return true;
  }

  public function allocateResource(
    DrydockBlueprint $blueprint,
    DrydockLease $lease) {

    $free_bindings = $this->loadFreeBindings($blueprint);
    shuffle($free_bindings);

    $exceptions = array();
    foreach ($free_bindings as $binding) {
      $device = $binding->getDevice();
      $device_name = $device->getName();

      $binding_phid = $binding->getPHID();

      $resource = $this->newResourceTemplate($blueprint)
        ->setActivateWhenAllocated(true)
        ->setAttribute('almanacDeviceName', $device_name)
        ->setAttribute('almanacServicePHID', $binding->getServicePHID())
        ->setAttribute('almanacBindingPHID', $binding_phid)
        ->needSlotLock("almanac.host.binding({$binding_phid})");

      try {
        return $resource->allocateResource();
      } catch (Exception $ex) {
        $exceptions[] = $ex;
      }
    }

    throw new PhutilAggregateException(
      pht('Unable to allocate any binding as a resource.'),
      $exceptions);
  }

  public function destroyResource(
    DrydockBlueprint $blueprint,
    DrydockResource $resource) {
    // We don't create anything when allocating hosts, so we don't need to do
    // any cleanup here.
    return;
  }

  public function getResourceName(
    DrydockBlueprint $blueprint,
    DrydockResource $resource) {
    $device_name = $resource->getAttribute(
      'almanacDeviceName',
      pht('<Unknown>'));
    return pht('Host (%s)', $device_name);
  }

  public function canAcquireLeaseOnResource(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {

    // Require the binding to a given host be active before we'll hand out more
    // leases on the corresponding resource.
    $binding = $this->loadBindingForResource($resource);
    if ($binding->getIsDisabled()) {
      return false;
    }

    return true;
  }

  public function acquireLease(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {

    $lease
      ->setActivateWhenAcquired(true)
      ->acquireOnResource($resource);
  }

  public function didReleaseLease(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {
    // Almanac hosts stick around indefinitely so we don't need to recycle them
    // if they don't have any leases.
    return;
  }

  public function destroyLease(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {
    // We don't create anything when activating a lease, so we don't need to
    // throw anything away.
    return;
  }

  public function getType() {
    return 'host';
  }

  public function getInterface(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease,
    $type) {

    switch ($type) {
      case DrydockCommandInterface::INTERFACE_TYPE:
        $credential_phid = $blueprint->getFieldValue('credentialPHID');
        $binding = $this->loadBindingForResource($resource);
        $interface = $binding->getInterface();

        return id(new DrydockSSHCommandInterface())
          ->setConfig('credentialPHID', $credential_phid)
          ->setConfig('host', $interface->getAddress())
          ->setConfig('port', $interface->getPort());
    }
  }

  protected function getCustomFieldSpecifications() {
    return array(
      'almanacServicePHIDs' => array(
        'name' => pht('Almanac Services'),
        'type' => 'datasource',
        'datasource.class' => 'AlmanacServiceDatasource',
        'datasource.parameters' => array(
          'serviceTypes' => $this->getAlmanacServiceTypes(),
        ),
        'required' => true,
      ),
      'credentialPHID' => array(
        'name' => pht('Credentials'),
        'type' => 'credential',
        'credential.provides' =>
          PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE,
        'credential.type' =>
          PassphraseSSHPrivateKeyTextCredentialType::CREDENTIAL_TYPE,
      ),
    );
  }

  private function loadServices(DrydockBlueprint $blueprint) {
    if (!$this->services) {
      $service_phids = $blueprint->getFieldValue('almanacServicePHIDs');
      if (!$service_phids) {
        throw new Exception(
          pht(
            'This blueprint ("%s") does not define any Almanac Service PHIDs.',
            $blueprint->getBlueprintName()));
      }

      $viewer = $this->getViewer();
      $services = id(new AlmanacServiceQuery())
        ->setViewer($viewer)
        ->withPHIDs($service_phids)
        ->withServiceTypes($this->getAlmanacServiceTypes())
        ->needActiveBindings(true)
        ->execute();
      $services = mpull($services, null, 'getPHID');

      if (count($services) != count($service_phids)) {
        $missing_phids = array_diff($service_phids, array_keys($services));
        throw new Exception(
          pht(
            'Some of the Almanac Services defined by this blueprint '.
            'could not be loaded. They may be invalid, no longer exist, '.
            'or be of the wrong type: %s.',
            implode(', ', $missing_phids)));
      }

      $this->services = $services;
    }

    return $this->services;
  }

  private function getActiveBindings(array $services) {
    assert_instances_of($services, 'AlmanacService');
    $bindings = array_mergev(mpull($services, 'getActiveBindings'));
    return mpull($bindings, null, 'getPHID');
  }

  private function loadFreeBindings(DrydockBlueprint $blueprint) {
    if ($this->freeBindings === null) {
      $viewer = $this->getViewer();

      $pool = id(new DrydockResourceQuery())
        ->setViewer($viewer)
        ->withBlueprintPHIDs(array($blueprint->getPHID()))
        ->withStatuses(
          array(
            DrydockResourceStatus::STATUS_PENDING,
            DrydockResourceStatus::STATUS_ACTIVE,
            DrydockResourceStatus::STATUS_BROKEN,
            DrydockResourceStatus::STATUS_RELEASED,
          ))
        ->execute();

      $allocated_phids = array();
      foreach ($pool as $resource) {
        $allocated_phids[] = $resource->getAttribute('almanacBindingPHID');
      }
      $allocated_phids = array_fuse($allocated_phids);

      $services = $this->loadServices($blueprint);
      $bindings = $this->getActiveBindings($services);

      $free = array();
      foreach ($bindings as $binding) {
        if (empty($allocated_phids[$binding->getPHID()])) {
          $free[] = $binding;
        }
      }

      $this->freeBindings = $free;
    }

    return $this->freeBindings;
  }

  private function getAlmanacServiceTypes() {
    return array(
      AlmanacDrydockPoolServiceType::SERVICETYPE,
    );
  }

  private function loadBindingForResource(DrydockResource $resource) {
    $binding_phid = $resource->getAttribute('almanacBindingPHID');
    if (!$binding_phid) {
      throw new Exception(
        pht(
          'Drydock resource ("%s") has no Almanac binding PHID, so its '.
          'binding can not be loaded.',
          $resource->getPHID()));
    }

    $viewer = $this->getViewer();

    $binding = id(new AlmanacBindingQuery())
      ->setViewer($viewer)
      ->withPHIDs(array($binding_phid))
      ->executeOne();
    if (!$binding) {
      throw new Exception(
        pht(
          'Unable to load Almanac binding ("%s") for resource ("%s").',
          $binding_phid,
          $resource->getPHID()));
    }

    return $binding;
  }

}
 ?>

Did this file decode correctly?

Original Code

<?php

final class DrydockAlmanacServiceHostBlueprintImplementation
  extends DrydockBlueprintImplementation {

  private $services;
  private $freeBindings;

  public function isEnabled() {
    $almanac_app = 'PhabricatorAlmanacApplication';
    return PhabricatorApplication::isClassInstalled($almanac_app);
  }

  public function getBlueprintName() {
    return pht('Almanac Hosts');
  }

  public function getBlueprintIcon() {
    return 'fa-server';
  }

  public function getDescription() {
    return pht(
      'Allows Drydock to lease existing hosts defined in an Almanac service '.
      'pool.');
  }

  public function canAnyBlueprintEverAllocateResourceForLease(
    DrydockLease $lease) {
    return true;
  }

  public function canEverAllocateResourceForLease(
    DrydockBlueprint $blueprint,
    DrydockLease $lease) {
    $services = $this->loadServices($blueprint);
    $bindings = $this->getActiveBindings($services);

    if (!$bindings) {
      // If there are no devices bound to the services for this blueprint,
      // we can not allocate resources.
      return false;
    }

    return true;
  }

  public function shouldAllocateSupplementalResource(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {
    // We want to use every host in an Almanac service, since the amount of
    // hardware is fixed and there's normally no value in packing leases onto a
    // subset of it. Always build a new supplemental resource if we can.
    return true;
  }

  public function canAllocateResourceForLease(
    DrydockBlueprint $blueprint,
    DrydockLease $lease) {

    // We will only allocate one resource per unique device bound to the
    // services for this blueprint. Make sure we have a free device somewhere.
    $free_bindings = $this->loadFreeBindings($blueprint);
    if (!$free_bindings) {
      return false;
    }

    return true;
  }

  public function allocateResource(
    DrydockBlueprint $blueprint,
    DrydockLease $lease) {

    $free_bindings = $this->loadFreeBindings($blueprint);
    shuffle($free_bindings);

    $exceptions = array();
    foreach ($free_bindings as $binding) {
      $device = $binding->getDevice();
      $device_name = $device->getName();

      $binding_phid = $binding->getPHID();

      $resource = $this->newResourceTemplate($blueprint)
        ->setActivateWhenAllocated(true)
        ->setAttribute('almanacDeviceName', $device_name)
        ->setAttribute('almanacServicePHID', $binding->getServicePHID())
        ->setAttribute('almanacBindingPHID', $binding_phid)
        ->needSlotLock("almanac.host.binding({$binding_phid})");

      try {
        return $resource->allocateResource();
      } catch (Exception $ex) {
        $exceptions[] = $ex;
      }
    }

    throw new PhutilAggregateException(
      pht('Unable to allocate any binding as a resource.'),
      $exceptions);
  }

  public function destroyResource(
    DrydockBlueprint $blueprint,
    DrydockResource $resource) {
    // We don't create anything when allocating hosts, so we don't need to do
    // any cleanup here.
    return;
  }

  public function getResourceName(
    DrydockBlueprint $blueprint,
    DrydockResource $resource) {
    $device_name = $resource->getAttribute(
      'almanacDeviceName',
      pht('<Unknown>'));
    return pht('Host (%s)', $device_name);
  }

  public function canAcquireLeaseOnResource(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {

    // Require the binding to a given host be active before we'll hand out more
    // leases on the corresponding resource.
    $binding = $this->loadBindingForResource($resource);
    if ($binding->getIsDisabled()) {
      return false;
    }

    return true;
  }

  public function acquireLease(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {

    $lease
      ->setActivateWhenAcquired(true)
      ->acquireOnResource($resource);
  }

  public function didReleaseLease(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {
    // Almanac hosts stick around indefinitely so we don't need to recycle them
    // if they don't have any leases.
    return;
  }

  public function destroyLease(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease) {
    // We don't create anything when activating a lease, so we don't need to
    // throw anything away.
    return;
  }

  public function getType() {
    return 'host';
  }

  public function getInterface(
    DrydockBlueprint $blueprint,
    DrydockResource $resource,
    DrydockLease $lease,
    $type) {

    switch ($type) {
      case DrydockCommandInterface::INTERFACE_TYPE:
        $credential_phid = $blueprint->getFieldValue('credentialPHID');
        $binding = $this->loadBindingForResource($resource);
        $interface = $binding->getInterface();

        return id(new DrydockSSHCommandInterface())
          ->setConfig('credentialPHID', $credential_phid)
          ->setConfig('host', $interface->getAddress())
          ->setConfig('port', $interface->getPort());
    }
  }

  protected function getCustomFieldSpecifications() {
    return array(
      'almanacServicePHIDs' => array(
        'name' => pht('Almanac Services'),
        'type' => 'datasource',
        'datasource.class' => 'AlmanacServiceDatasource',
        'datasource.parameters' => array(
          'serviceTypes' => $this->getAlmanacServiceTypes(),
        ),
        'required' => true,
      ),
      'credentialPHID' => array(
        'name' => pht('Credentials'),
        'type' => 'credential',
        'credential.provides' =>
          PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE,
        'credential.type' =>
          PassphraseSSHPrivateKeyTextCredentialType::CREDENTIAL_TYPE,
      ),
    );
  }

  private function loadServices(DrydockBlueprint $blueprint) {
    if (!$this->services) {
      $service_phids = $blueprint->getFieldValue('almanacServicePHIDs');
      if (!$service_phids) {
        throw new Exception(
          pht(
            'This blueprint ("%s") does not define any Almanac Service PHIDs.',
            $blueprint->getBlueprintName()));
      }

      $viewer = $this->getViewer();
      $services = id(new AlmanacServiceQuery())
        ->setViewer($viewer)
        ->withPHIDs($service_phids)
        ->withServiceTypes($this->getAlmanacServiceTypes())
        ->needActiveBindings(true)
        ->execute();
      $services = mpull($services, null, 'getPHID');

      if (count($services) != count($service_phids)) {
        $missing_phids = array_diff($service_phids, array_keys($services));
        throw new Exception(
          pht(
            'Some of the Almanac Services defined by this blueprint '.
            'could not be loaded. They may be invalid, no longer exist, '.
            'or be of the wrong type: %s.',
            implode(', ', $missing_phids)));
      }

      $this->services = $services;
    }

    return $this->services;
  }

  private function getActiveBindings(array $services) {
    assert_instances_of($services, 'AlmanacService');
    $bindings = array_mergev(mpull($services, 'getActiveBindings'));
    return mpull($bindings, null, 'getPHID');
  }

  private function loadFreeBindings(DrydockBlueprint $blueprint) {
    if ($this->freeBindings === null) {
      $viewer = $this->getViewer();

      $pool = id(new DrydockResourceQuery())
        ->setViewer($viewer)
        ->withBlueprintPHIDs(array($blueprint->getPHID()))
        ->withStatuses(
          array(
            DrydockResourceStatus::STATUS_PENDING,
            DrydockResourceStatus::STATUS_ACTIVE,
            DrydockResourceStatus::STATUS_BROKEN,
            DrydockResourceStatus::STATUS_RELEASED,
          ))
        ->execute();

      $allocated_phids = array();
      foreach ($pool as $resource) {
        $allocated_phids[] = $resource->getAttribute('almanacBindingPHID');
      }
      $allocated_phids = array_fuse($allocated_phids);

      $services = $this->loadServices($blueprint);
      $bindings = $this->getActiveBindings($services);

      $free = array();
      foreach ($bindings as $binding) {
        if (empty($allocated_phids[$binding->getPHID()])) {
          $free[] = $binding;
        }
      }

      $this->freeBindings = $free;
    }

    return $this->freeBindings;
  }

  private function getAlmanacServiceTypes() {
    return array(
      AlmanacDrydockPoolServiceType::SERVICETYPE,
    );
  }

  private function loadBindingForResource(DrydockResource $resource) {
    $binding_phid = $resource->getAttribute('almanacBindingPHID');
    if (!$binding_phid) {
      throw new Exception(
        pht(
          'Drydock resource ("%s") has no Almanac binding PHID, so its '.
          'binding can not be loaded.',
          $resource->getPHID()));
    }

    $viewer = $this->getViewer();

    $binding = id(new AlmanacBindingQuery())
      ->setViewer($viewer)
      ->withPHIDs(array($binding_phid))
      ->executeOne();
    if (!$binding) {
      throw new Exception(
        pht(
          'Unable to load Almanac binding ("%s") for resource ("%s").',
          $binding_phid,
          $resource->getPHID()));
    }

    return $binding;
  }

}

Function Calls

None

Variables

None

Stats

MD5 5e2f9f6d1de4e9b0707a81ff46a167f5
Eval Count 0
Decode Time 94 ms