icingaweb2/library/vendor/Zend/Cloud/Infrastructure/Adapter/Ec2.php

480 lines
16 KiB
PHP

<?php
/**
* @category Zend
* @package Zend_Cloud_Infrastructure
* @subpackage Adapter
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Amazon EC2 adapter for infrastructure service
*
* @package Zend_Cloud_Infrastructure
* @subpackage Adapter
* @copyright Copyright (c) 2005-2014 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)) {
throw new Zend_Cloud_Infrastructure_Exception('Invalid options provided');
}
if (!isset($options[self::AWS_ACCESS_KEY])
|| !isset($options[self::AWS_SECRET_KEY])
) {
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) {
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)
{
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)
{
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)) {
throw new Zend_Cloud_Infrastructure_Exception(sprintf(
'The metric "%s" is not valid',
$metric
));
}
if (!empty($options) && !is_array($options)) {
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]))
) {
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();
}
}