| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- <?php
- /**
- * @category Zend
- * @package Zend_Cloud_Infrastructure
- * @subpackage Adapter
- * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- require_once 'Zend/Service/Amazon/Ec2/Instance.php';
- require_once 'Zend/Service/Amazon/Ec2/Image.php';
- require_once 'Zend/Service/Amazon/Ec2/Availabilityzones.php';
- require_once 'Zend/Service/Amazon/Ec2/CloudWatch.php';
- require_once 'Zend/Cloud/Infrastructure/Instance.php';
- require_once 'Zend/Cloud/Infrastructure/InstanceList.php';
- require_once 'Zend/Cloud/Infrastructure/Image.php';
- require_once 'Zend/Cloud/Infrastructure/ImageList.php';
- require_once 'Zend/Cloud/Infrastructure/Adapter/AbstractAdapter.php';
- /**
- * Amazon EC2 adapter for infrastructure service
- *
- * @package Zend_Cloud_Infrastructure
- * @subpackage Adapter
- * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- class Zend_Cloud_Infrastructure_Adapter_Ec2 extends Zend_Cloud_Infrastructure_Adapter_AbstractAdapter
- {
- /**
- * AWS constants
- */
- const AWS_ACCESS_KEY = 'aws_accesskey';
- const AWS_SECRET_KEY = 'aws_secretkey';
- const AWS_REGION = 'aws_region';
- const AWS_SECURITY_GROUP = 'securityGroup';
- /**
- * Ec2 Instance
- *
- * @var Ec2Instance
- */
- protected $ec2;
- /**
- * Ec2 Image
- *
- * @var Ec2Image
- */
- protected $ec2Image;
- /**
- * Ec2 Zone
- *
- * @var Ec2Zone
- */
- protected $ec2Zone;
- /**
- * Ec2 Monitor
- *
- * @var Ec2Monitor
- */
- protected $ec2Monitor;
- /**
- * AWS Access Key
- *
- * @var string
- */
- protected $accessKey;
- /**
- * AWS Access Secret
- *
- * @var string
- */
- protected $accessSecret;
- /**
- * Region zone
- *
- * @var string
- */
- protected $region;
- /**
- * Map array between EC2 and Infrastructure status
- *
- * @var array
- */
- protected $mapStatus = array (
- 'running' => Zend_Cloud_Infrastructure_Instance::STATUS_RUNNING,
- 'terminated' => Zend_Cloud_Infrastructure_Instance::STATUS_TERMINATED,
- 'pending' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING,
- 'shutting-down' => Zend_Cloud_Infrastructure_Instance::STATUS_SHUTTING_DOWN,
- 'stopping' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING,
- 'stopped' => Zend_Cloud_Infrastructure_Instance::STATUS_STOPPED,
- 'rebooting' => Zend_Cloud_Infrastructure_Instance::STATUS_REBOOTING,
- );
- /**
- * Map monitor metrics between Infrastructure and EC2
- *
- * @var array
- */
- protected $mapMetrics= array (
- Zend_Cloud_Infrastructure_Instance::MONITOR_CPU => 'CPUUtilization',
- Zend_Cloud_Infrastructure_Instance::MONITOR_DISK_READ => 'DiskReadBytes',
- Zend_Cloud_Infrastructure_Instance::MONITOR_DISK_WRITE => 'DiskWriteBytes',
- Zend_Cloud_Infrastructure_Instance::MONITOR_NETWORK_IN => 'NetworkIn',
- Zend_Cloud_Infrastructure_Instance::MONITOR_NETWORK_OUT => 'NetworkOut',
- );
- /**
- * Constructor
- *
- * @param array|Zend_Config $options
- * @return void
- */
- public function __construct($options = array())
- {
- if (is_object($options)) {
- if (method_exists($options, 'toArray')) {
- $options= $options->toArray();
- } elseif ($options instanceof Traversable) {
- $options = iterator_to_array($options);
- }
- }
-
- if (empty($options) || !is_array($options)) {
- require_once 'Zend/Cloud/Infrastructure/Exception.php';
- throw new Zend_Cloud_Infrastructure_Exception('Invalid options provided');
- }
-
- if (!isset($options[self::AWS_ACCESS_KEY])
- || !isset($options[self::AWS_SECRET_KEY])
- ) {
- require_once 'Zend/Cloud/Infrastructure/Exception.php';
- throw new Zend_Cloud_Infrastructure_Exception('AWS keys not specified!');
- }
- $this->accessKey = $options[self::AWS_ACCESS_KEY];
- $this->accessSecret = $options[self::AWS_SECRET_KEY];
- $this->region = '';
- if (isset($options[self::AWS_REGION])) {
- $this->region= $options[self::AWS_REGION];
- }
- try {
- $this->ec2 = new Zend_Service_Amazon_Ec2_Instance($options[self::AWS_ACCESS_KEY], $options[self::AWS_SECRET_KEY], $this->region);
- } catch (Exception $e) {
- require_once 'Zend/Cloud/Infrastructure/Exception.php';
- throw new Zend_Cloud_Infrastructure_Exception('Error on create: ' . $e->getMessage(), $e->getCode(), $e);
- }
- if (isset($options[self::HTTP_ADAPTER])) {
- $this->ec2->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]);
- }
- }
- /**
- * Convert the attributes of EC2 into attributes of Infrastructure
- *
- * @param array $attr
- * @return array|boolean
- */
- private function convertAttributes($attr)
- {
- $result = array();
- if (!empty($attr) && is_array($attr)) {
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ID] = $attr['instanceId'];
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STATUS] = $this->mapStatus[$attr['instanceState']['name']];
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_IMAGEID] = $attr['imageId'];
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ZONE] = $attr['availabilityZone'];
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_LAUNCHTIME] = $attr['launchTime'];
- switch ($attr['instanceType']) {
- case Zend_Service_Amazon_Ec2_Instance::MICRO:
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '1 virtual core';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '613MB';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '0GB';
- break;
- case Zend_Service_Amazon_Ec2_Instance::SMALL:
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '1 virtual core';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '1.7GB';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '160GB';
- break;
- case Zend_Service_Amazon_Ec2_Instance::LARGE:
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '2 virtual core';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '7.5GB';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '850GB';
- break;
- case Zend_Service_Amazon_Ec2_Instance::XLARGE:
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '4 virtual core';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '15GB';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '1690GB';
- break;
- case Zend_Service_Amazon_Ec2_Instance::HCPU_MEDIUM:
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '2 virtual core';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '1.7GB';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '350GB';
- break;
- case Zend_Service_Amazon_Ec2_Instance::HCPU_XLARGE:
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_CPU] = '8 virtual core';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = '7GB';
- $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = '1690GB';
- break;
- }
- }
- return $result;
- }
- /**
- * Return a list of the available instancies
- *
- * @return Zend_Cloud_Infrastructure_InstanceList
- */
- public function listInstances()
- {
- $this->adapterResult = $this->ec2->describe();
- $result = array();
- foreach ($this->adapterResult['instances'] as $instance) {
- $result[]= $this->convertAttributes($instance);
- }
- return new Zend_Cloud_Infrastructure_InstanceList($this, $result);
- }
- /**
- * Return the status of an instance
- *
- * @param string
- * @return string|boolean
- */
- public function statusInstance($id)
- {
- $this->adapterResult = $this->ec2->describe($id);
- if (empty($this->adapterResult['instances'])) {
- return false;
- }
- $result = $this->adapterResult['instances'][0];
- return $this->mapStatus[$result['instanceState']['name']];
- }
- /**
- * Return the public DNS name of the instance
- *
- * @param string $id
- * @return string|boolean
- */
- public function publicDnsInstance($id)
- {
- $this->adapterResult = $this->ec2->describe($id);
- if (empty($this->adapterResult['instances'])) {
- return false;
- }
- $result = $this->adapterResult['instances'][0];
- return $result['dnsName'];
- }
- /**
- * Reboot an instance
- *
- * @param string $id
- * @return boolean
- */
- public function rebootInstance($id)
- {
- $this->adapterResult= $this->ec2->reboot($id);
- return $this->adapterResult;
- }
- /**
- * Create a new instance
- *
- * @param string $name
- * @param array $options
- * @return Instance|boolean
- */
- public function createInstance($name, $options)
- {
- // @todo instance's name management?
- $this->adapterResult = $this->ec2->run($options);
- if (empty($this->adapterResult['instances'])) {
- return false;
- }
- $this->error= false;
- return new Zend_Cloud_Infrastructure_Instance($this, $this->convertAttributes($this->adapterResult['instances'][0]));
- }
- /**
- * Stop an instance
- *
- * @param string $id
- * @return boolean
- */
- public function stopInstance($id)
- {
- require_once 'Zend/Cloud/Infrastructure/Exception.php';
- throw new Zend_Cloud_Infrastructure_Exception('The stopInstance method is not implemented in the adapter');
- }
-
- /**
- * Start an instance
- *
- * @param string $id
- * @return boolean
- */
- public function startInstance($id)
- {
- require_once 'Zend/Cloud/Infrastructure/Exception.php';
- throw new Zend_Cloud_Infrastructure_Exception('The startInstance method is not implemented in the adapter');
- }
-
- /**
- * Destroy an instance
- *
- * @param string $id
- * @return boolean
- */
- public function destroyInstance($id)
- {
- $this->adapterResult = $this->ec2->terminate($id);
- return (!empty($this->adapterResult));
- }
-
- /**
- * Return a list of all the available instance images
- *
- * @return ImageList
- */
- public function imagesInstance()
- {
- if (!isset($this->ec2Image)) {
- $this->ec2Image = new Zend_Service_Amazon_Ec2_Image($this->accessKey, $this->accessSecret, $this->region);
- }
- $this->adapterResult = $this->ec2Image->describe();
-
- $images = array();
- foreach ($this->adapterResult as $result) {
- switch (strtolower($result['platform'])) {
- case 'windows' :
- $platform = Zend_Cloud_Infrastructure_Image::IMAGE_WINDOWS;
- break;
- default:
- $platform = Zend_Cloud_Infrastructure_Image::IMAGE_LINUX;
- break;
- }
- $images[]= array (
- Zend_Cloud_Infrastructure_Image::IMAGE_ID => $result['imageId'],
- Zend_Cloud_Infrastructure_Image::IMAGE_NAME => '',
- Zend_Cloud_Infrastructure_Image::IMAGE_DESCRIPTION => $result['imageLocation'],
- Zend_Cloud_Infrastructure_Image::IMAGE_OWNERID => $result['imageOwnerId'],
- Zend_Cloud_Infrastructure_Image::IMAGE_ARCHITECTURE => $result['architecture'],
- Zend_Cloud_Infrastructure_Image::IMAGE_PLATFORM => $platform,
- );
- }
- return new Zend_Cloud_Infrastructure_ImageList($images,$this->ec2Image);
- }
- /**
- * Return all the available zones
- *
- * @return array
- */
- public function zonesInstance()
- {
- if (!isset($this->ec2Zone)) {
- $this->ec2Zone = new Zend_Service_Amazon_Ec2_AvailabilityZones($this->accessKey,$this->accessSecret,$this->region);
- }
- $this->adapterResult = $this->ec2Zone->describe();
- $zones = array();
- foreach ($this->adapterResult as $zone) {
- if (strtolower($zone['zoneState']) === 'available') {
- $zones[] = array (
- Zend_Cloud_Infrastructure_Instance::INSTANCE_ZONE => $zone['zoneName'],
- );
- }
- }
- return $zones;
- }
- /**
- * Return the system information about the $metric of an instance
- *
- * @param string $id
- * @param string $metric
- * @param null|array $options
- * @return array
- */
- public function monitorInstance($id, $metric, $options = null)
- {
- if (empty($id) || empty($metric)) {
- return false;
- }
- if (!in_array($metric,$this->validMetrics)) {
- require_once 'Zend/Cloud/Infrastructure/Exception.php';
- throw new Zend_Cloud_Infrastructure_Exception(sprintf(
- 'The metric "%s" is not valid',
- $metric
- ));
- }
- if (!empty($options) && !is_array($options)) {
- require_once 'Zend/Cloud/Infrastructure/Exception.php';
- throw new Zend_Cloud_Infrastructure_Exception('The options must be an array');
- }
- if (!empty($options)
- && (empty($options[Zend_Cloud_Infrastructure_Instance::MONITOR_START_TIME])
- || empty($options[Zend_Cloud_Infrastructure_Instance::MONITOR_END_TIME]))
- ) {
- require_once 'Zend/Cloud/Infrastructure/Exception.php';
- throw new Zend_Cloud_Infrastructure_Exception(sprintf(
- 'The options array must contain: "%s" and "%s"',
- $options[Zend_Cloud_Infrastructure_Instance::MONITOR_START_TIME],
- $options[Zend_Cloud_Infrastructure_Instance::MONITOR_END_TIME]
- ));
- }
- if (!isset($this->ec2Monitor)) {
- $this->ec2Monitor = new Zend_Service_Amazon_Ec2_CloudWatch($this->accessKey, $this->accessSecret, $this->region);
- }
- $param = array(
- 'MeasureName' => $this->mapMetrics[$metric],
- 'Statistics' => array('Average'),
- 'Dimensions' => array('InstanceId' => $id),
- );
- if (!empty($options)) {
- $param['StartTime'] = $options[Zend_Cloud_Infrastructure_Instance::MONITOR_START_TIME];
- $param['EndTime'] = $options[Zend_Cloud_Infrastructure_Instance::MONITOR_END_TIME];
- }
- $this->adapterResult = $this->ec2Monitor->getMetricStatistics($param);
- $monitor = array();
- $num = 0;
- $average = 0;
- if (!empty($this->adapterResult['datapoints'])) {
- foreach ($this->adapterResult['datapoints'] as $result) {
- $monitor['series'][] = array (
- 'timestamp' => $result['Timestamp'],
- 'value' => $result['Average'],
- );
- $average += $result['Average'];
- $num++;
- }
- }
- if ($num > 0) {
- $monitor['average'] = $average / $num;
- }
- return $monitor;
- }
- /**
- * Get the adapter
- *
- * @return Zend_Service_Amazon_Ec2_Instance
- */
- public function getAdapter()
- {
- return $this->ec2;
- }
- /**
- * Get last HTTP request
- *
- * @return string
- */
- public function getLastHttpRequest()
- {
- return $this->ec2->getHttpClient()->getLastRequest();
- }
- /**
- * Get the last HTTP response
- *
- * @return Zend_Http_Response
- */
- public function getLastHttpResponse()
- {
- return $this->ec2->getHttpClient()->getLastResponse();
- }
- }
|