Skip to content

Commit

Permalink
Merge branch 'jwh315-feature-lb'
Browse files Browse the repository at this point in the history
  • Loading branch information
yassirh committed May 27, 2017
2 parents c894bb1 + 4948dbf commit 4464ceb
Show file tree
Hide file tree
Showing 10 changed files with 726 additions and 0 deletions.
27 changes: 27 additions & 0 deletions README.md
Expand Up @@ -400,6 +400,33 @@ $updatedKey = $key->update(123, 'new-key-name');
$key->delete(123);
```

Load Balancer
-------------

```php
// ..
// return the load balancer api
$loadBalancer = $digitalocean->loadbalancer();

//returns a collection of Load Balancer entities
$loadBalancers = $loadBalancer->getAll();

//return a Load Balancer entity by id
$myLoadBalancer = $loadBalancer->getById('506f78a4-e098-11e5-ad9f-000f53306ae1');

/**
* updates an existing load balancer, the method will except a LoadBalancer
* entity or a load balancer representation in array form, the digitial
* Ocean API requires a full representation of your load
* balancer, any attribute that is missing will
* be reset to it's default setting.
*/
$myUpdatedLoadBalancer = $loadBalancer->update('506f78a4-e098-11e5-ad9f-000f53306ae1', $myLoadBalancer);

