Overview
  • Namespace
  • Class

Namespaces

  • OpenCloud
    • Autoscale
      • Resource
    • CloudMonitoring
      • Collection
      • Exception
      • Resource
    • Common
      • Collection
      • Constants
      • Exceptions
      • Http
        • Message
      • Log
      • Resource
      • Service
    • Compute
      • Constants
      • Exception
      • Resource
    • Database
      • Resource
    • DNS
      • Collection
      • Resource
    • Identity
      • Constants
      • Resource
    • Image
      • Enum
      • Resource
        • JsonPatch
        • Schema
    • LoadBalancer
      • Collection
      • Enum
      • Resource
    • Networking
      • Resource
    • ObjectStore
      • Constants
      • Exception
      • Resource
      • Upload
    • Orchestration
      • Resource
    • Queues
      • Collection
      • Exception
      • Resource
    • Volume
      • Resource

Classes

  • OpenCloud\Volume\Resource\Snapshot
  • OpenCloud\Volume\Resource\Volume
  • OpenCloud\Volume\Resource\VolumeType
  1 <?php
  2 /**
  3  * Copyright 2012-2014 Rackspace US, Inc.
  4  *
  5  * Licensed under the Apache License, Version 2.0 (the "License");
  6  * you may not use this file except in compliance with the License.
  7  * You may obtain a copy of the License at
  8  *
  9  * http://www.apache.org/licenses/LICENSE-2.0
 10  *
 11  * Unless required by applicable law or agreed to in writing, software
 12  * distributed under the License is distributed on an "AS IS" BASIS,
 13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  * See the License for the specific language governing permissions and
 15  * limitations under the License.
 16  */
 17 
 18 namespace OpenCloud\LoadBalancer\Resource;
 19 
 20 use OpenCloud\Common\Exceptions;
 21 use OpenCloud\Common\Log\Logger;
 22 use OpenCloud\Common\Resource\PersistentResource;
 23 use OpenCloud\DNS\Resource\HasPtrRecordsInterface;
 24 use OpenCloud\LoadBalancer\Enum\NodeCondition;
 25 use OpenCloud\LoadBalancer\Enum\IpType;
 26 use OpenCloud\LoadBalancer\Enum\NodeType;
 27 
 28 /**
 29  * A load balancer is a logical device which belongs to a cloud account. It is
 30  * used to distribute workloads between multiple back-end systems or services,
 31  * based on the criteria defined as part of its configuration.
 32  */
 33 class LoadBalancer extends PersistentResource implements HasPtrRecordsInterface
 34 {
 35     public $id;
 36 
 37     /**
 38      * Name of the load balancer to create. The name must be 128 characters or
 39      * less in length, and all UTF-8 characters are valid.
 40      *
 41      * @var string
 42      */
 43     public $name;
 44 
 45     /**
 46      * Port of the service which is being load balanced.
 47      *
 48      * @var string
 49      */
 50     public $port;
 51 
 52     /**
 53      * Protocol of the service which is being load balanced.
 54      *
 55      * @var string
 56      */
 57     public $protocol;
 58 
 59     /**
 60      * Type of virtual IP to add along with the creation of a load balancer.
 61      *
 62      * @var array|Collection
 63      */
 64     public $virtualIps = array();
 65 
 66     /**
 67      * Nodes to be added to the load balancer.
 68      *
 69      * @var array|Collection
 70      */
 71     public $nodes = array();
 72 
 73     /**
 74      * The access list management feature allows fine-grained network access
 75      * controls to be applied to the load balancer's virtual IP address.
 76      *
 77      * @var Collection
 78      */
 79     public $accessList;
 80 
 81     /**
 82      * Algorithm that defines how traffic should be directed between back-end nodes.
 83      *
 84      * @var Algorithm
 85      */
 86     public $algorithm;
 87 
 88 
 89     /**
 90      * Enables or disables HTTP to HTTPS redirection for the load balancer.
 91      *
 92      * @var bool
 93      */
 94     public $httpsRedirect;
 95 
 96     /**
 97      * Current connection logging configuration.
 98      *
 99      * @var ConnectionLogging
100      */
101     public $connectionLogging;
102 
103     /**
104      * Specifies limits on the number of connections per IP address to help
105      * mitigate malicious or abusive traffic to your applications.
106      *
107      * @var ConnectionThrottle
108      */
109     public $connectionThrottle;
110 
111     /**
112      * The type of health monitor check to perform to ensure that the service is
113      * performing properly.
114      *
115      * @var HealthMonitor
116      */
117     public $healthMonitor;
118 
119     /**
120      * Forces multiple requests, of the same protocol, from clients to be
121      * directed to the same node.
122      *
123      * @var SessionPersistance
124      */
125     public $sessionPersistence;
126 
127     /**
128      * Information (metadata) that can be associated with each load balancer for
129      * the client's personal use.
130      *
131      * @var array|Metadata
132      */
133     public $metadata = array();
134 
135     /**
136      * The timeout value for the load balancer and communications with its nodes.
137      * Defaults to 30 seconds with a maximum of 120 seconds.
138      *
139      * @var int
140      */
141     public $timeout;
142 
143     public $created;
144     public $updated;
145     public $status;
146     public $nodeCount;
147     public $sourceAddresses;
148     public $cluster;
149 
150     protected static $json_name = 'loadBalancer';
151     protected static $url_resource = 'loadbalancers';
152 
153     protected $associatedResources = array(
154         'certificateMapping' => 'CertificateMapping',
155         'node'               => 'Node',
156         'virtualIp'          => 'VirtualIp',
157         'connectionLogging'  => 'ConnectionLogging',
158         'healthMonitor'      => 'HealthMonitor',
159         'sessionPersistance' => 'SessionPersistance'
160     );
161 
162     protected $associatedCollections = array(
163         'certificateMappings' => 'CertificateMapping',
164         'nodes'               => 'Node',
165         'virtualIps'          => 'VirtualIp',
166         'accessList'          => 'Access'
167     );
168 
169     protected $createKeys = array(
170         'name',
171         'port',
172         'protocol',
173         'virtualIps',
174         'nodes',
175         'accessList',
176         'algorithm',
177         'connectionLogging',
178         'connectionThrottle',
179         'healthMonitor',
180         'sessionPersistence',
181         'httpsRedirect'
182     );
183 
184     /**
185      * This method creates a Node object and adds it to a list of Nodes
186      * to be added to the LoadBalancer. This method will not add the nodes
187      * directly to the load balancer itself; it stores them in an array and
188      * the nodes are added later, in one of two ways:
189      *
190      * * for a new load balancer, the nodes are added as part of the create() method call
191      * * for an existing load balancer, you must call the addNodes() method
192      *
193      * @param string  $address   the IP address of the node
194      * @param integer $port      the port # of the node
195      * @param boolean $condition the initial condition of the node
196      * @param string  $type      either PRIMARY or SECONDARY
197      * @param integer $weight    the node weight (for round-robin)
198      *
199      * @throws \InvalidArgumentException
200      * @return void
201      */
202     public function addNode(
203         $address,
204         $port,
205         $condition = NodeCondition::ENABLED,
206         $type = null,
207         $weight = null
208     ) {
209         $allowedConditions = array(
210             NodeCondition::ENABLED,
211             NodeCondition::DISABLED,
212             NodeCondition::DRAINING
213         );
214 
215         if (!in_array($condition, $allowedConditions)) {
216             throw new \InvalidArgumentException(sprintf(
217                 "Invalid condition. It must one of the following: %s",
218                 implode(', ', $allowedConditions)
219             ));
220         }
221 
222         $allowedTypes = array(NodeType::PRIMARY, NodeType::SECONDARY);
223         if ($type && !in_array($type, $allowedTypes)) {
224             throw new \InvalidArgumentException(sprintf(
225                 "Invalid type. It must one of the following: %s",
226                 implode(', ', $allowedTypes)
227             ));
228         }
229 
230         if ($weight && !is_numeric($weight)) {
231             throw new \InvalidArgumentException('Invalid weight. You must supply a numeric type');
232         }
233 
234         // queue it
235         $this->nodes[] = $this->node(array(
236             'address'   => $address,
237             'port'      => $port,
238             'condition' => $condition,
239             'type'      => $type,
240             'weight'    => $weight
241         ));
242     }
243 
244     /**
245      * Creates currently added nodes by sending them to the API
246      *
247      * @return array of {@see \Guzzle\Http\Message\Response} objects
248      * @throws \OpenCloud\Common\Exceptions\MissingValueError
249      */
250     public function addNodes()
251     {
252         if (empty($this->nodes)) {
253             throw new Exceptions\MissingValueError(
254                 'Cannot add nodes; no nodes are defined'
255             );
256         }
257 
258         $requests = array();
259 
260         foreach ($this->nodes as $node) {
261             // Only add the node if it is new
262             if (null === $node->getId()) {
263                 $json = json_encode($node->createJson());
264                 $requests[] = $this->getClient()->post($node->getUrl(), self::getJsonHeader(), $json);
265             }
266         }
267 
268         return $this->getClient()->send($requests);
269     }
270 
271     /**
272      * Remove a node from this load-balancer
273      *
274      * @param int $id id of the node
275      * @return \Guzzle\Http\Message\Response
276      */
277     public function removeNode($nodeId)
278     {
279         return $this->node($nodeId)->delete();
280     }
281 
282     /**
283      * Adds a virtual IP to the load balancer. You can use the strings 'PUBLIC'
284      * or 'SERVICENET' to indicate the public or internal networks, or you can
285      * pass the `Id` of an existing IP address.
286      *
287      * @param string  $id        either 'public' or 'servicenet' or an ID of an
288      *                           existing IP address
289      * @param integer $ipVersion either null, 4, or 6 (both, IPv4, or IPv6)
290      * @return void
291      */
292     public function addVirtualIp($type = IpType::PUBLIC_TYPE, $ipVersion = null)
293     {
294         $object = new \stdClass();
295 
296         switch (strtoupper($type)) {
297             case IpType::PUBLIC_TYPE:
298             case IpType::SERVICENET_TYPE:
299                 $object->type = strtoupper($type);
300                 break;
301             default:
302                 $object->id = $type;
303                 break;
304         }
305 
306         if ($ipVersion) {
307             switch ($ipVersion) {
308                 case 4:
309                     $object->ipVersion = IpType::IPv4;
310                     break;
311                 case 6:
312                     $object->ipVersion = IpType::IPv6;
313                     break;
314                 default:
315                     throw new Exceptions\DomainError(sprintf(
316                         'Value [%s] for ipVersion is not valid',
317                         $ipVersion
318                     ));
319             }
320         }
321 
322         /**
323          * If the load balancer exists, we want to add it immediately.
324          * If not, we add it to the virtualIps list and add it when the load
325          * balancer is created.
326          */
327         if ($this->Id()) {
328             $virtualIp = $this->virtualIp();
329             $virtualIp->type = $type;
330             $virtualIp->ipVersion = $object->ipVersion;
331             return $virtualIp->create();
332         } else {
333             // queue it
334             $this->virtualIps[] = $object;
335         }
336 
337         return true;
338     }
339 
340     /**
341      * Returns a Node
342      *
343      * @return \OpenCloud\LoadBalancer\Resource\Node
344      */
345     public function node($id = null)
346     {
347         return $this->getService()->resource('Node', $id, $this);
348     }
349 
350     /**
351      * returns a Collection of Nodes
352      *
353      * @return \OpenCloud\Common\Collection\PaginatedIterator
354      */
355     public function nodeList()
356     {
357         return $this->getService()->resourceList('Node', null, $this);
358     }
359 
360     /**
361      * Returns a NodeEvent object
362      *
363      * @return \OpenCloud\LoadBalancer\Resource\NodeEvent
364      */
365     public function nodeEvent()
366     {
367         return $this->getService()->resource('NodeEvent', null, $this);
368     }
369 
370     /**
371      * Returns a Collection of NodeEvents
372      *
373      * @return \OpenCloud\Common\Collection\PaginatedIterator
374      */
375     public function nodeEventList()
376     {
377         return $this->getService()->resourceList('NodeEvent', null, $this);
378     }
379 
380     /**
381      * Returns a single Virtual IP (not called publicly)
382      *
383      * @return \OpenCloud\LoadBalancer\Resource\VirtualIp
384      */
385     public function virtualIp($data = null)
386     {
387         return $this->getService()->resource('VirtualIp', $data, $this);
388     }
389 
390     /**
391      * @return \OpenCloud\Common\Collection\PaginatedIterator
392      */
393     public function virtualIpList()
394     {
395         return $this->getService()->resourceList('VirtualIp', null, $this);
396     }
397 
398     /**
399      * Returns a Certificate Mapping.
400      *
401      * @param int|array $id (Optional) Either a particular Certificate mapping ID, or an array of data about the
402      *                      mapping. An array can include these keys: hostName, privateKey, certificate,
403      *                      intermediateCertificate.
404      * @return \OpenCloud\LoadBalancer\Resource\CertificateMapping
405      */
406     public function certificateMapping($id = null)
407     {
408         return $this->getService()->resource('CertificateMapping', $id, $this);
409     }
410 
411     /**
412      * Returns a Collection of Certificate Mappings.
413      *
414      * @return \OpenCloud\Common\Collection\PaginatedIterator
415      */
416     public function certificateMappingList()
417     {
418         return $this->getService()->resourceList('CertificateMapping', null, $this);
419     }
420 
421     /**
422      * Creates a certificate mapping.
423      *
424      * @throws \OpenCloud\Common\Exceptions\MissingValueError
425      *
426      * @param string $hostName                The domain name for the certificate.
427      * @param string $privateKey              The private key for the certificate
428      * @param string $certificate             The certificate itself.
429      * @param string $intermediateCertificate The intermediate certificate chain.
430      * @return array An array of \Guzzle\Http\Message\Response objects.
431      */
432     public function addCertificateMapping(
433         $hostName,
434         $privateKey,
435         $certificate,
436         $intermediateCertificate = null
437     ) {
438         $certificateMapping = $this->certificateMapping(
439             array(
440                 'hostName'                => $hostName,
441                 'privateKey'              => $privateKey,
442                 'certificate'             => $certificate,
443                 'intermediateCertificate' => $intermediateCertificate
444             )
445         );
446         $json = json_encode($certificateMapping->createJson());
447         $request = $this->getClient()->post($certificateMapping->getUrl(), self::getJsonHeader(), $json);
448 
449         return $this->getClient()->send($request);
450     }
451 
452     /**
453      * Updates a certificate mapping.
454      *
455      * @param int    $id                      ID of the certificate mapping.
456      * @param string $hostName                (Optional) The domain name of the certificate.
457      * @param string $privateKey              (Optional) The private key for the certificate.
458      * @param string $certificate             The certificate itself.
459      * @param string $intermediateCertificate The intermediate certificate chain.
460      * @return array An array of \Guzzle\Http\Message\Response objects.
461      */
462     public function updateCertificateMapping(
463         $id,
464         $hostName = null,
465         $privateKey = null,
466         $certificate = null,
467         $intermediateCertificate = null
468     ) {
469         $certificateMapping = $this->certificateMapping($id);
470         return $certificateMapping->update(
471             array(
472                 'hostName'                => $hostName,
473                 'privateKey'              => $privateKey,
474                 'certificate'             => $certificate,
475                 'intermediateCertificate' => $intermediateCertificate
476             )
477         );
478     }
479 
480     /**
481      * Remove a certificate mapping.
482      *
483      * @param int $id ID of the certificate mapping.
484      * @return \Guzzle\Http\Message\Response
485      */
486     public function removeCertificateMapping($id)
487     {
488         return $this->certificateMapping($id)->delete();
489     }
490 
491     /**
492      * Return the session persistence resource
493      *
494      * @return \OpenCloud\LoadBalancer\Resource\SessionPersistence
495      */
496     public function sessionPersistence()
497     {
498         return $this->getService()->resource('SessionPersistence', null, $this);
499     }
500 
501     /**
502      * Returns the load balancer's error page object
503      *
504      * @return \OpenCloud\LoadBalancer\Resource\ErrorPage
505      */
506     public function errorPage()
507     {
508         return $this->getService()->resource('ErrorPage', null, $this);
509     }
510 
511     /**
512      * Returns the load balancer's health monitor object
513      *
514      * @return \OpenCloud\LoadBalancer\Resource\HealthMonitor
515      */
516     public function healthMonitor()
517     {
518         return $this->getService()->resource('HealthMonitor', null, $this);
519     }
520 
521     /**
522      * Returns statistics on the load balancer operation
523      *
524      * @return \OpenCloud\LoadBalancer\Resource\Stats
525      */
526     public function stats()
527     {
528         return $this->getService()->resource('Stats', null, $this);
529     }
530 
531     /**
532      * @return \OpenCloud\Common\Collection\PaginatedIterator
533      */
534     public function usage()
535     {
536         return $this->getService()->resourceList('UsageRecord', null, $this);
537     }
538 
539     /**
540      * Return an access resource
541      *
542      * @return \OpenCloud\LoadBalancer\Resource\Access
543      */
544     public function access($data = null)
545     {
546         return $this->getService()->resource('Access', $data, $this);
547     }
548 
549     /**
550      * Creates an access list. You must provide an array of \stdClass objects,
551      * each of which contains `type' and `address' properties. Valid types for
552      * the former are: "DENY" or "ALLOW". The address must be a valid IP
553      * address, either v4 or v6.
554      *
555      * @param stdClass[] $list
556      *
557      * @return \Guzzle\Http\Message\Response
558      */
559     public function createAccessList(array $list)
560     {
561         $url = $this->getUrl();
562         $url->addPath('accesslist');
563 
564         $json = json_encode($list);
565         $this->checkJsonError();
566 
567         return $this->getClient()->post($url, self::getJsonHeader(), $json)->send();
568     }
569 
570     /**
571      * @return \OpenCloud\Common\Collection\PaginatedIterator
572      */
573     public function accessList()
574     {
575         return $this->getService()->resourceList('Access', null, $this);
576     }
577 
578     /**
579      * Return a connection throttle resource
580      *
581      * @return \OpenCloud\LoadBalancer\Resource\ConnectionThrottle
582      */
583     public function connectionThrottle()
584     {
585         return $this->getService()->resource('ConnectionThrottle', null, $this);
586     }
587 
588     /**
589      * Find out whether connection logging is enabled for this load balancer
590      *
591      * @return bool Returns TRUE if enabled, FALSE if not
592      */
593     public function hasConnectionLogging()
594     {
595         $url = clone $this->getUrl();
596         $url->addPath('connectionlogging');
597 
598         $response = $this->getClient()->get($url)->send()->json();
599 
600         return isset($response['connectionLogging']['enabled'])
601             && $response['connectionLogging']['enabled'] === true;
602     }
603 
604     /**
605      * Set the connection logging setting for this load balancer
606      *
607      * @param $bool  Set to TRUE to enable, FALSE to disable
608      * @return \Guzzle\Http\Message\Response
609      */
610     public function enableConnectionLogging($bool)
611     {
612         $url = clone $this->getUrl();
613         $url->addPath('connectionlogging');
614 
615         $body = array('connectionLogging' => (bool) $bool);
616 
617         return $this->getClient()->put($url, self::getJsonHeader(), $body)->send();
618     }
619 
620     /**
621      * @deprecated
622      */
623     public function connectionLogging()
624     {
625         $this->getLogger()->warning(Logger::deprecated(__METHOD__, 'hasConnectionLogging or enableConnectionLogging'));
626     }
627 
628     /**
629      * Find out whether content caching is enabled for this load balancer
630      *
631      * @return bool Returns TRUE if enabled, FALSE if not
632      */
633     public function hasContentCaching()
634     {
635         $url = clone $this->getUrl();
636         $url->addPath('contentcaching');
637 
638         $response = $this->getClient()->get($url)->send()->json();
639 
640         return isset($response['contentCaching']['enabled'])
641             && $response['contentCaching']['enabled'] === true;
642     }
643 
644     /**
645      * Set the content caching setting for this load balancer
646      *
647      * @param $bool  Set to TRUE to enable, FALSE to disable
648      * @return \Guzzle\Http\Message\Response
649      */
650     public function enableContentCaching($bool)
651     {
652         $url = clone $this->getUrl();
653         $url->addPath('contentcaching');
654 
655         $body = array('contentCaching' => array('enabled' => (bool) $bool));
656         $body = json_encode($body);
657         $this->checkJsonError();
658 
659         return $this->getClient()->put($url, self::getJsonHeader(), $body)->send();
660     }
661 
662     /**
663      * @deprecated
664      */
665     public function contentCaching()
666     {
667         $this->getLogger()->warning(sprintf(
668             'The %s method is deprecated, please use %s instead', __METHOD__, 'hasContentCaching or setContentCaching'));
669     }
670 
671     /**
672      * Return a SSL Termination resource
673      *
674      * @return \OpenCloud\LoadBalancer\Resource\SSLTermination
675      */
676     public function SSLTermination()
677     {
678         return $this->getService()->resource('SSLTermination', null, $this);
679     }
680 
681     /**
682      * Return a metadata item
683      *
684      * @return \OpenCloud\LoadBalancer\Resource\Metadata
685      */
686     public function metadata($data = null)
687     {
688         return $this->getService()->resource('Metadata', $data, $this);
689     }
690 
691     /**
692      * Return a collection of metadata items
693      *
694      * @return \OpenCloud\Common\Collection\PaginatedIterator
695      */
696     public function metadataList()
697     {
698         return $this->getService()->resourceList('Metadata', null, $this);
699     }
700 
701     protected function createJson()
702     {
703         $element = (object) array();
704 
705         foreach ($this->createKeys as $key) {
706             if ($key == 'nodes') {
707                 foreach ($this->nodes as $node) {
708                     $nodeObject = (object) array();
709                     foreach ($node->createKeys as $key) {
710                         if (!empty($node->$key)) {
711                             $nodeObject->$key = $node->$key;
712                         }
713                     }
714                     $element->nodes[] = (object) $nodeObject;
715                 }
716             } elseif ($key == 'virtualIps') {
717                 foreach ($this->virtualIps as $virtualIp) {
718                     $element->virtualIps[] = $virtualIp;
719                 }
720             } elseif (isset($this->$key)) {
721                 $element->$key = $this->$key;
722             }
723         }
724 
725         $object = (object) array($this->jsonName() => $element);
726 
727         return $object;
728     }
729 
730     protected function updateJson($params = array())
731     {
732         $updatableFields = array('name', 'algorithm', 'protocol', 'port', 'timeout', 'halfClosed', 'httpsRedirect');
733 
734         $fields = array_keys($params);
735         foreach ($fields as $field) {
736             if (!in_array($field, $updatableFields)) {
737                 throw new Exceptions\InvalidArgumentError("You cannot update $field.");
738             }
739         }
740 
741         $object = new \stdClass();
742         $object->loadBalancer = new \stdClass();
743         foreach ($params as $name => $value) {
744             $object->loadBalancer->$name = $this->$name;
745         }
746 
747         return $object;
748     }
749 }
750 
API documentation generated by ApiGen