web/lib/Zend/Service/Amazon/Ec2/Instance.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Service_Amazon
       
    17  * @subpackage Ec2
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: Instance.php 22046 2010-04-28 22:12:32Z shahar $
       
    21  */
       
    22 
       
    23 /**
       
    24  * @see Zend_Service_Amazon_Ec2_Abstract
       
    25  */
       
    26 require_once 'Zend/Service/Amazon/Ec2/Abstract.php';
       
    27 
       
    28 /**
       
    29  * An Amazon EC2 interface that allows yout to run, terminate, reboot and describe Amazon
       
    30  * Ec2 Instances.
       
    31  *
       
    32  * @category   Zend
       
    33  * @package    Zend_Service_Amazon
       
    34  * @subpackage Ec2
       
    35  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    36  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    37  */
       
    38 class Zend_Service_Amazon_Ec2_Instance extends Zend_Service_Amazon_Ec2_Abstract
       
    39 {
       
    40     /**
       
    41      * Constant for Small Instance TYpe
       
    42      */
       
    43     const SMALL = 'm1.small';
       
    44 
       
    45     /**
       
    46      * Constant for Large Instance TYpe
       
    47      */
       
    48     const LARGE = 'm1.large';
       
    49 
       
    50     /**
       
    51      * Constant for X-Large Instance TYpe
       
    52      */
       
    53     const XLARGE = 'm1.xlarge';
       
    54 
       
    55     /**
       
    56      * Constant for High CPU Medium Instance TYpe
       
    57      */
       
    58     const HCPU_MEDIUM = 'c1.medium';
       
    59 
       
    60     /**
       
    61      * Constant for High CPU X-Large Instance TYpe
       
    62      */
       
    63     const HCPU_XLARGE = 'c1.xlarge';
       
    64 
       
    65 
       
    66     /**
       
    67      * Launches a specified number of Instances.
       
    68      *
       
    69      * If Amazon EC2 cannot launch the minimum number AMIs you request, no
       
    70      * instances launch. If there is insufficient capacity to launch the
       
    71      * maximum number of AMIs you request, Amazon EC2 launches as many
       
    72      * as possible to satisfy the requested maximum values.
       
    73      *
       
    74      * Every instance is launched in a security group. If you do not specify
       
    75      * a security group at launch, the instances start in your default security group.
       
    76      * For more information on creating security groups, see CreateSecurityGroup.
       
    77      *
       
    78      * An optional instance type can be specified. For information
       
    79      * about instance types, see Instance Types.
       
    80      *
       
    81      * You can provide an optional key pair ID for each image in the launch request
       
    82      * (for more information, see CreateKeyPair). All instances that are created
       
    83      * from images that use this key pair will have access to the associated public
       
    84      * key at boot. You can use this key to provide secure access to an instance of an
       
    85      * image on a per-instance basis. Amazon EC2 public images use this feature to
       
    86      * provide secure access without passwords.
       
    87      *
       
    88      * Launching public images without a key pair ID will leave them inaccessible.
       
    89      *
       
    90      * @param array $options                        An array that contins the options to start an instance.
       
    91      *                                              Required Values:
       
    92      *                                                imageId string        ID of the AMI with which to launch instances.
       
    93      *                                              Optional Values:
       
    94      *                                                minCount integer      Minimum number of instances to launch.
       
    95      *                                                maxCount integer      Maximum number of instances to launch.
       
    96      *                                                keyName string        Name of the key pair with which to launch instances.
       
    97      *                                                securityGruop string|array Names of the security groups with which to associate the instances.
       
    98      *                                                userData string       The user data available to the launched instances. This should not be Base64 encoded.
       
    99      *                                                instanceType constant Specifies the instance type.
       
   100      *                                                placement string      Specifies the availability zone in which to launch the instance(s). By default, Amazon EC2 selects an availability zone for you.
       
   101      *                                                kernelId string       The ID of the kernel with which to launch the instance.
       
   102      *                                                ramdiskId string      The ID of the RAM disk with which to launch the instance.
       
   103      *                                                blockDeviceVirtualName string     Specifies the virtual name to map to the corresponding device name. For example: instancestore0
       
   104      *                                                blockDeviceName string            Specifies the device to which you are mapping a virtual name. For example: sdb
       
   105      *                                                monitor boolean               Turn on CloudWatch Monitoring for an instance.
       
   106      * @return array
       
   107      */
       
   108     public function run(array $options)
       
   109     {
       
   110         $_defaultOptions = array(
       
   111             'minCount'  => 1,
       
   112             'maxCount'  => 1,
       
   113             'instanceType' => Zend_Service_Amazon_Ec2_Instance::SMALL
       
   114         );
       
   115 
       
   116         // set / override the defualt optoins if they are not passed into the array;
       
   117         $options = array_merge($_defaultOptions, $options);
       
   118 
       
   119         if(!isset($options['imageId'])) {
       
   120             require_once 'Zend/Service/Amazon/Ec2/Exception.php';
       
   121             throw new Zend_Service_Amazon_Ec2_Exception('No Image Id Provided');
       
   122         }
       
   123 
       
   124 
       
   125         $params = array();
       
   126         $params['Action'] = 'RunInstances';
       
   127         $params['ImageId'] = $options['imageId'];
       
   128         $params['MinCount'] = $options['minCount'];
       
   129         $params['MaxCount'] = $options['maxCount'];
       
   130 
       
   131         if(isset($options['keyName'])) {
       
   132             $params['KeyName'] = $options['keyName'];
       
   133         }
       
   134 
       
   135         if(is_array($options['securityGroup']) && !empty($options['securityGroup'])) {
       
   136             foreach($options['securityGroup'] as $k=>$name) {
       
   137                 $params['SecurityGroup.' . ($k+1)] = $name;
       
   138             }
       
   139         } elseif(isset($options['securityGroup'])) {
       
   140             $params['SecurityGroup.1'] = $options['securityGroup'];
       
   141         }
       
   142 
       
   143         if(isset($options['userData'])) {
       
   144             $params['UserData'] = base64_encode($options['userData']);
       
   145         }
       
   146 
       
   147         if(isset($options['instanceType'])) {
       
   148             $params['InstanceType'] = $options['instanceType'];
       
   149         }
       
   150 
       
   151         if(isset($options['placement'])) {
       
   152             $params['Placement.AvailabilityZone'] = $options['placement'];
       
   153         }
       
   154 
       
   155         if(isset($options['kernelId'])) {
       
   156             $params['KernelId'] = $options['kernelId'];
       
   157         }
       
   158 
       
   159         if(isset($options['ramdiskId'])) {
       
   160             $params['RamdiskId'] = $options['ramdiskId'];
       
   161         }
       
   162 
       
   163         if(isset($options['blockDeviceVirtualName']) && isset($options['blockDeviceName'])) {
       
   164             $params['BlockDeviceMapping.n.VirtualName'] = $options['blockDeviceVirtualName'];
       
   165             $params['BlockDeviceMapping.n.DeviceName'] = $options['blockDeviceName'];
       
   166         }
       
   167 
       
   168         if(isset($options['monitor']) && $options['monitor'] === true) {
       
   169             $params['Monitoring.Enabled'] = true;
       
   170         }
       
   171 
       
   172         $response = $this->sendRequest($params);
       
   173         $xpath = $response->getXPath();
       
   174 
       
   175         $return = array();
       
   176 
       
   177         $return['reservationId'] = $xpath->evaluate('string(//ec2:reservationId/text())');
       
   178         $return['ownerId'] = $xpath->evaluate('string(//ec2:ownerId/text())');
       
   179 
       
   180         $gs = $xpath->query('//ec2:groupSet/ec2:item');
       
   181         foreach($gs as $gs_node) {
       
   182             $return['groupSet'][] = $xpath->evaluate('string(ec2:groupId/text())', $gs_node);
       
   183             unset($gs_node);
       
   184         }
       
   185         unset($gs);
       
   186 
       
   187         $is = $xpath->query('//ec2:instancesSet/ec2:item');
       
   188         foreach($is as $is_node) {
       
   189             $item = array();
       
   190 
       
   191             $item['instanceId'] = $xpath->evaluate('string(ec2:instanceId/text())', $is_node);
       
   192             $item['imageId'] = $xpath->evaluate('string(ec2:imageId/text())', $is_node);
       
   193             $item['instanceState']['code'] = $xpath->evaluate('string(ec2:instanceState/ec2:code/text())', $is_node);
       
   194             $item['instanceState']['name'] = $xpath->evaluate('string(ec2:instanceState/ec2:name/text())', $is_node);
       
   195             $item['privateDnsName'] = $xpath->evaluate('string(ec2:privateDnsName/text())', $is_node);
       
   196             $item['dnsName'] = $xpath->evaluate('string(ec2:dnsName/text())', $is_node);
       
   197             $item['keyName'] = $xpath->evaluate('string(ec2:keyName/text())', $is_node);
       
   198             $item['instanceType'] = $xpath->evaluate('string(ec2:instanceType/text())', $is_node);
       
   199             $item['amiLaunchIndex'] = $xpath->evaluate('string(ec2:amiLaunchIndex/text())', $is_node);
       
   200             $item['launchTime'] = $xpath->evaluate('string(ec2:launchTime/text())', $is_node);
       
   201             $item['availabilityZone'] = $xpath->evaluate('string(ec2:placement/ec2:availabilityZone/text())', $is_node);
       
   202 
       
   203             $return['instances'][] = $item;
       
   204             unset($item);
       
   205             unset($is_node);
       
   206         }
       
   207         unset($is);
       
   208 
       
   209         return $return;
       
   210 
       
   211     }
       
   212 
       
   213     /**
       
   214      * Returns information about instances that you own.
       
   215      *
       
   216      * If you specify one or more instance IDs, Amazon EC2 returns information
       
   217      * for those instances. If you do not specify instance IDs, Amazon EC2
       
   218      * returns information for all relevant instances. If you specify an invalid
       
   219      * instance ID, a fault is returned. If you specify an instance that you do
       
   220      * not own, it will not be included in the returned results.
       
   221      *
       
   222      * Recently terminated instances might appear in the returned results.
       
   223      * This interval is usually less than one hour.
       
   224      *
       
   225      * @param string|array $instaceId       Set of instances IDs of which to get the status.
       
   226      * @param boolean                       Ture to ignore Terminated Instances.
       
   227      * @return array
       
   228      */
       
   229     public function describe($instanceId = null, $ignoreTerminated = false)
       
   230     {
       
   231         $params = array();
       
   232         $params['Action'] = 'DescribeInstances';
       
   233 
       
   234         if(is_array($instanceId) && !empty($instanceId)) {
       
   235             foreach($instanceId as $k=>$name) {
       
   236                 $params['InstanceId.' . ($k+1)] = $name;
       
   237             }
       
   238         } elseif($instanceId) {
       
   239             $params['InstanceId.1'] = $instanceId;
       
   240         }
       
   241 
       
   242         $response = $this->sendRequest($params);
       
   243 
       
   244         $xpath = $response->getXPath();
       
   245 
       
   246         $nodes = $xpath->query('//ec2:reservationSet/ec2:item');
       
   247 
       
   248         $return = array();
       
   249         $return['instances'] = array();
       
   250 
       
   251         foreach($nodes as $node) {
       
   252             if($xpath->evaluate('string(ec2:instancesSet/ec2:item/ec2:instanceState/ec2:code/text())', $node) == 48 && $ignoreTerminated) continue;
       
   253             $item = array();
       
   254 
       
   255             $item['reservationId'] = $xpath->evaluate('string(ec2:reservationId/text())', $node);
       
   256             $item['ownerId'] = $xpath->evaluate('string(ec2:ownerId/text())', $node);
       
   257 
       
   258             $gs = $xpath->query('ec2:groupSet/ec2:item', $node);
       
   259             foreach($gs as $gs_node) {
       
   260                 $item['groupSet'][] = $xpath->evaluate('string(ec2:groupId/text())', $gs_node);
       
   261                 unset($gs_node);
       
   262             }
       
   263             unset($gs);
       
   264 
       
   265             $is = $xpath->query('ec2:instancesSet/ec2:item', $node);
       
   266 
       
   267             foreach($is as $is_node) {
       
   268 
       
   269                 $item['instanceId'] = $xpath->evaluate('string(ec2:instanceId/text())', $is_node);
       
   270                 $item['imageId'] = $xpath->evaluate('string(ec2:imageId/text())', $is_node);
       
   271                 $item['instanceState']['code'] = $xpath->evaluate('string(ec2:instanceState/ec2:code/text())', $is_node);
       
   272                 $item['instanceState']['name'] = $xpath->evaluate('string(ec2:instanceState/ec2:name/text())', $is_node);
       
   273                 $item['privateDnsName'] = $xpath->evaluate('string(ec2:privateDnsName/text())', $is_node);
       
   274                 $item['dnsName'] = $xpath->evaluate('string(ec2:dnsName/text())', $is_node);
       
   275                 $item['keyName'] = $xpath->evaluate('string(ec2:keyName/text())', $is_node);
       
   276                 $item['productCode'] = $xpath->evaluate('string(ec2:productCodesSet/ec2:item/ec2:productCode/text())', $is_node);
       
   277                 $item['instanceType'] = $xpath->evaluate('string(ec2:instanceType/text())', $is_node);
       
   278                 $item['launchTime'] = $xpath->evaluate('string(ec2:launchTime/text())', $is_node);
       
   279                 $item['availabilityZone'] = $xpath->evaluate('string(ec2:placement/ec2:availabilityZone/text())', $is_node);
       
   280                 $item['kernelId'] = $xpath->evaluate('string(ec2:kernelId/text())', $is_node);
       
   281                 $item['ramediskId'] = $xpath->evaluate('string(ec2:ramediskId/text())', $is_node);
       
   282                 $item['amiLaunchIndex'] = $xpath->evaluate('string(ec2:amiLaunchIndex/text())', $is_node);
       
   283                 $item['monitoringState'] = $xpath->evaluate('string(ec2:monitoring/ec2:state/text())', $is_node);
       
   284 
       
   285                 $return['instances'][] = $item;
       
   286                 unset($is_node);
       
   287             }
       
   288             unset($item);
       
   289             unset($is);
       
   290         }
       
   291 
       
   292         return $return;
       
   293     }
       
   294 
       
   295     /**
       
   296      * Returns information about instances that you own that were started from
       
   297      * a specific imageId
       
   298      *
       
   299      * Recently terminated instances might appear in the returned results.
       
   300      * This interval is usually less than one hour.
       
   301      *
       
   302      * @param string $imageId               The imageId used to start the Instance.
       
   303      * @param boolean                       Ture to ignore Terminated Instances.
       
   304      * @return array
       
   305      */
       
   306     public function describeByImageId($imageId, $ignoreTerminated = false)
       
   307     {
       
   308         $arrInstances = $this->describe(null, $ignoreTerminated);
       
   309 
       
   310         $return = array();
       
   311 
       
   312         foreach($arrInstances['instances'] as $instance) {
       
   313             if($instance['imageId'] !== $imageId) continue;
       
   314             $return[] = $instance;
       
   315         }
       
   316 
       
   317         return $return;
       
   318     }
       
   319 
       
   320     /**
       
   321      * Shuts down one or more instances. This operation is idempotent; if you terminate
       
   322      * an instance more than once, each call will succeed.
       
   323      *
       
   324      * Terminated instances will remain visible after termination (approximately one hour).
       
   325      *
       
   326      * @param string|array $instanceId      One or more instance IDs returned.
       
   327      * @return array
       
   328      */
       
   329     public function terminate($instanceId)
       
   330     {
       
   331         $params = array();
       
   332         $params['Action'] = 'TerminateInstances';
       
   333 
       
   334         if(is_array($instanceId) && !empty($instanceId)) {
       
   335             foreach($instanceId as $k=>$name) {
       
   336                 $params['InstanceId.' . ($k+1)] = $name;
       
   337             }
       
   338         } elseif($instanceId) {
       
   339             $params['InstanceId.1'] = $instanceId;
       
   340         }
       
   341 
       
   342         $response = $this->sendRequest($params);
       
   343         $xpath = $response->getXPath();
       
   344 
       
   345         $nodes = $xpath->query('//ec2:instancesSet/ec2:item');
       
   346 
       
   347         $return = array();
       
   348         foreach($nodes as $node) {
       
   349             $item = array();
       
   350 
       
   351             $item['instanceId'] = $xpath->evaluate('string(ec2:instanceId/text())', $node);
       
   352             $item['shutdownState']['code'] = $xpath->evaluate('string(ec2:shutdownState/ec2:code/text())', $node);
       
   353             $item['shutdownState']['name'] = $xpath->evaluate('string(ec2:shutdownState/ec2:name/text())', $node);
       
   354             $item['previousState']['code'] = $xpath->evaluate('string(ec2:previousState/ec2:code/text())', $node);
       
   355             $item['previousState']['name'] = $xpath->evaluate('string(ec2:previousState/ec2:name/text())', $node);
       
   356 
       
   357             $return[] = $item;
       
   358             unset($item);
       
   359         }
       
   360 
       
   361         return $return;
       
   362     }
       
   363 
       
   364     /**
       
   365      * Requests a reboot of one or more instances.
       
   366      *
       
   367      * This operation is asynchronous; it only queues a request to reboot the specified instance(s). The operation
       
   368      * will succeed if the instances are valid and belong to the user. Requests to reboot terminated instances are ignored.
       
   369      *
       
   370      * @param string|array $instanceId  One or more instance IDs.
       
   371      * @return boolean
       
   372      */
       
   373     public function reboot($instanceId)
       
   374     {
       
   375         $params = array();
       
   376         $params['Action'] = 'RebootInstances';
       
   377 
       
   378         if(is_array($instanceId) && !empty($instanceId)) {
       
   379             foreach($instanceId as $k=>$name) {
       
   380                 $params['InstanceId.' . ($k+1)] = $name;
       
   381             }
       
   382         } elseif($instanceId) {
       
   383             $params['InstanceId.1'] = $instanceId;
       
   384         }
       
   385 
       
   386         $response = $this->sendRequest($params);
       
   387         $xpath = $response->getXPath();
       
   388 
       
   389         $return = $xpath->evaluate('string(//ec2:return/text())');
       
   390 
       
   391         return ($return === "true");
       
   392     }
       
   393 
       
   394     /**
       
   395      * Retrieves console output for the specified instance.
       
   396      *
       
   397      * Instance console output is buffered and posted shortly after instance boot, reboot, and termination.
       
   398      * Amazon EC2 preserves the most recent 64 KB output which will be available for at least one hour after the most recent post.
       
   399      *
       
   400      * @param string $instanceId       An instance ID
       
   401      * @return array
       
   402      */
       
   403     public function consoleOutput($instanceId)
       
   404     {
       
   405         $params = array();
       
   406         $params['Action'] = 'GetConsoleOutput';
       
   407         $params['InstanceId'] = $instanceId;
       
   408 
       
   409         $response = $this->sendRequest($params);
       
   410         $xpath = $response->getXPath();
       
   411 
       
   412         $return = array();
       
   413 
       
   414         $return['instanceId'] = $xpath->evaluate('string(//ec2:instanceId/text())');
       
   415         $return['timestamp'] = $xpath->evaluate('string(//ec2:timestamp/text())');
       
   416         $return['output'] = base64_decode($xpath->evaluate('string(//ec2:output/text())'));
       
   417 
       
   418         return $return;
       
   419     }
       
   420 
       
   421     /**
       
   422      * Returns true if the specified product code is attached to the specified instance.
       
   423      * The operation returns false if the product code is not attached to the instance.
       
   424      *
       
   425      * The confirmProduct operation can only be executed by the owner of the AMI.
       
   426      * This feature is useful when an AMI owner is providing support and wants to
       
   427      * verify whether a user's instance is eligible.
       
   428      *
       
   429      * @param string $productCode           The product code to confirm.
       
   430      * @param string $instanceId            The instance for which to confirm the product code.
       
   431      * @return array|boolean                An array if the product code is attached to the instance, false if it is not.
       
   432      */
       
   433     public function confirmProduct($productCode, $instanceId)
       
   434     {
       
   435         $params = array();
       
   436         $params['Action'] = 'ConfirmProductInstance';
       
   437         $params['ProductCode'] = $productCode;
       
   438         $params['InstanceId'] = $instanceId;
       
   439 
       
   440         $response = $this->sendRequest($params);
       
   441         $xpath = $response->getXPath();
       
   442 
       
   443         $result = $xpath->evaluate('string(//ec2:result/text())');
       
   444 
       
   445         if($result === "true") {
       
   446             $return['result'] = true;
       
   447             $return['ownerId'] = $xpath->evaluate('string(//ec2:ownerId/text())');
       
   448 
       
   449             return $return;
       
   450         }
       
   451 
       
   452         return false;
       
   453     }
       
   454 
       
   455     /**
       
   456     * Turn on Amazon CloudWatch Monitoring for an instance or a list of instances
       
   457     *
       
   458     * @param array|string $instanceId           The instance or list of instances you want to enable monitoring for
       
   459     * @return array
       
   460     */
       
   461     public function monitor($instanceId)
       
   462     {
       
   463         $params = array();
       
   464         $params['Action'] = 'MonitorInstances';
       
   465 
       
   466         if(is_array($instanceId) && !empty($instanceId)) {
       
   467             foreach($instanceId as $k=>$name) {
       
   468                 $params['InstanceId.' . ($k+1)] = $name;
       
   469             }
       
   470         } elseif($instanceId) {
       
   471             $params['InstanceId.1'] = $instanceId;
       
   472         }
       
   473 
       
   474         $response = $this->sendRequest($params);
       
   475         $xpath = $response->getXPath();
       
   476 
       
   477 
       
   478         $items = $xpath->query('//ec2:instancesSet/ec2:item');
       
   479 
       
   480         $arrReturn = array();
       
   481         foreach($items as $item) {
       
   482             $i = array();
       
   483             $i['instanceid'] = $xpath->evaluate('string(//ec2:instanceId/text())', $item);
       
   484             $i['monitorstate'] = $xpath->evaluate('string(//ec2:monitoring/ec2:state/text())');
       
   485             $arrReturn[] = $i;
       
   486             unset($i);
       
   487         }
       
   488 
       
   489         return $arrReturn;
       
   490     }
       
   491     /**
       
   492     * Turn off Amazon CloudWatch Monitoring for an instance or a list of instances
       
   493     *
       
   494     * @param array|string $instanceId           The instance or list of instances you want to disable monitoring for
       
   495     * @return array
       
   496     */
       
   497     public function unmonitor($instanceId)
       
   498     {
       
   499         $params = array();
       
   500         $params['Action'] = 'UnmonitorInstances';
       
   501 
       
   502         if(is_array($instanceId) && !empty($instanceId)) {
       
   503             foreach($instanceId as $k=>$name) {
       
   504                 $params['InstanceId.' . ($k+1)] = $name;
       
   505             }
       
   506         } elseif($instanceId) {
       
   507             $params['InstanceId.1'] = $instanceId;
       
   508         }
       
   509 
       
   510         $response = $this->sendRequest($params);
       
   511         $xpath = $response->getXPath();
       
   512 
       
   513 
       
   514         $items = $xpath->query('//ec2:instancesSet/ec2:item');
       
   515 
       
   516         $arrReturn = array();
       
   517         foreach($items as $item) {
       
   518             $i = array();
       
   519             $i['instanceid'] = $xpath->evaluate('string(//ec2:instanceId/text())', $item);
       
   520             $i['monitorstate'] = $xpath->evaluate('string(//ec2:monitoring/ec2:state/text())');
       
   521             $arrReturn[] = $i;
       
   522             unset($i);
       
   523         }
       
   524 
       
   525         return $arrReturn;
       
   526     }
       
   527 
       
   528 }
       
   529