You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/01/15 03:04:54 UTC
[36/44] Revert "Merge remote-tracking branch 'origin/javelin' into
javelin"
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/110465b5/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java
----------------------------------------------------------------------
diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java
index eb25249..0f8eded 100644
--- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java
+++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java
@@ -22,9 +22,6 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.SignatureException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
@@ -32,6 +29,7 @@ import java.util.List;
import java.util.Properties;
import java.util.UUID;
+import javax.inject.Inject;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
@@ -39,13 +37,9 @@ import org.xml.sax.SAXException;
import com.cloud.bridge.model.CloudStackServiceOfferingVO;
import com.cloud.bridge.persist.dao.CloudStackAccountDao;
-import com.cloud.bridge.persist.dao.CloudStackAccountDaoImpl;
import com.cloud.bridge.persist.dao.CloudStackSvcOfferingDao;
-import com.cloud.bridge.persist.dao.CloudStackSvcOfferingDaoImpl;
-import com.cloud.bridge.persist.dao.OfferingDaoImpl;
-import com.cloud.bridge.persist.dao.SObjectItemDaoImpl;
+import com.cloud.bridge.persist.dao.OfferingDao;
import com.cloud.bridge.service.UserContext;
-
import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute;
import com.cloud.bridge.service.exception.EC2ServiceException;
import com.cloud.bridge.service.exception.EC2ServiceException.ClientError;
@@ -68,7 +62,6 @@ import com.cloud.stack.models.CloudStackResourceLimit;
import com.cloud.stack.models.CloudStackResourceTag;
import com.cloud.stack.models.CloudStackSecurityGroup;
import com.cloud.stack.models.CloudStackSecurityGroupIngress;
-import com.cloud.stack.models.CloudStackServiceOffering;
import com.cloud.stack.models.CloudStackSnapshot;
import com.cloud.stack.models.CloudStackTemplate;
import com.cloud.stack.models.CloudStackTemplatePermission;
@@ -76,453 +69,451 @@ import com.cloud.stack.models.CloudStackUser;
import com.cloud.stack.models.CloudStackUserVm;
import com.cloud.stack.models.CloudStackVolume;
import com.cloud.stack.models.CloudStackZone;
-import com.cloud.utils.component.ComponentLocator;
-import com.cloud.utils.db.Transaction;
/**
* EC2Engine processes the ec2 commands and calls their cloudstack analogs
*
*/
public class EC2Engine {
- protected final static Logger logger = Logger.getLogger(EC2Engine.class);
- String managementServer = null;
- String cloudAPIPort = null;
-
- protected final CloudStackSvcOfferingDao scvoDao = ComponentLocator.inject(CloudStackSvcOfferingDaoImpl.class);
- protected final OfferingDaoImpl ofDao = ComponentLocator.inject(OfferingDaoImpl.class);
- CloudStackAccountDao accDao = ComponentLocator.inject(CloudStackAccountDaoImpl.class);
- private CloudStackApi _eng = null;
-
- private CloudStackAccount currentAccount = null;
-
- public EC2Engine() throws IOException {
- loadConfigValues();
- }
-
- /**
- * Which management server to we talk to?
- * Load a mapping form Amazon values for 'instanceType' to cloud defined
- * diskOfferingId and serviceOfferingId.
- *
- * @throws IOException
- */
- private void loadConfigValues() throws IOException {
- File propertiesFile = ConfigurationHelper.findConfigurationFile("ec2-service.properties");
- if (null != propertiesFile) {
- logger.info("Use EC2 properties file: " + propertiesFile.getAbsolutePath());
- Properties EC2Prop = new Properties();
- try {
- EC2Prop.load( new FileInputStream( propertiesFile ));
- } catch (FileNotFoundException e) {
- logger.warn("Unable to open properties file: " + propertiesFile.getAbsolutePath(), e);
- } catch (IOException e) {
- logger.warn("Unable to read properties file: " + propertiesFile.getAbsolutePath(), e);
- }
- managementServer = EC2Prop.getProperty( "managementServer" );
- cloudAPIPort = EC2Prop.getProperty( "cloudAPIPort", null );
-
- try {
- if(ofDao.getOfferingCount() == 0) {
- String strValue = EC2Prop.getProperty("m1.small.serviceId");
- if(strValue != null) ofDao.setOfferMapping("m1.small", strValue);
-
- strValue = EC2Prop.getProperty("m1.large.serviceId");
- if(strValue != null) ofDao.setOfferMapping("m1.large", strValue);
-
- strValue = EC2Prop.getProperty("m1.xlarge.serviceId");
- if(strValue != null) ofDao.setOfferMapping("m1.xlarge", strValue);
-
- strValue = EC2Prop.getProperty("c1.medium.serviceId");
- if(strValue != null) ofDao.setOfferMapping("c1.medium", strValue);
-
- strValue = EC2Prop.getProperty("c1.xlarge.serviceId");
- if(strValue != null) ofDao.setOfferMapping("c1.xlarge", strValue);
-
- strValue = EC2Prop.getProperty("m2.xlarge.serviceId");
- if(strValue != null) ofDao.setOfferMapping("m2.xlarge", strValue);
-
- strValue = EC2Prop.getProperty("m2.2xlarge.serviceId");
- if(strValue != null) ofDao.setOfferMapping("m2.2xlarge", strValue);
-
- strValue = EC2Prop.getProperty("m2.4xlarge.serviceId");
- if(strValue != null) ofDao.setOfferMapping("m2.4xlarge", strValue);
-
- strValue = EC2Prop.getProperty("cc1.4xlarge.serviceId");
- if(strValue != null) ofDao.setOfferMapping("cc1.4xlarge", strValue);
- }
- } catch(Exception e) {
- logger.error("Unexpected exception ", e);
- }
- } else logger.error( "ec2-service.properties not found" );
- }
-
- /**
- * Helper function to manage the api connection
- *
- * @return
- */
- private CloudStackApi getApi() {
- if (_eng == null) {
- _eng = new CloudStackApi(managementServer, cloudAPIPort, false);
- }
- // regardless of whether _eng is initialized, we must make sure
- // access/secret keys are current with what's in the UserCredentials
+ protected final static Logger logger = Logger.getLogger(EC2Engine.class);
+ String managementServer = null;
+ String cloudAPIPort = null;
+
+ @Inject CloudStackSvcOfferingDao scvoDao;
+ @Inject OfferingDao ofDao;
+ @Inject CloudStackAccountDao accDao;
+ private CloudStackApi _eng = null;
+
+ private CloudStackAccount currentAccount = null;
+
+ public EC2Engine() throws IOException {
+ loadConfigValues();
+ }
+
+ /**
+ * Which management server to we talk to?
+ * Load a mapping form Amazon values for 'instanceType' to cloud defined
+ * diskOfferingId and serviceOfferingId.
+ *
+ * @throws IOException
+ */
+ private void loadConfigValues() throws IOException {
+ File propertiesFile = ConfigurationHelper.findConfigurationFile("ec2-service.properties");
+ if (null != propertiesFile) {
+ logger.info("Use EC2 properties file: " + propertiesFile.getAbsolutePath());
+ Properties EC2Prop = new Properties();
+ try {
+ EC2Prop.load( new FileInputStream( propertiesFile ));
+ } catch (FileNotFoundException e) {
+ logger.warn("Unable to open properties file: " + propertiesFile.getAbsolutePath(), e);
+ } catch (IOException e) {
+ logger.warn("Unable to read properties file: " + propertiesFile.getAbsolutePath(), e);
+ }
+ managementServer = EC2Prop.getProperty( "managementServer" );
+ cloudAPIPort = EC2Prop.getProperty( "cloudAPIPort", null );
+
+ try {
+ if(ofDao.getOfferingCount() == 0) {
+ String strValue = EC2Prop.getProperty("m1.small.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("m1.small", strValue);
+
+ strValue = EC2Prop.getProperty("m1.large.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("m1.large", strValue);
+
+ strValue = EC2Prop.getProperty("m1.xlarge.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("m1.xlarge", strValue);
+
+ strValue = EC2Prop.getProperty("c1.medium.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("c1.medium", strValue);
+
+ strValue = EC2Prop.getProperty("c1.xlarge.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("c1.xlarge", strValue);
+
+ strValue = EC2Prop.getProperty("m2.xlarge.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("m2.xlarge", strValue);
+
+ strValue = EC2Prop.getProperty("m2.2xlarge.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("m2.2xlarge", strValue);
+
+ strValue = EC2Prop.getProperty("m2.4xlarge.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("m2.4xlarge", strValue);
+
+ strValue = EC2Prop.getProperty("cc1.4xlarge.serviceId");
+ if(strValue != null) ofDao.setOfferMapping("cc1.4xlarge", strValue);
+ }
+ } catch(Exception e) {
+ logger.error("Unexpected exception ", e);
+ }
+ } else logger.error( "ec2-service.properties not found" );
+ }
+
+ /**
+ * Helper function to manage the api connection
+ *
+ * @return
+ */
+ private CloudStackApi getApi() {
+ if (_eng == null) {
+ _eng = new CloudStackApi(managementServer, cloudAPIPort, false);
+ }
+ // regardless of whether _eng is initialized, we must make sure
+ // access/secret keys are current with what's in the UserCredentials
_eng.setApiKey(UserContext.current().getAccessKey());
_eng.setSecretKey(UserContext.current().getSecretKey());
- return _eng;
- }
-
-
- /**
- * Verifies account can access CloudStack
- *
- * @param accessKey
- * @param secretKey
- * @return
- * @throws EC2ServiceException
- */
- public boolean validateAccount( String accessKey, String secretKey ) throws EC2ServiceException {
- String oldApiKey = null;
- String oldSecretKey = null;
-
- if (accessKey == null || secretKey == null) {
+ return _eng;
+ }
+
+
+ /**
+ * Verifies account can access CloudStack
+ *
+ * @param accessKey
+ * @param secretKey
+ * @return
+ * @throws EC2ServiceException
+ */
+ public boolean validateAccount( String accessKey, String secretKey ) throws EC2ServiceException {
+ String oldApiKey = null;
+ String oldSecretKey = null;
+
+ if (accessKey == null || secretKey == null) {
return false;
}
-
- // okay, instead of using the getApi() nonsense for validate, we are going to manage _eng
- if (_eng == null) {
+
+ // okay, instead of using the getApi() nonsense for validate, we are going to manage _eng
+ if (_eng == null) {
_eng = new CloudStackApi(managementServer, cloudAPIPort, false);
- }
-
- try {
- oldApiKey = _eng.getApiKey();
- oldSecretKey = _eng.getSecretKey();
- } catch(Exception e) {
- // we really don't care, and expect this
- }
+ }
+
+ try {
+ oldApiKey = _eng.getApiKey();
+ oldSecretKey = _eng.getSecretKey();
+ } catch(Exception e) {
+ // we really don't care, and expect this
+ }
+ try {
+ _eng.setApiKey(accessKey);
+ _eng.setSecretKey(secretKey);
+ List<CloudStackAccount> accts = _eng.listAccounts(null, null, null, null, null, null, null, null);
+ if (oldApiKey != null && oldSecretKey != null) {
+ _eng.setApiKey(oldApiKey);
+ _eng.setSecretKey(oldSecretKey);
+ }
+ if (accts == null) {
+ return false;
+ }
+ return true;
+ } catch(Exception e) {
+ logger.error("Validate account failed!");
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * Creates a security group
+ *
+ * @param groupName
+ * @param groupDesc
+ * @return
+ */
+ public Boolean createSecurityGroup(String groupName, String groupDesc) {
+ try {
+ CloudStackSecurityGroup grp = getApi().createSecurityGroup(groupName, null, groupDesc, null);
+ if (grp != null && grp.getId() != null) {
+ return true;
+ }
+ return false;
+ } catch( Exception e ) {
+ logger.error( "EC2 CreateSecurityGroup - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * Deletes a security group
+ *
+ * @param groupName
+ * @return
+ */
+ public boolean deleteSecurityGroup(String groupName) {
+ try {
+ CloudStackInfoResponse resp = getApi().deleteSecurityGroup(null, null, null, groupName);
+ if (resp != null) {
+ return resp.getSuccess();
+ }
+ return false;
+ } catch( Exception e ) {
+ logger.error( "EC2 DeleteSecurityGroup - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * returns a list of security groups
+ *
+ * @param request
+ * @return
+ */
+ public EC2DescribeSecurityGroupsResponse describeSecurityGroups(EC2DescribeSecurityGroups request)
+ {
+ try {
+ EC2DescribeSecurityGroupsResponse response = listSecurityGroups( request.getGroupSet());
+ EC2GroupFilterSet gfs = request.getFilterSet();
+
+ if ( null == gfs )
+ return response;
+ else return gfs.evaluate( response );
+ } catch( Exception e ) {
+ logger.error( "EC2 DescribeSecurityGroups - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * CloudStack supports revoke only by using the ruleid of the ingress rule.
+ * We list all security groups and find the matching group and use the first ruleId we find.
+ *
+ * @param request
+ * @return
+ */
+ public boolean revokeSecurityGroup( EC2AuthorizeRevokeSecurityGroup request )
+ {
+ if (null == request.getName()) throw new EC2ServiceException(ServerError.InternalError, "Name is a required parameter");
+ try {
+ String[] groupSet = new String[1];
+ groupSet[0] = request.getName();
+ String ruleId = null;
+
+ EC2IpPermission[] items = request.getIpPermissionSet();
+
+ EC2DescribeSecurityGroupsResponse response = listSecurityGroups( groupSet );
+ EC2SecurityGroup[] groups = response.getGroupSet();
+
+ for (EC2SecurityGroup group : groups) {
+ EC2IpPermission[] perms = group.getIpPermissionSet();
+ for (EC2IpPermission perm : perms) {
+ ruleId = doesRuleMatch( items[0], perm );
+ if (ruleId != null) break;
+ }
+ }
+
+ if (null == ruleId)
+ throw new EC2ServiceException(ClientError.InvalidGroup_NotFound, "Cannot find matching ruleid.");
+
+ CloudStackInfoResponse resp = getApi().revokeSecurityGroupIngress(ruleId);
+ if (resp != null && resp.getId() != null) {
+ return resp.getSuccess();
+ }
+ return false;
+ } catch( Exception e ) {
+ logger.error( "EC2 revokeSecurityGroupIngress" + " - " + e.getMessage());
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * authorizeSecurityGroup
+ *
+ * @param request - ip permission parameters
+ */
+ public boolean authorizeSecurityGroup(EC2AuthorizeRevokeSecurityGroup request )
+ {
+ if (null == request.getName()) throw new EC2ServiceException(ServerError.InternalError, "Name is a required parameter");
+
+ EC2IpPermission[] items = request.getIpPermissionSet();
+
try {
- _eng.setApiKey(accessKey);
- _eng.setSecretKey(secretKey);
- List<CloudStackAccount> accts = _eng.listAccounts(null, null, null, null, null, null, null, null);
- if (oldApiKey != null && oldSecretKey != null) {
- _eng.setApiKey(oldApiKey);
- _eng.setSecretKey(oldSecretKey);
- }
- if (accts == null) {
- return false;
- }
- return true;
- } catch(Exception e) {
- logger.error("Validate account failed!");
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * Creates a security group
- *
- * @param groupName
- * @param groupDesc
- * @return
- */
- public Boolean createSecurityGroup(String groupName, String groupDesc) {
- try {
- CloudStackSecurityGroup grp = getApi().createSecurityGroup(groupName, null, groupDesc, null);
- if (grp != null && grp.getId() != null) {
- return true;
- }
- return false;
- } catch( Exception e ) {
- logger.error( "EC2 CreateSecurityGroup - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * Deletes a security group
- *
- * @param groupName
- * @return
- */
- public boolean deleteSecurityGroup(String groupName) {
- try {
- CloudStackInfoResponse resp = getApi().deleteSecurityGroup(null, null, null, groupName);
- if (resp != null) {
- return resp.getSuccess();
- }
- return false;
- } catch( Exception e ) {
- logger.error( "EC2 DeleteSecurityGroup - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * returns a list of security groups
- *
- * @param request
- * @return
- */
- public EC2DescribeSecurityGroupsResponse describeSecurityGroups(EC2DescribeSecurityGroups request)
- {
- try {
- EC2DescribeSecurityGroupsResponse response = listSecurityGroups( request.getGroupSet());
- EC2GroupFilterSet gfs = request.getFilterSet();
-
- if ( null == gfs )
- return response;
- else return gfs.evaluate( response );
- } catch( Exception e ) {
- logger.error( "EC2 DescribeSecurityGroups - ", e);
- throw new EC2ServiceException(ServerError.InternalError, "An unexpected error occurred.");
- }
- }
-
- /**
- * CloudStack supports revoke only by using the ruleid of the ingress rule.
- * We list all security groups and find the matching group and use the first ruleId we find.
- *
- * @param request
- * @return
- */
- public boolean revokeSecurityGroup( EC2AuthorizeRevokeSecurityGroup request )
- {
- if (null == request.getName()) throw new EC2ServiceException(ServerError.InternalError, "Name is a required parameter");
- try {
- String[] groupSet = new String[1];
- groupSet[0] = request.getName();
- String ruleId = null;
-
- EC2IpPermission[] items = request.getIpPermissionSet();
-
- EC2DescribeSecurityGroupsResponse response = listSecurityGroups( groupSet );
- EC2SecurityGroup[] groups = response.getGroupSet();
-
- for (EC2SecurityGroup group : groups) {
- EC2IpPermission[] perms = group.getIpPermissionSet();
- for (EC2IpPermission perm : perms) {
- ruleId = doesRuleMatch( items[0], perm );
- if (ruleId != null) break;
- }
- }
-
- if (null == ruleId)
- throw new EC2ServiceException(ClientError.InvalidGroup_NotFound, "Cannot find matching ruleid.");
-
- CloudStackInfoResponse resp = getApi().revokeSecurityGroupIngress(ruleId);
- if (resp != null && resp.getId() != null) {
- return resp.getSuccess();
- }
- return false;
- } catch( Exception e ) {
- logger.error( "EC2 revokeSecurityGroupIngress" + " - " + e.getMessage());
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * authorizeSecurityGroup
- *
- * @param request - ip permission parameters
- */
- public boolean authorizeSecurityGroup(EC2AuthorizeRevokeSecurityGroup request )
- {
- if (null == request.getName()) throw new EC2ServiceException(ServerError.InternalError, "Name is a required parameter");
-
- EC2IpPermission[] items = request.getIpPermissionSet();
-
- try {
- for (EC2IpPermission ipPerm : items) {
- EC2SecurityGroup[] groups = ipPerm.getUserSet();
-
- List<CloudStackKeyValue> secGroupList = new ArrayList<CloudStackKeyValue>();
- for (EC2SecurityGroup group : groups) {
- CloudStackKeyValue pair = new CloudStackKeyValue();
- pair.setKeyValue(group.getAccount(), group.getName());
- secGroupList.add(pair);
- }
- CloudStackSecurityGroupIngress resp = null;
- if (ipPerm.getProtocol().equalsIgnoreCase("icmp")) {
- resp = getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, null,
- ipPerm.getIcmpCode(), ipPerm.getIcmpType(), ipPerm.getProtocol(), null,
- request.getName(), null, secGroupList);
- } else {
- resp = getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null,
- ipPerm.getToPort().longValue(), null, null, ipPerm.getProtocol(), null, request.getName(),
- ipPerm.getFromPort().longValue(), secGroupList);
- }
- if (resp != null && resp.getRuleId() != null) {
- return true;
- }
- return false;
- }
- } catch(Exception e) {
- logger.error( "EC2 AuthorizeSecurityGroupIngress - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- return true;
- }
-
- /**
- * Does the permission from the request (left) match the permission from the cloudStack query (right).
- * If the cloudStack rule matches then we return its ruleId.
- *
- * @param permLeft
- * @param permRight
- * @return ruleId of the cloudstack rule
- */
- private String doesRuleMatch(EC2IpPermission permLeft, EC2IpPermission permRight)
- {
- int matches = 0;
-
- if (null != permLeft.getIcmpType() && null != permLeft.getIcmpCode()) {
- if (null == permRight.getIcmpType() || null == permRight.getIcmpCode()) return null;
-
- if (!permLeft.getIcmpType().equalsIgnoreCase( permRight.getIcmpType())) return null;
- if (!permLeft.getIcmpCode().equalsIgnoreCase( permRight.getIcmpCode())) return null;
- matches++;
- }
-
- // -> "Valid Values for EC2 security groups: tcp | udp | icmp or the corresponding protocol number (6 | 17 | 1)."
- if (null != permLeft.getProtocol()) {
- if (null == permRight.getProtocol()) return null;
-
- String protocol = permLeft.getProtocol();
- if (protocol.equals( "6" )) protocol = "tcp";
- else if (protocol.equals( "17" )) protocol = "udp";
- else if (protocol.equals( "1" )) protocol = "icmp";
-
- if (!protocol.equalsIgnoreCase( permRight.getProtocol())) return null;
- matches++;
- }
-
-
- if (null != permLeft.getCIDR()) {
- if (null == permRight.getCIDR()) return null;
-
- if (!permLeft.getCIDR().equalsIgnoreCase( permRight.getCIDR())) return null;
- matches++;
- }
-
- // -> is the port(s) from the request (left) a match of the rule's port(s)
- if (0 != permLeft.getFromPort()) {
- // -> -1 means all ports match
- if (-1 != permLeft.getFromPort()) {
- if (permLeft.getFromPort().compareTo(permRight.getFromPort()) != 0 ||
- permLeft.getToPort().compareTo(permRight.getToPort()) != 0)
- return null;
- }
- matches++;
- }
-
-
- // -> was permLeft set up properly with at least one property to match?
- if ( 0 == matches )
- return null;
- else return permRight.getRuleId();
- }
-
- /**
- * Returns a list of all snapshots
- *
- * @param request
- * @return
- */
+ for (EC2IpPermission ipPerm : items) {
+ EC2SecurityGroup[] groups = ipPerm.getUserSet();
+
+ List<CloudStackKeyValue> secGroupList = new ArrayList<CloudStackKeyValue>();
+ for (EC2SecurityGroup group : groups) {
+ CloudStackKeyValue pair = new CloudStackKeyValue();
+ pair.setKeyValue(group.getAccount(), group.getName());
+ secGroupList.add(pair);
+ }
+ CloudStackSecurityGroupIngress resp = null;
+ if (ipPerm.getProtocol().equalsIgnoreCase("icmp")) {
+ resp = getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null, null,
+ ipPerm.getIcmpCode(), ipPerm.getIcmpType(), ipPerm.getProtocol(), null,
+ request.getName(), null, secGroupList);
+ } else {
+ resp = getApi().authorizeSecurityGroupIngress(null, constructList(ipPerm.getIpRangeSet()), null,
+ ipPerm.getToPort().longValue(), null, null, ipPerm.getProtocol(), null, request.getName(),
+ ipPerm.getFromPort().longValue(), secGroupList);
+ }
+ if (resp != null && resp.getRuleId() != null) {
+ return true;
+ }
+ return false;
+ }
+ } catch(Exception e) {
+ logger.error( "EC2 AuthorizeSecurityGroupIngress - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ return true;
+ }
+
+ /**
+ * Does the permission from the request (left) match the permission from the cloudStack query (right).
+ * If the cloudStack rule matches then we return its ruleId.
+ *
+ * @param permLeft
+ * @param permRight
+ * @return ruleId of the cloudstack rule
+ */
+ private String doesRuleMatch(EC2IpPermission permLeft, EC2IpPermission permRight)
+ {
+ int matches = 0;
+
+ if (null != permLeft.getIcmpType() && null != permLeft.getIcmpCode()) {
+ if (null == permRight.getIcmpType() || null == permRight.getIcmpCode()) return null;
+
+ if (!permLeft.getIcmpType().equalsIgnoreCase( permRight.getIcmpType())) return null;
+ if (!permLeft.getIcmpCode().equalsIgnoreCase( permRight.getIcmpCode())) return null;
+ matches++;
+ }
+
+ // -> "Valid Values for EC2 security groups: tcp | udp | icmp or the corresponding protocol number (6 | 17 | 1)."
+ if (null != permLeft.getProtocol()) {
+ if (null == permRight.getProtocol()) return null;
+
+ String protocol = permLeft.getProtocol();
+ if (protocol.equals( "6" )) protocol = "tcp";
+ else if (protocol.equals( "17" )) protocol = "udp";
+ else if (protocol.equals( "1" )) protocol = "icmp";
+
+ if (!protocol.equalsIgnoreCase( permRight.getProtocol())) return null;
+ matches++;
+ }
+
+
+ if (null != permLeft.getCIDR()) {
+ if (null == permRight.getCIDR()) return null;
+
+ if (!permLeft.getCIDR().equalsIgnoreCase( permRight.getCIDR())) return null;
+ matches++;
+ }
+
+ // -> is the port(s) from the request (left) a match of the rule's port(s)
+ if (0 != permLeft.getFromPort()) {
+ // -> -1 means all ports match
+ if (-1 != permLeft.getFromPort()) {
+ if (permLeft.getFromPort().compareTo(permRight.getFromPort()) != 0 ||
+ permLeft.getToPort().compareTo(permRight.getToPort()) != 0)
+ return null;
+ }
+ matches++;
+ }
+
+
+ // -> was permLeft set up properly with at least one property to match?
+ if ( 0 == matches )
+ return null;
+ else return permRight.getRuleId();
+ }
+
+ /**
+ * Returns a list of all snapshots
+ *
+ * @param request
+ * @return
+ */
public EC2DescribeSnapshotsResponse handleRequest( EC2DescribeSnapshots request )
- {
- EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
- EC2SnapshotFilterSet sfs = request.getFilterSet();
+ {
+ EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
+ EC2SnapshotFilterSet sfs = request.getFilterSet();
EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
- try {
- // -> query to get the volume size for each snapshot
+ try {
+ // -> query to get the volume size for each snapshot
EC2DescribeSnapshotsResponse response = listSnapshots( request.getSnapshotSet(),
getResourceTags(tagKeyValueSet));
- if (response == null) {
- return new EC2DescribeSnapshotsResponse();
- }
- EC2Snapshot[] snapshots = response.getSnapshotSet();
- for (EC2Snapshot snap : snapshots) {
- volumes = listVolumes(snap.getVolumeId(), null, volumes, null);
- EC2Volume[] volSet = volumes.getVolumeSet();
- if (0 < volSet.length) snap.setVolumeSize(volSet[0].getSize());
- volumes.reset();
- }
-
- if ( null == sfs )
- return response;
- else return sfs.evaluate( response );
- } catch( EC2ServiceException error ) {
- logger.error( "EC2 DescribeSnapshots - ", error);
- throw error;
-
- } catch( Exception e ) {
- logger.error( "EC2 DescribeSnapshots - ", e);
- throw new EC2ServiceException(ServerError.InternalError, "An unexpected error occurred.");
- }
- }
-
- /**
- * Creates a snapshot
- *
- * @param volumeId
- * @return
- */
- public EC2Snapshot createSnapshot( String volumeId ) {
- try {
-
- CloudStackSnapshot snap = getApi().createSnapshot(volumeId, null, null, null);
- if (snap == null) {
- throw new EC2ServiceException(ServerError.InternalError, "Unable to create snapshot!");
- }
- EC2Snapshot ec2Snapshot = new EC2Snapshot();
-
- ec2Snapshot.setId(snap.getId());
- ec2Snapshot.setName(snap.getName());
- ec2Snapshot.setType(snap.getSnapshotType());
- ec2Snapshot.setAccountName(snap.getAccountName());
- ec2Snapshot.setDomainId(snap.getDomainId());
- ec2Snapshot.setCreated(snap.getCreated());
- ec2Snapshot.setVolumeId(snap.getVolumeId());
-
- List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, snap.getVolumeId(), null, null, null, null, null, null, null, null);
-
- if(vols.size() > 0) {
- assert(vols.get(0).getSize() != null);
- Long sizeInGB = vols.get(0).getSize().longValue()/1073741824;
- ec2Snapshot.setVolumeSize(sizeInGB);
- }
-
- return ec2Snapshot;
- } catch( Exception e ) {
- logger.error( "EC2 CreateSnapshot - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * Deletes a snapshot
- *
- * @param snapshotId
- * @return
- */
- public boolean deleteSnapshot(String snapshotId) {
- try {
-
- CloudStackInfoResponse resp = getApi().deleteSnapshot(snapshotId);
- if(resp != null) {
- return resp.getSuccess();
- }
-
- return false;
- } catch(Exception e) {
- logger.error( "EC2 DeleteSnapshot - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
-
- /** REST API calls this method.
+ if (response == null) {
+ return new EC2DescribeSnapshotsResponse();
+ }
+ EC2Snapshot[] snapshots = response.getSnapshotSet();
+ for (EC2Snapshot snap : snapshots) {
+ volumes = listVolumes(snap.getVolumeId(), null, volumes, null);
+ EC2Volume[] volSet = volumes.getVolumeSet();
+ if (0 < volSet.length) snap.setVolumeSize(volSet[0].getSize());
+ volumes.reset();
+ }
+
+ if ( null == sfs )
+ return response;
+ else return sfs.evaluate( response );
+ } catch( EC2ServiceException error ) {
+ logger.error( "EC2 DescribeSnapshots - ", error);
+ throw error;
+
+ } catch( Exception e ) {
+ logger.error( "EC2 DescribeSnapshots - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * Creates a snapshot
+ *
+ * @param volumeId
+ * @return
+ */
+ public EC2Snapshot createSnapshot( String volumeId ) {
+ try {
+
+ CloudStackSnapshot snap = getApi().createSnapshot(volumeId, null, null, null);
+ if (snap == null) {
+ throw new EC2ServiceException(ServerError.InternalError, "Unable to create snapshot!");
+ }
+ EC2Snapshot ec2Snapshot = new EC2Snapshot();
+
+ ec2Snapshot.setId(snap.getId());
+ ec2Snapshot.setName(snap.getName());
+ ec2Snapshot.setType(snap.getSnapshotType());
+ ec2Snapshot.setAccountName(snap.getAccountName());
+ ec2Snapshot.setDomainId(snap.getDomainId());
+ ec2Snapshot.setCreated(snap.getCreated());
+ ec2Snapshot.setVolumeId(snap.getVolumeId());
+
+ List<CloudStackVolume> vols = getApi().listVolumes(null, null, null, snap.getVolumeId(), null, null, null, null, null, null, null, null);
+
+ if(vols.size() > 0) {
+ assert(vols.get(0).getSize() != null);
+ Long sizeInGB = vols.get(0).getSize().longValue()/1073741824;
+ ec2Snapshot.setVolumeSize(sizeInGB);
+ }
+
+ return ec2Snapshot;
+ } catch( Exception e ) {
+ logger.error( "EC2 CreateSnapshot - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * Deletes a snapshot
+ *
+ * @param snapshotId
+ * @return
+ */
+ public boolean deleteSnapshot(String snapshotId) {
+ try {
+
+ CloudStackInfoResponse resp = getApi().deleteSnapshot(snapshotId);
+ if(resp != null) {
+ return resp.getSuccess();
+ }
+
+ return false;
+ } catch(Exception e) {
+ logger.error( "EC2 DeleteSnapshot - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+
+ /** REST API calls this method.
* Modify an existing template
*
* @param request
@@ -536,7 +527,7 @@ public class EC2Engine {
try {
images = listTemplates( request.getId(), images );
EC2Image[] imageSet = images.getImageSet();
-
+
CloudStackTemplate resp = getApi().updateTemplate(request.getId(), null, request.getDescription(), null, imageSet[0].getName(), null, null);
if (resp != null) {
return true;
@@ -549,21 +540,21 @@ public class EC2Engine {
}
- /**
- * Modify an existing template
- *
- * @param request
- * @return
- */
- public boolean modifyImageAttribute( EC2ModifyImageAttribute request )
- {
+ /**
+ * Modify an existing template
+ *
+ * @param request
+ * @return
+ */
+ public boolean modifyImageAttribute( EC2ModifyImageAttribute request )
+ {
try {
if(request.getAttribute().equals(ImageAttribute.launchPermission)){
-
+
String accounts = "";
Boolean isPublic = null;
EC2ModifyImageAttribute.Operation operation = request.getLaunchPermOperation();
-
+
List<String> accountOrGroupList = request.getLaunchPermissionAccountsList();
if(accountOrGroupList != null && !accountOrGroupList.isEmpty()){
boolean first = true;
@@ -597,25 +588,25 @@ public class EC2Engine {
logger.error( "EC2 modifyImageAttribute - ", e);
throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
}
-
+
return false;
-
-
- }
-
+
+
+ }
+
public EC2ImageAttributes describeImageAttribute(EC2DescribeImageAttribute request) {
EC2ImageAttributes imageAtts = new EC2ImageAttributes();
-
+
try {
imageAtts.setImageId(request.getImageId());
if(request.getAttribute().equals(ImageAttribute.launchPermission)){
CloudStackTemplatePermission tempPerm = getApi().listTemplatePermissions(request.getImageId(), null, null);
if(tempPerm != null){
imageAtts.setDomainId(tempPerm.getDomainId());
-
+
List<String> accntList = tempPerm.getAccounts();
imageAtts.setAccountNamesWithLaunchPermission(accntList);
-
+
imageAtts.setIsPublic(tempPerm.getIsPublic());
}
}else if(request.getAttribute().equals(ImageAttribute.description)){
@@ -631,47 +622,47 @@ public class EC2Engine {
logger.error( "EC2 describeImageAttribute - ", e);
throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
}
-
+
return imageAtts;
}
-
- /**
- * If given a specific list of snapshots of interest, then only values from those snapshots are returned.
- *
- * @param interestedShots - can be null, should be a subset of all snapshots
- */
+
+ /**
+ * If given a specific list of snapshots of interest, then only values from those snapshots are returned.
+ *
+ * @param interestedShots - can be null, should be a subset of all snapshots
+ */
private EC2DescribeSnapshotsResponse listSnapshots( String[] interestedShots, List<CloudStackKeyValue> resourceTagSet ) throws Exception {
- EC2DescribeSnapshotsResponse snapshots = new EC2DescribeSnapshotsResponse();
+ EC2DescribeSnapshotsResponse snapshots = new EC2DescribeSnapshotsResponse();
- List<CloudStackSnapshot> cloudSnaps;
- if (interestedShots == null || interestedShots.length == 0) {
+ List<CloudStackSnapshot> cloudSnaps;
+ if (interestedShots == null || interestedShots.length == 0) {
cloudSnaps = getApi().listSnapshots(null, null, null, null, null, null, null, null, null, resourceTagSet);
- } else {
- cloudSnaps = new ArrayList<CloudStackSnapshot>();
+ } else {
+ cloudSnaps = new ArrayList<CloudStackSnapshot>();
- for(String id : interestedShots) {
+ for(String id : interestedShots) {
List<CloudStackSnapshot> tmpList = getApi().listSnapshots(null, null, id, null, null, null, null,
- null, null, resourceTagSet);
- cloudSnaps.addAll(tmpList);
- }
- }
-
- if (cloudSnaps == null) {
- return null;
- }
-
- for(CloudStackSnapshot cloudSnapshot : cloudSnaps) {
- EC2Snapshot shot = new EC2Snapshot();
- shot.setId(cloudSnapshot.getId());
- shot.setName(cloudSnapshot.getName());
- shot.setVolumeId(cloudSnapshot.getVolumeId());
- shot.setType(cloudSnapshot.getSnapshotType());
- shot.setState(cloudSnapshot.getState());
- shot.setCreated(cloudSnapshot.getCreated());
- shot.setAccountName(cloudSnapshot.getAccountName());
- shot.setDomainId(cloudSnapshot.getDomainId());
+ null, null, resourceTagSet);
+ cloudSnaps.addAll(tmpList);
+ }
+ }
+
+ if (cloudSnaps == null) {
+ return null;
+ }
+
+ for(CloudStackSnapshot cloudSnapshot : cloudSnaps) {
+ EC2Snapshot shot = new EC2Snapshot();
+ shot.setId(cloudSnapshot.getId());
+ shot.setName(cloudSnapshot.getName());
+ shot.setVolumeId(cloudSnapshot.getVolumeId());
+ shot.setType(cloudSnapshot.getSnapshotType());
+ shot.setState(cloudSnapshot.getState());
+ shot.setCreated(cloudSnapshot.getCreated());
+ shot.setAccountName(cloudSnapshot.getAccountName());
+ shot.setDomainId(cloudSnapshot.getDomainId());
List<CloudStackKeyValue> resourceTags = cloudSnapshot.getTags();
for(CloudStackKeyValue resourceTag : resourceTags) {
@@ -682,663 +673,663 @@ public class EC2Engine {
shot.addResourceTag(param);
}
- snapshots.addSnapshot(shot);
- }
- return snapshots;
- }
-
-
- // handlers
- /**
- * return password data from the instance
- *
- * @param instanceId
- * @return
- */
- public EC2PasswordData getPasswordData(String instanceId) {
- try {
- CloudStackPasswordData resp = getApi().getVMPassword(instanceId);
- EC2PasswordData passwdData = new EC2PasswordData();
- if (resp != null) {
- passwdData.setInstanceId(instanceId);
- passwdData.setEncryptedPassword(resp.getEncryptedpassword());
- }
- return passwdData;
- } catch(Exception e) {
- logger.error("EC2 GetPasswordData - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
- /**
- * Lists SSH KeyPairs on the systme
- *
- * @param request
- * @return
- */
- public EC2DescribeKeyPairsResponse describeKeyPairs( EC2DescribeKeyPairs request ) {
- try {
- EC2KeyPairFilterSet filterSet = request.getKeyFilterSet();
- String[] keyNames = request.getKeyNames();
- List<CloudStackKeyPair> keyPairs = getApi().listSSHKeyPairs(null, null, null);
- List<EC2SSHKeyPair> keyPairsList = new ArrayList<EC2SSHKeyPair>();
-
- if (keyPairs != null) {
- // Let's trim the list of keypairs to only the ones listed in keyNames
- List<CloudStackKeyPair> matchedKeyPairs = new ArrayList<CloudStackKeyPair>();
- if (keyNames != null && keyNames.length > 0) {
- for (CloudStackKeyPair keyPair : keyPairs) {
- boolean matched = false;
- for (String keyName : keyNames) {
- if (keyPair.getName().equalsIgnoreCase(keyName)) {
- matched = true;
- break;
- }
- }
- if (matched) {
- matchedKeyPairs.add(keyPair);
- }
- }
- if (matchedKeyPairs.isEmpty()) {
- throw new EC2ServiceException(ServerError.InternalError, "No matching keypairs found");
- }
- }else{
- matchedKeyPairs = keyPairs;
- }
-
-
- // this should be reworked... converting from CloudStackKeyPairResponse to EC2SSHKeyPair is dumb
- for (CloudStackKeyPair respKeyPair: matchedKeyPairs) {
- EC2SSHKeyPair ec2KeyPair = new EC2SSHKeyPair();
- ec2KeyPair.setFingerprint(respKeyPair.getFingerprint());
- ec2KeyPair.setKeyName(respKeyPair.getName());
- ec2KeyPair.setPrivateKey(respKeyPair.getPrivatekey());
- keyPairsList.add(ec2KeyPair);
- }
- }
- return filterSet.evaluate(keyPairsList);
- } catch(Exception e) {
- logger.error("EC2 DescribeKeyPairs - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * Delete SSHKeyPair
- *
- * @param request
- * @return
- */
- public boolean deleteKeyPair( EC2DeleteKeyPair request ) {
- try {
- CloudStackInfoResponse resp = getApi().deleteSSHKeyPair(request.getKeyName(), null, null);
- if (resp == null) {
- throw new Exception("Ivalid CloudStack API response");
- }
-
- return resp.getSuccess();
- } catch(Exception e) {
- logger.error("EC2 DeleteKeyPair - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * Create SSHKeyPair
- *
- * @param request
- * @return
- */
- public EC2SSHKeyPair createKeyPair(EC2CreateKeyPair request) {
- try {
- CloudStackKeyPair resp = getApi().createSSHKeyPair(request.getKeyName(), null, null);
- if (resp == null) {
- throw new Exception("Ivalid CloudStack API response");
- }
-
- EC2SSHKeyPair response = new EC2SSHKeyPair();
- response.setFingerprint(resp.getFingerprint());
- response.setKeyName(resp.getName());
- response.setPrivateKey(resp.getPrivatekey());
-
- return response;
- } catch (Exception e) {
- logger.error("EC2 CreateKeyPair - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * Import an existing SSH KeyPair
- *
- * @param request
- * @return
- */
- public EC2SSHKeyPair importKeyPair( EC2ImportKeyPair request ) {
- try {
- CloudStackKeyPair resp = getApi().registerSSHKeyPair(request.getKeyName(), request.getPublicKeyMaterial());
- if (resp == null) {
- throw new Exception("Ivalid CloudStack API response");
- }
-
- EC2SSHKeyPair response = new EC2SSHKeyPair();
- response.setFingerprint(resp.getFingerprint());
- response.setKeyName(resp.getName());
- response.setPrivateKey(resp.getPrivatekey());
-
- return response;
- } catch (Exception e) {
- logger.error("EC2 ImportKeyPair - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * list ip addresses that have been allocated
- *
- * @param request
- * @return
- */
- public EC2DescribeAddressesResponse describeAddresses( EC2DescribeAddresses request ) {
- try {
- List<CloudStackIpAddress> addrList = getApi().listPublicIpAddresses(null, null, null, null, null, null, null, null, null);
-
- EC2AddressFilterSet filterSet = request.getFilterSet();
- List<EC2Address> addressList = new ArrayList<EC2Address>();
- if (addrList != null && addrList.size() > 0) {
- for (CloudStackIpAddress addr: addrList) {
- // remember, if no filters are set, request.inPublicIpSet always returns true
- if (request.inPublicIpSet(addr.getIpAddress())) {
- EC2Address ec2Address = new EC2Address();
- ec2Address.setIpAddress(addr.getIpAddress());
- if (addr.getVirtualMachineId() != null)
- ec2Address.setAssociatedInstanceId(addr.getVirtualMachineId().toString());
- addressList.add(ec2Address);
- }
- }
- }
-
- return filterSet.evaluate(addressList);
- } catch(Exception e) {
- logger.error("EC2 DescribeAddresses - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- }
-
- /**
- * release an IP Address
- *
- * @param request
- * @return
- */
- public boolean releaseAddress(EC2ReleaseAddress request) {
- try {
- CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
- CloudStackInfoResponse resp = getApi().disassociateIpAddress(cloudIp.getId());
- if (resp != null) {
- return resp.getSuccess();
- }
- } catch(Exception e) {
- logger.error("EC2 ReleaseAddress - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
- }
- return false;
- }
-
- /**
- * Associate an address with an instance
- *
- * @param request
- * @return
- */
- public boolean associateAddress( EC2AssociateAddress request ) {
- try {
- CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
- CloudStackUserVm cloudVm = getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null).get(0);
-
- CloudStackInfoResponse resp = getApi().enableStaticNat(cloudIp.getId(), cloudVm.getId());
- if (resp != null) {
- return resp.getSuccess();
- }
- } catch(Exception e) {
- logger.error( "EC2 AssociateAddress - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- return false;
- }
-
- /**
- * Disassociate an address from an instance
- *
- * @param request
- * @return
- */
- public boolean disassociateAddress( EC2DisassociateAddress request ) {
- try {
- CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
- CloudStackInfoResponse resp = getApi().disableStaticNat(cloudIp.getId());
- if (resp != null) {
- return resp.getSuccess();
- }
- } catch(Exception e) {
- logger.error( "EC2 DisassociateAddress - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- return false;
- }
-
- /**
- * Allocate an address
- *
- * @param request
- * @return
- */
- public EC2Address allocateAddress()
- {
- try {
- EC2Address ec2Address = new EC2Address();
- // this gets our networkId
- CloudStackAccount caller = getCurrentAccount();
-
- CloudStackZone zone = findZone();
- CloudStackNetwork net = findNetwork(zone);
-// CloudStackIpAddress resp = getApi().associateIpAddress(null, null, null, "0036952d-48df-4422-9fd0-94b0885e18cb");
- CloudStackIpAddress resp = getApi().associateIpAddress(zone.getId(), caller.getName(), caller.getDomainId(), net != null ? net.getId():null);
- ec2Address.setAssociatedInstanceId(resp.getId());
-
- if (resp.getIpAddress() == null) {
- List<CloudStackIpAddress> addrList = getApi().listPublicIpAddresses(null, null, null, null, null, null, null, null, null);
- if (addrList != null && addrList.size() > 0) {
- for (CloudStackIpAddress addr: addrList) {
- if (addr.getId().equalsIgnoreCase(resp.getId())) {
- ec2Address.setIpAddress(addr.getIpAddress());
- }
- }
- }
- } else {
- ec2Address.setIpAddress(resp.getIpAddress());
- }
-
- return ec2Address;
- } catch(Exception e) {
- logger.error( "EC2 AllocateAddress - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * List of templates available. We only support the imageSet version of this call or when no search parameters are passed
- * which results in asking for all templates.
- *
- * @param request
- * @return
- */
- public EC2DescribeImagesResponse describeImages(EC2DescribeImages request)
- {
- EC2DescribeImagesResponse images = new EC2DescribeImagesResponse();
-
- try {
- String[] templateIds = request.getImageSet();
-
- if ( 0 == templateIds.length ) {
- return listTemplates(null, images);
- }
- for (String s : templateIds) {
- images = listTemplates(s, images);
- }
- return images;
-
- } catch( Exception e ) {
- logger.error( "EC2 DescribeImages - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * Create a template
- * Amazon API just gives us the instanceId to create the template from.
- * But our createTemplate function requires the volumeId and osTypeId.
- * So to get that we must make the following sequence of cloud API calls:
- * 1) listVolumes&virtualMachineId= -- gets the volumeId
- * 2) listVirtualMachinees&id= -- gets the templateId
- * 3) listTemplates&id= -- gets the osTypeId
- *
- * If we have to start and stop the VM in question then this function is
- * going to take a long time to complete.
- *
- * @param request
- * @return
- */
- public EC2CreateImageResponse createImage(EC2CreateImage request)
- {
- EC2CreateImageResponse response = null;
- boolean needsRestart = false;
- String volumeId = null;
-
- try {
- // [A] Creating a template from a VM volume should be from the ROOT volume
- // Also for this to work the VM must be in a Stopped state so we 'reboot' it if its not
- EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
- volumes = listVolumes( null, request.getInstanceId(), volumes, null );
- EC2Volume[] volSet = volumes.getVolumeSet();
- for (EC2Volume vol : volSet) {
- if (vol.getType().equalsIgnoreCase( "ROOT" )) {
- String vmState = vol.getVMState();
- if (vmState.equalsIgnoreCase( "running" ) || vmState.equalsIgnoreCase( "starting" )) {
- needsRestart = true;
- if (!stopVirtualMachine( request.getInstanceId() ))
- throw new EC2ServiceException(ClientError.IncorrectState, "CreateImage - instance must be in a stopped state");
- }
- volumeId = vol.getId();
- break;
- }
- }
-
- // [B] The parameters must be in sorted order for proper signature generation
- EC2DescribeInstancesResponse instances = new EC2DescribeInstancesResponse();
- instances = lookupInstances( request.getInstanceId(), instances, null );
- EC2Instance[] instanceSet = instances.getInstanceSet();
- String templateId = instanceSet[0].getTemplateId();
-
- EC2DescribeImagesResponse images = new EC2DescribeImagesResponse();
- images = listTemplates( templateId, images );
- EC2Image[] imageSet = images.getImageSet();
- String osTypeId = imageSet[0].getOsTypeId();
-
- CloudStackTemplate resp = getApi().createTemplate((request.getDescription() == null ? "" : request.getDescription()), request.getName(),
- osTypeId, null, null, null, null, null, null, volumeId);
- if (resp == null || resp.getId() == null) {
- throw new EC2ServiceException(ServerError.InternalError, "An upexpected error occurred.");
- }
-
- //if template was created succesfully, create the new image response
- response = new EC2CreateImageResponse();
- response.setId(resp.getId());
-
- // [C] If we stopped the virtual machine now we need to restart it
- if (needsRestart) {
- if (!startVirtualMachine( request.getInstanceId() ))
- throw new EC2ServiceException(ServerError.InternalError,
- "CreateImage - restarting instance " + request.getInstanceId() + " failed");
- }
- return response;
-
- } catch( Exception e ) {
- logger.error( "EC2 CreateImage - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * Register a template
- *
- * @param request
- * @return
- */
- public EC2CreateImageResponse registerImage(EC2RegisterImage request)
- {
- try {
- CloudStackAccount caller = getCurrentAccount();
- if (null == request.getName())
- throw new EC2ServiceException(ClientError.Unsupported, "Missing parameter - name");
-
- List<CloudStackTemplate> templates = getApi().registerTemplate((request.getDescription() == null ? request.getName() : request.getDescription()),
- request.getFormat(), request.getHypervisor(), request.getName(), toOSTypeId(request.getOsTypeName()), request.getLocation(),
- toZoneId(request.getZoneName(), null), null, null, null, null, null, null, null, null, null);
- if (templates != null) {
- // technically we will only ever register a single template...
- for (CloudStackTemplate template : templates) {
- if (template != null && template.getId() != null) {
- EC2CreateImageResponse image = new EC2CreateImageResponse();
- image.setId(template.getId().toString());
- return image;
- }
- }
- }
- return null;
- } catch( Exception e ) {
- logger.error( "EC2 RegisterImage - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * Deregister a template(image)
- * Our implementation is different from Amazon in that we do delete the template
- * when we deregister it. The cloud API has not deregister call.
- *
- * @param image
- * @return
- */
- public boolean deregisterImage( EC2Image image )
- {
- try {
- CloudStackInfoResponse resp = getApi().deleteTemplate(image.getId(), null);
- return resp.getSuccess();
- } catch( Exception e ) {
- logger.error( "EC2 DeregisterImage - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * list instances
- *
- * @param request
- * @return
- */
- public EC2DescribeInstancesResponse describeInstances(EC2DescribeInstances request ) {
- try {
- EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
- return listVirtualMachines( request.getInstancesSet(), request.getFilterSet(),
- getResourceTags(tagKeyValueSet));
- } catch( Exception e ) {
- logger.error( "EC2 DescribeInstances - " ,e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * list Zones
- *
- * @param request
- * @return
- */
- public EC2DescribeAvailabilityZonesResponse handleRequest(EC2DescribeAvailabilityZones request) {
- try {
- EC2DescribeAvailabilityZonesResponse availableZones = listZones(request.getZoneSet(), null);
- EC2AvailabilityZonesFilterSet azfs = request.getFilterSet();
- if ( null == azfs )
- return availableZones;
- else {
- List<String> matchedAvailableZones = azfs.evaluate(availableZones);
- if (matchedAvailableZones.isEmpty())
- return new EC2DescribeAvailabilityZonesResponse();
- return listZones(matchedAvailableZones.toArray(new String[0]), null);
- }
- } catch( EC2ServiceException error ) {
- logger.error( "EC2 DescribeAvailabilityZones - ", error);
- throw error;
-
- } catch( Exception e ) {
- logger.error( "EC2 DescribeAvailabilityZones - " ,e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * list volumes
- *
- * @param request
- * @return
- */
- public EC2DescribeVolumesResponse handleRequest( EC2DescribeVolumes request ) {
- EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
- EC2VolumeFilterSet vfs = request.getFilterSet();
- EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
- try {
- String[] volumeIds = request.getVolumeSet();
- if ( 0 == volumeIds.length ){
- volumes = listVolumes( null, null, volumes, getResourceTags(tagKeyValueSet) );
- } else {
- for (String s : volumeIds)
- volumes = listVolumes(s, null, volumes, getResourceTags(tagKeyValueSet) );
- }
-
- if ( null == vfs )
- return volumes;
- else return vfs.evaluate( volumes );
- } catch( Exception e ) {
- logger.error( "EC2 DescribeVolumes - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * Attach a volume to an instance
- *
- * @param request
- * @return
- */
- public EC2Volume attachVolume( EC2Volume request ) {
- try {
- request.setDeviceId(mapDeviceToCloudDeviceId(request.getDevice()));
- EC2Volume resp = new EC2Volume();
-
- CloudStackVolume vol = getApi().attachVolume(request.getId(), request.getInstanceId(), request.getDeviceId());
- if(vol != null) {
- resp.setAttached(vol.getAttached());
- resp.setCreated(vol.getCreated());
- resp.setDevice(request.getDevice());
- resp.setDeviceId(vol.getDeviceId());
- resp.setHypervisor(vol.getHypervisor());
- resp.setId(vol.getId());
- resp.setInstanceId(vol.getVirtualMachineId());
- resp.setSize(vol.getSize());
- resp.setSnapshotId(vol.getSnapshotId());
- resp.setState(vol.getState());
- resp.setType(vol.getVolumeType());
- resp.setVMState(vol.getVirtualMachineState());
- resp.setZoneName(vol.getZoneName());
- return resp;
- }
- throw new EC2ServiceException( ServerError.InternalError, "An unexpected error occurred." );
- } catch( Exception e ) {
- logger.error( "EC2 AttachVolume 2 - ", e);
- throw new EC2ServiceException( ServerError.InternalError, e.getMessage() != null ? e.getMessage() : e.toString());
- }
- }
-
- /**
- * Detach a volume from an instance
- *
- * @param request
- * @return
- */
- public EC2Volume detachVolume(EC2Volume request) {
- try {
- CloudStackVolume vol = getApi().detachVolume(null, request.getId(), null);
- EC2Volume resp = new EC2Volume();
-
- if(vol != null) {
- resp.setAttached(vol.getAttached());
- resp.setCreated(vol.getCreated());
- resp.setDevice(request.getDevice());
- resp.setDeviceId(vol.getDeviceId());
- resp.setHypervisor(vol.getHypervisor());
- resp.setId(vol.getId());
- resp.setInstanceId(vol.getVirtualMachineId());
- resp.setSize(vol.getSize());
- resp.setSnapshotId(vol.getSnapshotId());
- resp.setState(vol.getState());
- resp.setType(vol.getVolumeType());
- resp.setVMState(vol.getVirtualMachineState());
- resp.setZoneName(vol.getZoneName());
- return resp;
- }
-
- throw new EC2ServiceException( ServerError.InternalError, "An unexpected error occurred." );
- } catch( Exception e ) {
- logger.error( "EC2 DetachVolume - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * Create a volume
- *
- * @param request
- * @return
- */
- public EC2Volume createVolume( EC2CreateVolume request ) {
- try {
-
- CloudStackAccount caller = getCurrentAccount();
- // -> put either snapshotid or diskofferingid on the request
- String snapshotId = request.getSnapshotId();
- Long size = request.getSize();
- String diskOfferingId = null;
-
- if (snapshotId == null) {
- List<CloudStackDiskOffering> disks = getApi().listDiskOfferings(null, null, null, null);
- for (CloudStackDiskOffering offer : disks) {
- if (offer.isCustomized()) {
- diskOfferingId = offer.getId();
- }
- }
- if (diskOfferingId == null) throw new EC2ServiceException(ServerError.InternalError, "No Customize Disk Offering Found");
- }
+ snapshots.addSnapshot(shot);
+ }
+ return snapshots;
+ }
-// // -> no volume name is given in the Amazon request but is required in the cloud API
- CloudStackVolume vol = getApi().createVolume(UUID.randomUUID().toString(), null, diskOfferingId, null, size, snapshotId, toZoneId(request.getZoneName(), null));
- if (vol != null) {
- EC2Volume resp = new EC2Volume();
- resp.setAttached(vol.getAttached());
- resp.setCreated(vol.getCreated());
-// resp.setDevice();
- resp.setDeviceId(vol.getDeviceId());
- resp.setHypervisor(vol.getHypervisor());
- resp.setId(vol.getId());
- resp.setInstanceId(vol.getVirtualMachineId());
- resp.setSize(vol.getSize());
- resp.setSnapshotId(vol.getSnapshotId());
- resp.setState(vol.getState());
- resp.setType(vol.getVolumeType());
- resp.setVMState(vol.getVirtualMachineState());
- resp.setZoneName(vol.getZoneName());
- return resp;
- }
- return null;
- } catch( Exception e ) {
- logger.error( "EC2 CreateVolume - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
-
- /**
- * Delete a volume
- *
- * @param request
- * @return
- */
- public EC2Volume deleteVolume( EC2Volume request ) {
- try {
- CloudStackInfoResponse resp = getApi().deleteVolume(request.getId());
- if(resp != null) {
- request.setState("deleted");
- return request;
- }
-
- throw new EC2ServiceException(ServerError.InternalError, "An unexpected error occurred.");
- } catch( Exception e ) {
- logger.error( "EC2 DeleteVolume 2 - ", e);
- throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
- }
- }
+ // handlers
/**
- * Create/Delete tags
- *
- * @param request
+ * return password data from the instance
+ *
+ * @param instanceId
+ * @return
+ */
+ public EC2PasswordData getPasswordData(String instanceId) {
+ try {
+ CloudStackPasswordData resp = getApi().getVMPassword(instanceId);
+ EC2PasswordData passwdData = new EC2PasswordData();
+ if (resp != null) {
+ passwdData.setInstanceId(instanceId);
+ passwdData.setEncryptedPassword(resp.getEncryptedpassword());
+ }
+ return passwdData;
+ } catch(Exception e) {
+ logger.error("EC2 GetPasswordData - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+ /**
+ * Lists SSH KeyPairs on the systme
+ *
+ * @param request
+ * @return
+ */
+ public EC2DescribeKeyPairsResponse describeKeyPairs( EC2DescribeKeyPairs request ) {
+ try {
+ EC2KeyPairFilterSet filterSet = request.getKeyFilterSet();
+ String[] keyNames = request.getKeyNames();
+ List<CloudStackKeyPair> keyPairs = getApi().listSSHKeyPairs(null, null, null);
+ List<EC2SSHKeyPair> keyPairsList = new ArrayList<EC2SSHKeyPair>();
+
+ if (keyPairs != null) {
+ // Let's trim the list of keypairs to only the ones listed in keyNames
+ List<CloudStackKeyPair> matchedKeyPairs = new ArrayList<CloudStackKeyPair>();
+ if (keyNames != null && keyNames.length > 0) {
+ for (CloudStackKeyPair keyPair : keyPairs) {
+ boolean matched = false;
+ for (String keyName : keyNames) {
+ if (keyPair.getName().equalsIgnoreCase(keyName)) {
+ matched = true;
+ break;
+ }
+ }
+ if (matched) {
+ matchedKeyPairs.add(keyPair);
+ }
+ }
+ if (matchedKeyPairs.isEmpty()) {
+ throw new EC2ServiceException(ServerError.InternalError, "No matching keypairs found");
+ }
+ }else{
+ matchedKeyPairs = keyPairs;
+ }
+
+
+ // this should be reworked... converting from CloudStackKeyPairResponse to EC2SSHKeyPair is dumb
+ for (CloudStackKeyPair respKeyPair: matchedKeyPairs) {
+ EC2SSHKeyPair ec2KeyPair = new EC2SSHKeyPair();
+ ec2KeyPair.setFingerprint(respKeyPair.getFingerprint());
+ ec2KeyPair.setKeyName(respKeyPair.getName());
+ ec2KeyPair.setPrivateKey(respKeyPair.getPrivatekey());
+ keyPairsList.add(ec2KeyPair);
+ }
+ }
+ return filterSet.evaluate(keyPairsList);
+ } catch(Exception e) {
+ logger.error("EC2 DescribeKeyPairs - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * Delete SSHKeyPair
+ *
+ * @param request
+ * @return
+ */
+ public boolean deleteKeyPair( EC2DeleteKeyPair request ) {
+ try {
+ CloudStackInfoResponse resp = getApi().deleteSSHKeyPair(request.getKeyName(), null, null);
+ if (resp == null) {
+ throw new Exception("Ivalid CloudStack API response");
+ }
+
+ return resp.getSuccess();
+ } catch(Exception e) {
+ logger.error("EC2 DeleteKeyPair - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * Create SSHKeyPair
+ *
+ * @param request
+ * @return
+ */
+ public EC2SSHKeyPair createKeyPair(EC2CreateKeyPair request) {
+ try {
+ CloudStackKeyPair resp = getApi().createSSHKeyPair(request.getKeyName(), null, null);
+ if (resp == null) {
+ throw new Exception("Ivalid CloudStack API response");
+ }
+
+ EC2SSHKeyPair response = new EC2SSHKeyPair();
+ response.setFingerprint(resp.getFingerprint());
+ response.setKeyName(resp.getName());
+ response.setPrivateKey(resp.getPrivatekey());
+
+ return response;
+ } catch (Exception e) {
+ logger.error("EC2 CreateKeyPair - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * Import an existing SSH KeyPair
+ *
+ * @param request
+ * @return
+ */
+ public EC2SSHKeyPair importKeyPair( EC2ImportKeyPair request ) {
+ try {
+ CloudStackKeyPair resp = getApi().registerSSHKeyPair(request.getKeyName(), request.getPublicKeyMaterial());
+ if (resp == null) {
+ throw new Exception("Ivalid CloudStack API response");
+ }
+
+ EC2SSHKeyPair response = new EC2SSHKeyPair();
+ response.setFingerprint(resp.getFingerprint());
+ response.setKeyName(resp.getName());
+ response.setPrivateKey(resp.getPrivatekey());
+
+ return response;
+ } catch (Exception e) {
+ logger.error("EC2 ImportKeyPair - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * list ip addresses that have been allocated
+ *
+ * @param request
+ * @return
+ */
+ public EC2DescribeAddressesResponse describeAddresses( EC2DescribeAddresses request ) {
+ try {
+ List<CloudStackIpAddress> addrList = getApi().listPublicIpAddresses(null, null, null, null, null, null, null, null, null);
+
+ EC2AddressFilterSet filterSet = request.getFilterSet();
+ List<EC2Address> addressList = new ArrayList<EC2Address>();
+ if (addrList != null && addrList.size() > 0) {
+ for (CloudStackIpAddress addr: addrList) {
+ // remember, if no filters are set, request.inPublicIpSet always returns true
+ if (request.inPublicIpSet(addr.getIpAddress())) {
+ EC2Address ec2Address = new EC2Address();
+ ec2Address.setIpAddress(addr.getIpAddress());
+ if (addr.getVirtualMachineId() != null)
+ ec2Address.setAssociatedInstanceId(addr.getVirtualMachineId().toString());
+ addressList.add(ec2Address);
+ }
+ }
+ }
+
+ return filterSet.evaluate(addressList);
+ } catch(Exception e) {
+ logger.error("EC2 DescribeAddresses - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ }
+
+ /**
+ * release an IP Address
+ *
+ * @param request
+ * @return
+ */
+ public boolean releaseAddress(EC2ReleaseAddress request) {
+ try {
+ CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
+ CloudStackInfoResponse resp = getApi().disassociateIpAddress(cloudIp.getId());
+ if (resp != null) {
+ return resp.getSuccess();
+ }
+ } catch(Exception e) {
+ logger.error("EC2 ReleaseAddress - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
+ }
+ return false;
+ }
+
+ /**
+ * Associate an address with an instance
+ *
+ * @param request
+ * @return
+ */
+ public boolean associateAddress( EC2AssociateAddress request ) {
+ try {
+ CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
+ CloudStackUserVm cloudVm = getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null).get(0);
+
+ CloudStackInfoResponse resp = getApi().enableStaticNat(cloudIp.getId(), cloudVm.getId());
+ if (resp != null) {
+ return resp.getSuccess();
+ }
+ } catch(Exception e) {
+ logger.error( "EC2 AssociateAddress - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ return false;
+ }
+
+ /**
+ * Disassociate an address from an instance
+ *
+ * @param request
+ * @return
+ */
+ public boolean disassociateAddress( EC2DisassociateAddress request ) {
+ try {
+ CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
+ CloudStackInfoResponse resp = getApi().disableStaticNat(cloudIp.getId());
+ if (resp != null) {
+ return resp.getSuccess();
+ }
+ } catch(Exception e) {
+ logger.error( "EC2 DisassociateAddress - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ return false;
+ }
+
+ /**
+ * Allocate an address
+ *
+ * @param request
+ * @return
+ */
+ public EC2Address allocateAddress()
+ {
+ try {
+ EC2Address ec2Address = new EC2Address();
+ // this gets our networkId
+ CloudStackAccount caller = getCurrentAccount();
+
+ CloudStackZone zone = findZone();
+ CloudStackNetwork net = findNetwork(zone);
+// CloudStackIpAddress resp = getApi().associateIpAddress(null, null, null, "0036952d-48df-4422-9fd0-94b0885e18cb");
+ CloudStackIpAddress resp = getApi().associateIpAddress(zone.getId(), caller.getName(), caller.getDomainId(), net != null ? net.getId():null);
+ ec2Address.setAssociatedInstanceId(resp.getId());
+
+ if (resp.getIpAddress() == null) {
+ List<CloudStackIpAddress> addrList = getApi().listPublicIpAddresses(null, null, null, null, null, null, null, null, null);
+ if (addrList != null && addrList.size() > 0) {
+ for (CloudStackIpAddress addr: addrList) {
+ if (addr.getId().equalsIgnoreCase(resp.getId())) {
+ ec2Address.setIpAddress(addr.getIpAddress());
+ }
+ }
+ }
+ } else {
+ ec2Address.setIpAddress(resp.getIpAddress());
+ }
+
+ return ec2Address;
+ } catch(Exception e) {
+ logger.error( "EC2 AllocateAddress - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * List of templates available. We only support the imageSet version of this call or when no search parameters are passed
+ * which results in asking for all templates.
+ *
+ * @param request
+ * @return
+ */
+ public EC2DescribeImagesResponse describeImages(EC2DescribeImages request)
+ {
+ EC2DescribeImagesResponse images = new EC2DescribeImagesResponse();
+
+ try {
+ String[] templateIds = request.getImageSet();
+
+ if ( 0 == templateIds.length ) {
+ return listTemplates(null, images);
+ }
+ for (String s : templateIds) {
+ images = listTemplates(s, images);
+ }
+ return images;
+
+ } catch( Exception e ) {
+ logger.error( "EC2 DescribeImages - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * Create a template
+ * Amazon API just gives us the instanceId to create the template from.
+ * But our createTemplate function requires the volumeId and osTypeId.
+ * So to get that we must make the following sequence of cloud API calls:
+ * 1) listVolumes&virtualMachineId= -- gets the volumeId
+ * 2) listVirtualMachinees&id= -- gets the templateId
+ * 3) listTemplates&id= -- gets the osTypeId
+ *
+ * If we have to start and stop the VM in question then this function is
+ * going to take a long time to complete.
+ *
+ * @param request
+ * @return
+ */
+ public EC2CreateImageResponse createImage(EC2CreateImage request)
+ {
+ EC2CreateImageResponse response = null;
+ boolean needsRestart = false;
+ String volumeId = null;
+
+ try {
+ // [A] Creating a template from a VM volume should be from the ROOT volume
+ // Also for this to work the VM must be in a Stopped state so we 'reboot' it if its not
+ EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
+ volumes = listVolumes( null, request.getInstanceId(), volumes, null );
+ EC2Volume[] volSet = volumes.getVolumeSet();
+ for (EC2Volume vol : volSet) {
+ if (vol.getType().equalsIgnoreCase( "ROOT" )) {
+ String vmState = vol.getVMState();
+ if (vmState.equalsIgnoreCase( "running" ) || vmState.equalsIgnoreCase( "starting" )) {
+ needsRestart = true;
+ if (!stopVirtualMachine( request.getInstanceId() ))
+ throw new EC2ServiceException(ClientError.IncorrectState, "CreateImage - instance must be in a stopped state");
+ }
+ volumeId = vol.getId();
+ break;
+ }
+ }
+
+ // [B] The parameters must be in sorted order for proper signature generation
+ EC2DescribeInstancesResponse instances = new EC2DescribeInstancesResponse();
+ instances = lookupInstances( request.getInstanceId(), instances, null );
+ EC2Instance[] instanceSet = instances.getInstanceSet();
+ String templateId = instanceSet[0].getTemplateId();
+
+ EC2DescribeImagesResponse images = new EC2DescribeImagesResponse();
+ images = listTemplates( templateId, images );
+ EC2Image[] imageSet = images.getImageSet();
+ String osTypeId = imageSet[0].getOsTypeId();
+
+ CloudStackTemplate resp = getApi().createTemplate((request.getDescription() == null ? "" : request.getDescription()), request.getName(),
+ osTypeId, null, null, null, null, null, null, volumeId);
+ if (resp == null || resp.getId() == null) {
+ throw new EC2ServiceException(ServerError.InternalError, "An upexpected error occurred.");
+ }
+
+ //if template was created succesfully, create the new image response
+ response = new EC2CreateImageResponse();
+ response.setId(resp.getId());
+
+ // [C] If we stopped the virtual machine now we need to restart it
+ if (needsRestart) {
+ if (!startVirtualMachine( request.getInstanceId() ))
+ throw new EC2ServiceException(ServerError.InternalError,
+ "CreateImage - restarting instance " + request.getInstanceId() + " failed");
+ }
+ return response;
+
+ } catch( Exception e ) {
+ logger.error( "EC2 CreateImage - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * Register a template
+ *
+ * @param request
+ * @return
+ */
+ public EC2CreateImageResponse registerImage(EC2RegisterImage request)
+ {
+ try {
+ CloudStackAccount caller = getCurrentAccount();
+ if (null == request.getName())
+ throw new EC2ServiceException(ClientError.Unsupported, "Missing parameter - name");
+
+ List<CloudStackTemplate> templates = getApi().registerTemplate((request.getDescription() == null ? request.getName() : request.getDescription()),
+ request.getFormat(), request.getHypervisor(), request.getName(), toOSTypeId(request.getOsTypeName()), request.getLocation(),
+ toZoneId(request.getZoneName(), null), null, null, null, null, null, null, null, null, null);
+ if (templates != null) {
+ // technically we will only ever register a single template...
+ for (CloudStackTemplate template : templates) {
+ if (template != null && template.getId() != null) {
+ EC2CreateImageResponse image = new EC2CreateImageResponse();
+ image.setId(template.getId().toString());
+ return image;
+ }
+ }
+ }
+ return null;
+ } catch( Exception e ) {
+ logger.error( "EC2 RegisterImage - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * Deregister a template(image)
+ * Our implementation is different from Amazon in that we do delete the template
+ * when we deregister it. The cloud API has not deregister call.
+ *
+ * @param image
+ * @return
+ */
+ public boolean deregisterImage( EC2Image image )
+ {
+ try {
+ CloudStackInfoResponse resp = getApi().deleteTemplate(image.getId(), null);
+ return resp.getSuccess();
+ } catch( Exception e ) {
+ logger.error( "EC2 DeregisterImage - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * list instances
+ *
+ * @param request
+ * @return
+ */
+ public EC2DescribeInstancesResponse describeInstances(EC2DescribeInstances request ) {
+ try {
+ EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
+ return listVirtualMachines( request.getInstancesSet(), request.getFilterSet(),
+ getResourceTags(tagKeyValueSet));
+ } catch( Exception e ) {
+ logger.error( "EC2 DescribeInstances - " ,e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * list Zones
+ *
+ * @param request
+ * @return
+ */
+ public EC2DescribeAvailabilityZonesResponse handleRequest(EC2DescribeAvailabilityZones request) {
+ try {
+ EC2DescribeAvailabilityZonesResponse availableZones = listZones(request.getZoneSet(), null);
+ EC2AvailabilityZonesFilterSet azfs = request.getFilterSet();
+ if ( null == azfs )
+ return availableZones;
+ else {
+ List<String> matchedAvailableZones = azfs.evaluate(availableZones);
+ if (matchedAvailableZones.isEmpty())
+ return new EC2DescribeAvailabilityZonesResponse();
+ return listZones(matchedAvailableZones.toArray(new String[0]), null);
+ }
+ } catch( EC2ServiceException error ) {
+ logger.error( "EC2 DescribeAvailabilityZones - ", error);
+ throw error;
+
+ } catch( Exception e ) {
+ logger.error( "EC2 DescribeAvailabilityZones - " ,e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * list volumes
+ *
+ * @param request
+ * @return
+ */
+ public EC2DescribeVolumesResponse handleRequest( EC2DescribeVolumes request ) {
+ EC2DescribeVolumesResponse volumes = new EC2DescribeVolumesResponse();
+ EC2VolumeFilterSet vfs = request.getFilterSet();
+ EC2TagKeyValue[] tagKeyValueSet = request.getResourceTagSet();
+ try {
+ String[] volumeIds = request.getVolumeSet();
+ if ( 0 == volumeIds.length ){
+ volumes = listVolumes( null, null, volumes, getResourceTags(tagKeyValueSet) );
+ } else {
+ for (String s : volumeIds)
+ volumes = listVolumes(s, null, volumes, getResourceTags(tagKeyValueSet) );
+ }
+
+ if ( null == vfs )
+ return volumes;
+ else return vfs.evaluate( volumes );
+ } catch( Exception e ) {
+ logger.error( "EC2 DescribeVolumes - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * Attach a volume to an instance
+ *
+ * @param request
+ * @return
+ */
+ public EC2Volume attachVolume( EC2Volume request ) {
+ try {
+ request.setDeviceId(mapDeviceToCloudDeviceId(request.getDevice()));
+ EC2Volume resp = new EC2Volume();
+
+ CloudStackVolume vol = getApi().attachVolume(request.getId(), request.getInstanceId(), request.getDeviceId());
+ if(vol != null) {
+ resp.setAttached(vol.getAttached());
+ resp.setCreated(vol.getCreated());
+ resp.setDevice(request.getDevice());
+ resp.setDeviceId(vol.getDeviceId());
+ resp.setHypervisor(vol.getHypervisor());
+ resp.setId(vol.getId());
+ resp.setInstanceId(vol.getVirtualMachineId());
+ resp.setSize(vol.getSize());
+ resp.setSnapshotId(vol.getSnapshotId());
+ resp.setState(vol.getState());
+ resp.setType(vol.getVolumeType());
+ resp.setVMState(vol.getVirtualMachineState());
+ resp.setZoneName(vol.getZoneName());
+ return resp;
+ }
+ throw new EC2ServiceException( ServerError.InternalError, "An unexpected error occurred." );
+ } catch( Exception e ) {
+ logger.error( "EC2 AttachVolume 2 - ", e);
+ throw new EC2ServiceException( ServerError.InternalError, e.getMessage() != null ? e.getMessage() : e.toString());
+ }
+ }
+
+ /**
+ * Detach a volume from an instance
+ *
+ * @param request
+ * @return
+ */
+ public EC2Volume detachVolume(EC2Volume request) {
+ try {
+ CloudStackVolume vol = getApi().detachVolume(null, request.getId(), null);
+ EC2Volume resp = new EC2Volume();
+
+ if(vol != null) {
+ resp.setAttached(vol.getAttached());
+ resp.setCreated(vol.getCreated());
+ resp.setDevice(request.getDevice());
+ resp.setDeviceId(vol.getDeviceId());
+ resp.setHypervisor(vol.getHypervisor());
+ resp.setId(vol.getId());
+ resp.setInstanceId(vol.getVirtualMachineId());
+ resp.setSize(vol.getSize());
+ resp.setSnapshotId(vol.getSnapshotId());
+ resp.setState(vol.getState());
+ resp.setType(vol.getVolumeType());
+ resp.setVMState(vol.getVirtualMachineState());
+ resp.setZoneName(vol.getZoneName());
+ return resp;
+ }
+
+ throw new EC2ServiceException( ServerError.InternalError, "An unexpected error occurred." );
+ } catch( Exception e ) {
+ logger.error( "EC2 DetachVolume - ", e);
+ throw new EC2ServiceException(ServerError.InternalError, e.getMessage() != null ? e.getMessage() : "An unexpected error occurred.");
+ }
+ }
+
+ /**
+ * Create a volume
+ *
+ * @param request
+ * @return
+ */
+ public EC2Volume createVolume( EC2CreateVolume request ) {
+ try {
+
+ CloudStackAccount caller = getCurrentAccount();
+ // -> put either snapshotid or diskofferingid on the request
+ String snapshotId = request.getSnapshotId();
+ Long size = request.getSize();
+ String diskOfferingId = null;
+
+ if (snapshotId == null) {
+ List<CloudStackDiskOffering> disks = getApi().listDiskOfferings(null, null, null, null);
+ for (CloudStackDiskOffering offer : disks) {
+ if (offer.isCustomized()) {
+ diskOfferingId = offer.ge
<TRUNCATED>