//create a standard load balancer that listens on port 80 and 443 with ssl passthrough enabled
$myNewLoadBalancer = $loadBalancer->create('my-new-load-balancer', 'nyc1');
```

Region
------

Expand Down
193 changes: 193 additions & 0 deletions spec/DigitalOceanV2/Api/LoadBalancerSpec.php
@@ -0,0 +1,193 @@
<?php

namespace spec\DigitalOceanV2\Api;

use DigitalOceanV2\Adapter\AdapterInterface;
use DigitalOceanV2\Exception\HttpException;

class LoadBalancerSpec extends \PhpSpec\ObjectBehavior
{
function let(AdapterInterface $adapter)
{
$this->beConstructedWith($adapter);
}

function it_is_initializable()
{
$this->shouldHaveType('DigitalOceanV2\Api\LoadBalancer');
}

public function it_throws_an_http_exception_if_load_balancer_does_not_exist($adapter)
{
$adapter
->get('https://api.digitalocean.com/v2/load_balancers/1234')
->willThrow(new HttpException('Load Balancer not found'));

$this->shouldThrow(new HttpException('Load Balancer not found'))->duringGetById(1234);
}

public function it_returns_an_array_of_load_balancer_entity($adapter)
{
$total = 3;
$adapter->get('https://api.digitalocean.com/v2/load_balancers')
->willReturn(json_encode([
'load_balancers' => [
[],
[],
[],
],
'links' => [],
'meta' => [
'total' => $total,
],
]));

$loadBalancers = $this->getAll();
$loadBalancers->shouldBeArray();
$loadBalancers->shouldHaveCount($total);
foreach ($loadBalancers as $loadBalancer) {
$loadBalancer->shouldReturnAnInstanceOf('DigitalOceanV2\Entity\LoadBalancer');
}

$meta = $this->getMeta();
$meta->shouldBeAnInstanceOf('DigitalOceanV2\Entity\Meta');
$meta->total->shouldBe($total);
}

public function it_returns_a_load_balancer_entity_by_its_id($adapter)
{
$adapter->get('https://api.digitalocean.com/v2/load_balancers/1234')
->willReturn(json_encode($this->getLoadBalancerSpecification()));

$loadBalancer = $this->getById('1234');
$loadBalancer->shouldBeAnInstanceOf('DigitalOceanV2\Entity\LoadBalancer');
}

public function it_returns_a_created_load_balancer($adapter)
{
$loadBalancerSpecification = $this->getLoadBalancerSpecification();

$lbs = $loadBalancerSpecification['load_balancer'];
$data = [
'name' => $lbs['name'],
'algorithm' => 'round_robin',
'region' => 'nyc1',
'forwarding_rules' => $lbs['forwarding_rules'],
'health_check' => [],
'sticky_sessions' => [],
'droplet_ids' => [],
'redirect_http_to_https' => false,
];

$adapter
->post('https://api.digitalocean.com/v2/load_balancers', $data)
->willReturn(json_encode($loadBalancerSpecification));

$loadBalancer = $this->create('example-lb-01', 'nyc1', $lbs['forwarding_rules']);
$loadBalancer->shouldBeAnInstanceOf('DigitalOceanV2\Entity\LoadBalancer');
}

public function it_updates_an_existing_load_balancer($adapter)
{
$loadBalancerSpecification = $this->getLoadBalancerSpecification();
$lbs = $loadBalancerSpecification['load_balancer'];
$data = [
'name' => $lbs['name'],
'algorithm' => 'round_robin',
'region' => 'nyc1',
'forwarding_rules' => $lbs['forwarding_rules'],
'health_check' => [],
'sticky_sessions' => [],
'droplet_ids' => [],
'redirect_http_to_https' => false,
];

$adapter
->put('https://api.digitalocean.com/v2/load_balancers/'.$lbs['id'], $data)
->willReturn(json_encode($loadBalancerSpecification));

$loadBalancer = $this->update($lbs['id'], $data);
$loadBalancer->shouldBeAnInstanceOf('DigitalOceanV2\Entity\LoadBalancer');
}

/**
* @return string
*/
private function getLoadBalancerSpecification()
{
return [
'load_balancer' => [
'id' => '1234',
'name' => 'example-lb-01',
'ip' => '104.131.186.241',
'algorithm' => 'round_robin',
'status' => 'new',
'created_at' => '2017-02-01T22:22:58Z',
'forwarding_rules' => [
[
'entry_protocol' => 'http',
'entry_port' => 80,
'target_protocol' => 'http',
'target_port' => 80,
'certificate_id' => '',
'tls_passthrough' => false,
],
[
'entry_protocol' => 'https',
'entry_port' => 444,
'target_protocol' => 'https',
'target_port' => 443,
'certificate_id' => '',
'tls_passthrough' => true,
],
],
'health_check' => [
'protocol' => 'http',
'port' => 80,
'path' => '/',
'check_interval_seconds' => 10,
'response_timeout_seconds' => 5,
'healthy_threshold' => 5,
'unhealthy_threshold' => 3,
],
'sticky_sessions' => [
'type' => 'none',
],
'region' => [
'name' => 'New York 3',
'slug' => 'nyc3',
'sizes' => [
'512mb',
'1gb',
'2gb',
'4gb',
'8gb',
'16gb',
'm-16gb',
'32gb',
'm-32gb',
'48gb',
'm-64gb',
'64gb',
'm-128gb',
'm-224gb',
],
'features' => [
'private_networking',
'backups',
'ipv6',
'metadata',
'install_agent',
],
'available' => true,
],
'tag' => '',
'droplet_ids' => [
3164444,
3164445,
],
'redirect_http_to_https' => false,
],
];
}
}
5 changes: 5 additions & 0 deletions spec/DigitalOceanV2/DigitalOceanV2Spec.php
Expand Up @@ -61,6 +61,11 @@ function it_should_return_a_key_instance()
$this->key()->shouldBeAnInstanceOf('DigitalOceanV2\Api\Key');
}

function it_should_return_a_load_balancer_instance()
{
$this->loadBalancer()->shouldBeAnInstanceOf('DigitalOceanV2\Api\LoadBalancer');
}

function it_should_return_a_rate_limit_instance()
{
$this->rateLimit()->shouldBeAnInstanceOf('DigitalOceanV2\Api\RateLimit');
Expand Down
156 changes: 156 additions & 0 deletions src/Api/LoadBalancer.php
@@ -0,0 +1,156 @@
<?php

/*
* This file is part of the DigitalOceanV2 library.
*
* (c) Antoine Corcy <contact@sbin.dk>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace DigitalOceanV2\Api;

use DigitalOceanV2\Entity\AbstractEntity;
use DigitalOceanV2\Entity\ForwardingRule as ForwardRuleEntity;
use DigitalOceanV2\Entity\HealthCheck as HealthCheckEntity;
use DigitalOceanV2\Entity\LoadBalancer as LoadBalancerEntity;
use DigitalOceanV2\Exception\HttpException;

/**
* @author Jacob Holmes <jwh315@cox.net>
*/
class LoadBalancer extends AbstractApi
{
/**
* @return LoadBalancerEntity[]
*/
public function getAll()
{
$loadBalancers = $this->adapter->get(sprintf('%s/load_balancers', $this->endpoint));

$loadBalancers = json_decode($loadBalancers);

$this->extractMeta($loadBalancers);

return array_map(function ($key) {
return new LoadBalancerEntity($key);
}, $loadBalancers->load_balancers);
}

/**
* @param string $id
*
* @throws HttpException
*
* @return LoadBalancerEntity
*/
public function getById($id)
{
$loadBalancer = $this->adapter->get(sprintf('%s/load_balancers/%s', $this->endpoint, $id));

$loadBalancer = json_decode($loadBalancer);

return new LoadBalancerEntity($loadBalancer->load_balancer);
}

/**
* @param string $name
* @param string $region
* @param array|ForwardRuleEntity[] $forwardRules
* @param string $algorithm
* @param array|HealthCheckEntity[] $healthCheck
* @param array|StickySessionEntity[] $stickySessions
* @param array $dropletIds
* @param bool $httpsRedirect
*
* @throws HttpException
*
* @return LoadBalancerEntity
*/
public function create(
$name,
$region,
$forwardRules = null,
$algorithm = 'round_robin',
$healthCheck = [],
$stickySessions = [],
$dropletIds = [],
$httpsRedirect = false
) {
$data = [
'name' => $name,
'algorithm' => $algorithm,
'region' => $region,
'forwarding_rules' => $this->formatForwardRules($forwardRules),
'health_check' => $this->formatConfigurationOptions($healthCheck),
'sticky_sessions' => $this->formatConfigurationOptions($stickySessions),
'droplet_ids' => $dropletIds,
'redirect_http_to_https' => $httpsRedirect,
];

$loadBalancer = $this->adapter->post(sprintf('%s/load_balancers', $this->endpoint), $data);

$loadBalancer = json_decode($loadBalancer);

return new LoadBalancerEntity($loadBalancer->load_balancer);
}

/**
* @param string $id
* @param array|LoadBalancerEntity $loadBalancerSpec
*
* @throws HttpException
*
* @return LoadBalancerEntity
*/
public function update($id, $loadBalancerSpec)
{
$data = $this->formatConfigurationOptions($loadBalancerSpec);

$loadBalancer = $this->adapter->put(sprintf('%s/load_balancers/%s', $this->endpoint, $id), $data);

$loadBalancer = json_decode($loadBalancer);

return new LoadBalancerEntity($loadBalancer->load_balancer);
}

/**
* @param string $id
*
* @throws HttpException
*/
public function delete($id)
{
$this->adapter->delete(sprintf('%s/load_balancers/%s', $this->endpoint, $id));
}

/**
* @param array|AbstractEntity $forwardRules
*
* @return array
*/
private function formatForwardRules($forwardRules)
{
if (isset($forwardRules)) {
return array_map(function ($rule) {
return $this->formatConfigurationOptions($rule);
}, $forwardRules);
} else {
return [
(new ForwardRuleEntity())->setStandardHttpRules()->toArray(),
(new ForwardRuleEntity())->setStandardHttpsRules()->toArray(),
];
}
}

/**
* @param array|AbstractEntity $config
*
* @return array|AbstractEntity
*/
private function formatConfigurationOptions($config)
{
return $config instanceof AbstractEntity ? $config->toArray() : $config;
}
}

0 comments on commit 4464ceb

Please sign in to comment.