File indexing completed on 2025-03-02 05:29:46
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Service_Amazon 0017 * @subpackage Ec2 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * @see Zend_Service_Amazon_Ec2_Abstract 0025 */ 0026 // require_once 'Zend/Service/Amazon/Ec2/Abstract.php'; 0027 0028 /** 0029 * An Amazon EC2 interface that allows yout to run, terminate, reboot and describe Amazon 0030 * Ec2 Instances. 0031 * 0032 * @category Zend 0033 * @package Zend_Service_Amazon 0034 * @subpackage Ec2 0035 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0036 * @license http://framework.zend.com/license/new-bsd New BSD License 0037 */ 0038 class Zend_Service_Amazon_Ec2_Instance extends Zend_Service_Amazon_Ec2_Abstract 0039 { 0040 /** 0041 * Constant for Micro Instance Type 0042 */ 0043 const MICRO = 't1.micro'; 0044 /** 0045 * Constant for Small Instance TYpe 0046 */ 0047 const SMALL = 'm1.small'; 0048 0049 /** 0050 * Constant for Large Instance TYpe 0051 */ 0052 const LARGE = 'm1.large'; 0053 0054 /** 0055 * Constant for X-Large Instance TYpe 0056 */ 0057 const XLARGE = 'm1.xlarge'; 0058 0059 /** 0060 * Constant for High CPU Medium Instance TYpe 0061 */ 0062 const HCPU_MEDIUM = 'c1.medium'; 0063 0064 /** 0065 * Constant for High CPU X-Large Instance TYpe 0066 */ 0067 const HCPU_XLARGE = 'c1.xlarge'; 0068 0069 0070 /** 0071 * Launches a specified number of Instances. 0072 * 0073 * If Amazon EC2 cannot launch the minimum number AMIs you request, no 0074 * instances launch. If there is insufficient capacity to launch the 0075 * maximum number of AMIs you request, Amazon EC2 launches as many 0076 * as possible to satisfy the requested maximum values. 0077 * 0078 * Every instance is launched in a security group. If you do not specify 0079 * a security group at launch, the instances start in your default security group. 0080 * For more information on creating security groups, see CreateSecurityGroup. 0081 * 0082 * An optional instance type can be specified. For information 0083 * about instance types, see Instance Types. 0084 * 0085 * You can provide an optional key pair ID for each image in the launch request 0086 * (for more information, see CreateKeyPair). All instances that are created 0087 * from images that use this key pair will have access to the associated public 0088 * key at boot. You can use this key to provide secure access to an instance of an 0089 * image on a per-instance basis. Amazon EC2 public images use this feature to 0090 * provide secure access without passwords. 0091 * 0092 * Launching public images without a key pair ID will leave them inaccessible. 0093 * 0094 * @param array $options An array that contins the options to start an instance. 0095 * Required Values: 0096 * imageId string ID of the AMI with which to launch instances. 0097 * Optional Values: 0098 * minCount integer Minimum number of instances to launch. 0099 * maxCount integer Maximum number of instances to launch. 0100 * keyName string Name of the key pair with which to launch instances. 0101 * securityGruop string|array Names of the security groups with which to associate the instances. 0102 * userData string The user data available to the launched instances. This should not be Base64 encoded. 0103 * instanceType constant Specifies the instance type. 0104 * placement string Specifies the availability zone in which to launch the instance(s). By default, Amazon EC2 selects an availability zone for you. 0105 * kernelId string The ID of the kernel with which to launch the instance. 0106 * ramdiskId string The ID of the RAM disk with which to launch the instance. 0107 * blockDeviceVirtualName string Specifies the virtual name to map to the corresponding device name. For example: instancestore0 0108 * blockDeviceName string Specifies the device to which you are mapping a virtual name. For example: sdb 0109 * monitor boolean Turn on CloudWatch Monitoring for an instance. 0110 * @return array 0111 */ 0112 public function run(array $options) 0113 { 0114 $_defaultOptions = array( 0115 'minCount' => 1, 0116 'maxCount' => 1, 0117 'instanceType' => Zend_Service_Amazon_Ec2_Instance::SMALL 0118 ); 0119 0120 // set / override the defualt optoins if they are not passed into the array; 0121 $options = array_merge($_defaultOptions, $options); 0122 0123 if(!isset($options['imageId'])) { 0124 // require_once 'Zend/Service/Amazon/Ec2/Exception.php'; 0125 throw new Zend_Service_Amazon_Ec2_Exception('No Image Id Provided'); 0126 } 0127 0128 0129 $params = array(); 0130 $params['Action'] = 'RunInstances'; 0131 $params['ImageId'] = $options['imageId']; 0132 $params['MinCount'] = $options['minCount']; 0133 $params['MaxCount'] = $options['maxCount']; 0134 0135 if(isset($options['keyName'])) { 0136 $params['KeyName'] = $options['keyName']; 0137 } 0138 0139 if(is_array($options['securityGroup']) && !empty($options['securityGroup'])) { 0140 foreach($options['securityGroup'] as $k=>$name) { 0141 $params['SecurityGroup.' . ($k+1)] = $name; 0142 } 0143 } elseif(isset($options['securityGroup'])) { 0144 $params['SecurityGroup.1'] = $options['securityGroup']; 0145 } 0146 0147 if(isset($options['userData'])) { 0148 $params['UserData'] = base64_encode($options['userData']); 0149 } 0150 0151 if(isset($options['instanceType'])) { 0152 $params['InstanceType'] = $options['instanceType']; 0153 } 0154 0155 if(isset($options['placement'])) { 0156 $params['Placement.AvailabilityZone'] = $options['placement']; 0157 } 0158 0159 if(isset($options['kernelId'])) { 0160 $params['KernelId'] = $options['kernelId']; 0161 } 0162 0163 if(isset($options['ramdiskId'])) { 0164 $params['RamdiskId'] = $options['ramdiskId']; 0165 } 0166 0167 if(isset($options['blockDeviceVirtualName']) && isset($options['blockDeviceName'])) { 0168 $params['BlockDeviceMapping.n.VirtualName'] = $options['blockDeviceVirtualName']; 0169 $params['BlockDeviceMapping.n.DeviceName'] = $options['blockDeviceName']; 0170 } 0171 0172 if(isset($options['monitor']) && $options['monitor'] === true) { 0173 $params['Monitoring.Enabled'] = true; 0174 } 0175 $response = $this->sendRequest($params); 0176 $xpath = $response->getXPath(); 0177 0178 $return = array(); 0179 0180 $return['reservationId'] = $xpath->evaluate('string(//ec2:reservationId/text())'); 0181 $return['ownerId'] = $xpath->evaluate('string(//ec2:ownerId/text())'); 0182 0183 $gs = $xpath->query('//ec2:groupSet/ec2:item'); 0184 foreach($gs as $gs_node) { 0185 $return['groupSet'][] = $xpath->evaluate('string(ec2:groupId/text())', $gs_node); 0186 unset($gs_node); 0187 } 0188 unset($gs); 0189 0190 $is = $xpath->query('//ec2:instancesSet/ec2:item'); 0191 foreach($is as $is_node) { 0192 $item = array(); 0193 0194 $item['instanceId'] = $xpath->evaluate('string(ec2:instanceId/text())', $is_node); 0195 $item['imageId'] = $xpath->evaluate('string(ec2:imageId/text())', $is_node); 0196 $item['instanceState']['code'] = $xpath->evaluate('string(ec2:instanceState/ec2:code/text())', $is_node); 0197 $item['instanceState']['name'] = $xpath->evaluate('string(ec2:instanceState/ec2:name/text())', $is_node); 0198 $item['privateDnsName'] = $xpath->evaluate('string(ec2:privateDnsName/text())', $is_node); 0199 $item['dnsName'] = $xpath->evaluate('string(ec2:dnsName/text())', $is_node); 0200 $item['keyName'] = $xpath->evaluate('string(ec2:keyName/text())', $is_node); 0201 $item['instanceType'] = $xpath->evaluate('string(ec2:instanceType/text())', $is_node); 0202 $item['amiLaunchIndex'] = $xpath->evaluate('string(ec2:amiLaunchIndex/text())', $is_node); 0203 $item['launchTime'] = $xpath->evaluate('string(ec2:launchTime/text())', $is_node); 0204 $item['availabilityZone'] = $xpath->evaluate('string(ec2:placement/ec2:availabilityZone/text())', $is_node); 0205 0206 $return['instances'][] = $item; 0207 unset($item); 0208 unset($is_node); 0209 } 0210 unset($is); 0211 0212 return $return; 0213 0214 } 0215 0216 /** 0217 * Returns information about instances that you own. 0218 * 0219 * If you specify one or more instance IDs, Amazon EC2 returns information 0220 * for those instances. If you do not specify instance IDs, Amazon EC2 0221 * returns information for all relevant instances. If you specify an invalid 0222 * instance ID, a fault is returned. If you specify an instance that you do 0223 * not own, it will not be included in the returned results. 0224 * 0225 * Recently terminated instances might appear in the returned results. 0226 * This interval is usually less than one hour. 0227 * 0228 * @param string|array $instaceId Set of instances IDs of which to get the status. 0229 * @param boolean Ture to ignore Terminated Instances. 0230 * @return array 0231 */ 0232 public function describe($instanceId = null, $ignoreTerminated = false) 0233 { 0234 $params = array(); 0235 $params['Action'] = 'DescribeInstances'; 0236 0237 if(is_array($instanceId) && !empty($instanceId)) { 0238 foreach($instanceId as $k=>$name) { 0239 $params['InstanceId.' . ($k+1)] = $name; 0240 } 0241 } elseif($instanceId) { 0242 $params['InstanceId.1'] = $instanceId; 0243 } 0244 0245 $response = $this->sendRequest($params); 0246 0247 $xpath = $response->getXPath(); 0248 0249 $nodes = $xpath->query('//ec2:reservationSet/ec2:item'); 0250 0251 $return = array(); 0252 $return['instances'] = array(); 0253 0254 foreach($nodes as $node) { 0255 if($xpath->evaluate('string(ec2:instancesSet/ec2:item/ec2:instanceState/ec2:code/text())', $node) == 48 && $ignoreTerminated) continue; 0256 $item = array(); 0257 0258 $item['reservationId'] = $xpath->evaluate('string(ec2:reservationId/text())', $node); 0259 $item['ownerId'] = $xpath->evaluate('string(ec2:ownerId/text())', $node); 0260 0261 $gs = $xpath->query('ec2:groupSet/ec2:item', $node); 0262 foreach($gs as $gs_node) { 0263 $item['groupSet'][] = $xpath->evaluate('string(ec2:groupId/text())', $gs_node); 0264 unset($gs_node); 0265 } 0266 unset($gs); 0267 0268 $is = $xpath->query('ec2:instancesSet/ec2:item', $node); 0269 0270 foreach($is as $is_node) { 0271 0272 $item['instanceId'] = $xpath->evaluate('string(ec2:instanceId/text())', $is_node); 0273 $item['imageId'] = $xpath->evaluate('string(ec2:imageId/text())', $is_node); 0274 $item['instanceState']['code'] = $xpath->evaluate('string(ec2:instanceState/ec2:code/text())', $is_node); 0275 $item['instanceState']['name'] = $xpath->evaluate('string(ec2:instanceState/ec2:name/text())', $is_node); 0276 $item['privateDnsName'] = $xpath->evaluate('string(ec2:privateDnsName/text())', $is_node); 0277 $item['dnsName'] = $xpath->evaluate('string(ec2:dnsName/text())', $is_node); 0278 $item['keyName'] = $xpath->evaluate('string(ec2:keyName/text())', $is_node); 0279 $item['productCode'] = $xpath->evaluate('string(ec2:productCodesSet/ec2:item/ec2:productCode/text())', $is_node); 0280 $item['instanceType'] = $xpath->evaluate('string(ec2:instanceType/text())', $is_node); 0281 $item['launchTime'] = $xpath->evaluate('string(ec2:launchTime/text())', $is_node); 0282 $item['availabilityZone'] = $xpath->evaluate('string(ec2:placement/ec2:availabilityZone/text())', $is_node); 0283 $item['kernelId'] = $xpath->evaluate('string(ec2:kernelId/text())', $is_node); 0284 $item['ramediskId'] = $xpath->evaluate('string(ec2:ramediskId/text())', $is_node); 0285 $item['amiLaunchIndex'] = $xpath->evaluate('string(ec2:amiLaunchIndex/text())', $is_node); 0286 $item['monitoringState'] = $xpath->evaluate('string(ec2:monitoring/ec2:state/text())', $is_node); 0287 0288 $return['instances'][] = $item; 0289 unset($is_node); 0290 } 0291 unset($item); 0292 unset($is); 0293 } 0294 0295 return $return; 0296 } 0297 0298 /** 0299 * Returns information about instances that you own that were started from 0300 * a specific imageId 0301 * 0302 * Recently terminated instances might appear in the returned results. 0303 * This interval is usually less than one hour. 0304 * 0305 * @param string $imageId The imageId used to start the Instance. 0306 * @param boolean Ture to ignore Terminated Instances. 0307 * @return array 0308 */ 0309 public function describeByImageId($imageId, $ignoreTerminated = false) 0310 { 0311 $arrInstances = $this->describe(null, $ignoreTerminated); 0312 0313 $return = array(); 0314 0315 foreach($arrInstances['instances'] as $instance) { 0316 if($instance['imageId'] !== $imageId) continue; 0317 $return[] = $instance; 0318 } 0319 0320 return $return; 0321 } 0322 0323 /** 0324 * Shuts down one or more instances. This operation is idempotent; if you terminate 0325 * an instance more than once, each call will succeed. 0326 * 0327 * Terminated instances will remain visible after termination (approximately one hour). 0328 * 0329 * @param string|array $instanceId One or more instance IDs returned. 0330 * @return array 0331 */ 0332 public function terminate($instanceId) 0333 { 0334 $params = array(); 0335 $params['Action'] = 'TerminateInstances'; 0336 0337 if(is_array($instanceId) && !empty($instanceId)) { 0338 foreach($instanceId as $k=>$name) { 0339 $params['InstanceId.' . ($k+1)] = $name; 0340 } 0341 } elseif($instanceId) { 0342 $params['InstanceId.1'] = $instanceId; 0343 } 0344 0345 $response = $this->sendRequest($params); 0346 $xpath = $response->getXPath(); 0347 0348 $nodes = $xpath->query('//ec2:instancesSet/ec2:item'); 0349 0350 $return = array(); 0351 foreach($nodes as $node) { 0352 $item = array(); 0353 0354 $item['instanceId'] = $xpath->evaluate('string(ec2:instanceId/text())', $node); 0355 $item['shutdownState']['code'] = $xpath->evaluate('string(ec2:shutdownState/ec2:code/text())', $node); 0356 $item['shutdownState']['name'] = $xpath->evaluate('string(ec2:shutdownState/ec2:name/text())', $node); 0357 $item['previousState']['code'] = $xpath->evaluate('string(ec2:previousState/ec2:code/text())', $node); 0358 $item['previousState']['name'] = $xpath->evaluate('string(ec2:previousState/ec2:name/text())', $node); 0359 0360 $return[] = $item; 0361 unset($item); 0362 } 0363 0364 return $return; 0365 } 0366 0367 /** 0368 * Requests a reboot of one or more instances. 0369 * 0370 * This operation is asynchronous; it only queues a request to reboot the specified instance(s). The operation 0371 * will succeed if the instances are valid and belong to the user. Requests to reboot terminated instances are ignored. 0372 * 0373 * @param string|array $instanceId One or more instance IDs. 0374 * @return boolean 0375 */ 0376 public function reboot($instanceId) 0377 { 0378 $params = array(); 0379 $params['Action'] = 'RebootInstances'; 0380 0381 if(is_array($instanceId) && !empty($instanceId)) { 0382 foreach($instanceId as $k=>$name) { 0383 $params['InstanceId.' . ($k+1)] = $name; 0384 } 0385 } elseif($instanceId) { 0386 $params['InstanceId.1'] = $instanceId; 0387 } 0388 0389 $response = $this->sendRequest($params); 0390 $xpath = $response->getXPath(); 0391 0392 $return = $xpath->evaluate('string(//ec2:return/text())'); 0393 0394 return ($return === "true"); 0395 } 0396 0397 /** 0398 * Retrieves console output for the specified instance. 0399 * 0400 * Instance console output is buffered and posted shortly after instance boot, reboot, and termination. 0401 * Amazon EC2 preserves the most recent 64 KB output which will be available for at least one hour after the most recent post. 0402 * 0403 * @param string $instanceId An instance ID 0404 * @return array 0405 */ 0406 public function consoleOutput($instanceId) 0407 { 0408 $params = array(); 0409 $params['Action'] = 'GetConsoleOutput'; 0410 $params['InstanceId'] = $instanceId; 0411 0412 $response = $this->sendRequest($params); 0413 $xpath = $response->getXPath(); 0414 0415 $return = array(); 0416 0417 $return['instanceId'] = $xpath->evaluate('string(//ec2:instanceId/text())'); 0418 $return['timestamp'] = $xpath->evaluate('string(//ec2:timestamp/text())'); 0419 $return['output'] = base64_decode($xpath->evaluate('string(//ec2:output/text())')); 0420 0421 return $return; 0422 } 0423 0424 /** 0425 * Returns true if the specified product code is attached to the specified instance. 0426 * The operation returns false if the product code is not attached to the instance. 0427 * 0428 * The confirmProduct operation can only be executed by the owner of the AMI. 0429 * This feature is useful when an AMI owner is providing support and wants to 0430 * verify whether a user's instance is eligible. 0431 * 0432 * @param string $productCode The product code to confirm. 0433 * @param string $instanceId The instance for which to confirm the product code. 0434 * @return array|boolean An array if the product code is attached to the instance, false if it is not. 0435 */ 0436 public function confirmProduct($productCode, $instanceId) 0437 { 0438 $params = array(); 0439 $params['Action'] = 'ConfirmProductInstance'; 0440 $params['ProductCode'] = $productCode; 0441 $params['InstanceId'] = $instanceId; 0442 0443 $response = $this->sendRequest($params); 0444 $xpath = $response->getXPath(); 0445 0446 $result = $xpath->evaluate('string(//ec2:result/text())'); 0447 0448 if($result === "true") { 0449 $return['result'] = true; 0450 $return['ownerId'] = $xpath->evaluate('string(//ec2:ownerId/text())'); 0451 0452 return $return; 0453 } 0454 0455 return false; 0456 } 0457 0458 /** 0459 * Turn on Amazon CloudWatch Monitoring for an instance or a list of instances 0460 * 0461 * @param array|string $instanceId The instance or list of instances you want to enable monitoring for 0462 * @return array 0463 */ 0464 public function monitor($instanceId) 0465 { 0466 $params = array(); 0467 $params['Action'] = 'MonitorInstances'; 0468 0469 if(is_array($instanceId) && !empty($instanceId)) { 0470 foreach($instanceId as $k=>$name) { 0471 $params['InstanceId.' . ($k+1)] = $name; 0472 } 0473 } elseif($instanceId) { 0474 $params['InstanceId.1'] = $instanceId; 0475 } 0476 0477 $response = $this->sendRequest($params); 0478 $xpath = $response->getXPath(); 0479 0480 0481 $items = $xpath->query('//ec2:instancesSet/ec2:item'); 0482 0483 $arrReturn = array(); 0484 foreach($items as $item) { 0485 $i = array(); 0486 $i['instanceid'] = $xpath->evaluate('string(//ec2:instanceId/text())', $item); 0487 $i['monitorstate'] = $xpath->evaluate('string(//ec2:monitoring/ec2:state/text())'); 0488 $arrReturn[] = $i; 0489 unset($i); 0490 } 0491 0492 return $arrReturn; 0493 } 0494 /** 0495 * Turn off Amazon CloudWatch Monitoring for an instance or a list of instances 0496 * 0497 * @param array|string $instanceId The instance or list of instances you want to disable monitoring for 0498 * @return array 0499 */ 0500 public function unmonitor($instanceId) 0501 { 0502 $params = array(); 0503 $params['Action'] = 'UnmonitorInstances'; 0504 0505 if(is_array($instanceId) && !empty($instanceId)) { 0506 foreach($instanceId as $k=>$name) { 0507 $params['InstanceId.' . ($k+1)] = $name; 0508 } 0509 } elseif($instanceId) { 0510 $params['InstanceId.1'] = $instanceId; 0511 } 0512 0513 $response = $this->sendRequest($params); 0514 $xpath = $response->getXPath(); 0515 0516 0517 $items = $xpath->query('//ec2:instancesSet/ec2:item'); 0518 0519 $arrReturn = array(); 0520 foreach($items as $item) { 0521 $i = array(); 0522 $i['instanceid'] = $xpath->evaluate('string(//ec2:instanceId/text())', $item); 0523 $i['monitorstate'] = $xpath->evaluate('string(//ec2:monitoring/ec2:state/text())'); 0524 $arrReturn[] = $i; 0525 unset($i); 0526 } 0527 0528 return $arrReturn; 0529 } 0530 0531 } 0532