Zend_Cloud_Infrastructure_Instance::STATUS_RUNNING, 'SUSPENDED' => Zend_Cloud_Infrastructure_Instance::STATUS_STOPPED, 'BUILD' => Zend_Cloud_Infrastructure_Instance::STATUS_REBUILD, 'REBUILD' => Zend_Cloud_Infrastructure_Instance::STATUS_REBUILD, 'QUEUE_RESIZE' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, 'PREP_RESIZE' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, 'RESIZE' => Zend_Cloud_Infrastructure_Instance::STATUS_REBUILD, 'VERIFY_RESIZE' => Zend_Cloud_Infrastructure_Instance::STATUS_REBUILD, 'PASSWORD' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, 'RESCUE' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, 'REBOOT' => Zend_Cloud_Infrastructure_Instance::STATUS_REBOOTING, 'HARD_REBOOT' => Zend_Cloud_Infrastructure_Instance::STATUS_REBOOTING, 'SHARE_IP' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, 'SHARE_IP_NO_CONFIG' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, 'DELETE_IP' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING, 'UNKNOWN' => Zend_Cloud_Infrastructure_Instance::STATUS_PENDING ); /** * 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::RACKSPACE_USER])) { require_once 'Zend/Cloud/Infrastructure/Exception.php'; throw new Zend_Cloud_Infrastructure_Exception('Rackspace access user not specified!'); } if (!isset($options[self::RACKSPACE_KEY])) { require_once 'Zend/Cloud/Infrastructure/Exception.php'; throw new Zend_Cloud_Infrastructure_Exception('Rackspace access key not specified!'); } $this->accessUser = $options[self::RACKSPACE_USER]; $this->accessKey = $options[self::RACKSPACE_KEY]; if (isset($options[self::RACKSPACE_REGION])) { switch ($options[self::RACKSPACE_REGION]) { case self::RACKSPACE_ZONE_UK: $this->region= Zend_Service_Rackspace_Servers::UK_AUTH_URL; break; case self::RACKSPACE_ZONE_USA: $this->region = Zend_Service_Rackspace_Servers::US_AUTH_URL; break; default: require_once 'Zend/Cloud/Infrastructure/Exception.php'; throw new Zend_Cloud_Infrastructure_Exception('The region is not valid'); } } else { $this->region = Zend_Service_Rackspace_Servers::US_AUTH_URL; } try { $this->rackspace = new Zend_Service_Rackspace_Servers($this->accessUser,$this->accessKey, $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->rackspace->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]); } } /** * Convert the attributes of Rackspace server into attributes of Infrastructure * * @param array $attr * @return array|boolean */ protected function convertAttributes($attr) { $result = array(); if (!empty($attr) && is_array($attr)) { $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ID] = $attr['id']; $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_NAME] = $attr['name']; $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STATUS] = $this->mapStatus[$attr['status']]; $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_IMAGEID] = $attr['imageId']; if ($this->region==Zend_Service_Rackspace_Servers::US_AUTH_URL) { $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ZONE] = self::RACKSPACE_ZONE_USA; } else { $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_ZONE] = self::RACKSPACE_ZONE_UK; } $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_RAM] = $this->flavors[$attr['flavorId']]['ram']; $result[Zend_Cloud_Infrastructure_Instance::INSTANCE_STORAGE] = $this->flavors[$attr['flavorId']]['disk']; } return $result; } /** * Return a list of the available instancies * * @return InstanceList|boolean */ public function listInstances() { $this->adapterResult = $this->rackspace->listServers(true); if ($this->adapterResult===false) { return false; } $array= $this->adapterResult->toArray(); $result = array(); foreach ($array 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->rackspace->getServer($id); if ($this->adapterResult===false) { return false; } $array= $this->adapterResult->toArray(); return $this->mapStatus[$array['status']]; } /** * Return the public DNS name/Ip address of the instance * * @param string $id * @return string|boolean */ public function publicDnsInstance($id) { $this->adapterResult = $this->rackspace->getServerPublicIp($id); if (empty($this->adapterResult)) { return false; } return $this->adapterResult[0]; } /** * Reboot an instance * * @param string $id * @return boolean */ public function rebootInstance($id) { return $this->rackspace->rebootServer($id,true); } /** * Create a new instance * * @param string $name * @param array $options * @return Instance|boolean */ public function createInstance($name, $options) { if (empty($name)) { require_once 'Zend/Cloud/Infrastructure/Exception.php'; throw new Zend_Cloud_Infrastructure_Exception('You must specify the name of the instance'); } 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'); } // @todo create an generic abstract definition for an instance? $metadata= array(); if (isset($options['metadata'])) { $metadata= $options['metadata']; unset($options['metadata']); } $files= array(); if (isset($options['files'])) { $files= $options['files']; unset($options['files']); } $options['name']= $name; $this->adapterResult = $this->rackspace->createServer($options,$metadata,$files); if ($this->adapterResult===false) { return false; } return new Zend_Cloud_Infrastructure_Instance($this, $this->convertAttributes($this->adapterResult->toArray())); } /** * 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->rackspace->deleteServer($id); return $this->adapterResult; } /** * Return a list of all the available instance images * * @return ImageList|boolean */ public function imagesInstance() { $this->adapterResult = $this->rackspace->listImages(true); if ($this->adapterResult===false) { return false; } $images= $this->adapterResult->toArray(); $result= array(); foreach ($images as $image) { if (strtolower($image['status'])==='active') { if (strpos($image['name'],'Windows')!==false) { $platform = Zend_Cloud_Infrastructure_Image::IMAGE_WINDOWS; } else { $platform = Zend_Cloud_Infrastructure_Image::IMAGE_LINUX; } if (strpos($image['name'],'x64')!==false) { $arch = Zend_Cloud_Infrastructure_Image::ARCH_64BIT; } else { $arch = Zend_Cloud_Infrastructure_Image::ARCH_32BIT; } $result[]= array ( Zend_Cloud_Infrastructure_Image::IMAGE_ID => $image['id'], Zend_Cloud_Infrastructure_Image::IMAGE_NAME => $image['name'], Zend_Cloud_Infrastructure_Image::IMAGE_DESCRIPTION => $image['name'], Zend_Cloud_Infrastructure_Image::IMAGE_ARCHITECTURE => $arch, Zend_Cloud_Infrastructure_Image::IMAGE_PLATFORM => $platform, ); } } return new Zend_Cloud_Infrastructure_ImageList($result,$this->adapterResult); } /** * Return all the available zones * * @return array */ public function zonesInstance() { return array(self::RACKSPACE_ZONE_USA,self::RACKSPACE_ZONE_UK); } /** * Return the system information about the $metric of an instance * NOTE: it works only for Linux servers * * @param string $id * @param string $metric * @param null|array $options * @return array|boolean */ public function monitorInstance($id, $metric, $options = null) { if (!function_exists("ssh2_connect")) { require_once 'Zend/Cloud/Infrastructure/Exception.php'; throw new Zend_Cloud_Infrastructure_Exception('Monitor requires the PHP "SSH" extension (ext/ssh2)'); } if (empty($id)) { require_once 'Zend/Cloud/Infrastructure/Exception.php'; throw new Zend_Cloud_Infrastructure_Exception('You must specify the id of the instance to monitor'); } if (empty($metric)) { require_once 'Zend/Cloud/Infrastructure/Exception.php'; throw new Zend_Cloud_Infrastructure_Exception('You must specify the metric to monitor'); } 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'); } switch ($metric) { case Zend_Cloud_Infrastructure_Instance::MONITOR_CPU: $cmd= 'top -b -n '.self::MONITOR_CPU_SAMPLES.' | grep \'Cpu\''; break; case Zend_Cloud_Infrastructure_Instance::MONITOR_RAM: $cmd= 'top -b -n 1 | grep \'Mem\''; break; case Zend_Cloud_Infrastructure_Instance::MONITOR_DISK: $cmd= 'df --total | grep total'; break; } if (empty($cmd)) { require_once 'Zend/Cloud/Infrastructure/Exception.php'; throw new Zend_Cloud_Infrastructure_Exception('The metric specified is not supported by the adapter'); } $params= array( Zend_Cloud_Infrastructure_Instance::SSH_USERNAME => $options['username'], Zend_Cloud_Infrastructure_Instance::SSH_PASSWORD => $options['password'] ); $exec_time= time(); $result= $this->deployInstance($id,$params,$cmd); if (empty($result)) { return false; } $monitor = array(); $num = 0; $average = 0; $outputs= explode("\n",$result); foreach ($outputs as $output) { if (!empty($output)) { switch ($metric) { case Zend_Cloud_Infrastructure_Instance::MONITOR_CPU: if (preg_match('/(\d+\.\d)%us/', $output,$match)) { $usage = (float) $match[1]; } break; case Zend_Cloud_Infrastructure_Instance::MONITOR_RAM: if (preg_match('/(\d+)k total/', $output,$match)) { $total = (integer) $match[1]; } if (preg_match('/(\d+)k used/', $output,$match)) { $used = (integer) $match[1]; } if ($total>0) { $usage= (float) $used/$total; } break; case Zend_Cloud_Infrastructure_Instance::MONITOR_DISK: if (preg_match('/(\d+)%/', $output,$match)) { $usage = (float) $match[1]; } break; } $monitor['series'][] = array ( 'timestamp' => $exec_time, 'value' => number_format($usage,2).'%' ); $average += $usage; $exec_time+= 60; // seconds $num++; } } if ($num>0) { $monitor['average'] = number_format($average/$num,2).'%'; } return $monitor; } /** * Get the adapter * * @return Zend_Service_Rackspace_Servers */ public function getAdapter() { return $this->rackspace; } /** * Get last HTTP request * * @return string */ public function getLastHttpRequest() { return $this->rackspace->getHttpClient()->getLastRequest(); } /** * Get the last HTTP response * * @return Zend_Http_Response */ public function getLastHttpResponse() { return $this->rackspace->getHttpClient()->getLastResponse(); } }