- Changes to EC2MainServlet to turn down request in enable.ec2.api is 'false'

- runInstances now calls CS to get the matching serviceOffering for the EC2 instanceType
This commit is contained in:
prachi 2012-04-20 17:08:02 -07:00
parent 860aa58540
commit 38fffccb58
6 changed files with 173 additions and 14 deletions

View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 2011 Citrix Systems, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cloud.bridge.persist;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.cloud.bridge.util.ConfigurationHelper;
public class CloudStackDao {
public static final Logger logger = Logger.getLogger(CloudStackDao.class);
private Connection conn = null;
private String dbName = null;
private String dbHost = null;
private String dbUser = null;
private String dbPassword = null;
private String dbPort = null;
public CloudStackDao() {
File propertiesFile = ConfigurationHelper.findConfigurationFile("db.properties");
Properties EC2Prop = null;
if (null != propertiesFile) {
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);
}
dbHost = EC2Prop.getProperty( "db.cloud.host" );
dbName = EC2Prop.getProperty( "db.cloud.name" );
dbUser = EC2Prop.getProperty( "db.cloud.username" );
dbPassword = EC2Prop.getProperty( "db.cloud.password" );
dbPort = EC2Prop.getProperty( "db.cloud.port" );
}
}
public String getConfigValue( String configName ){
String value = null;
try {
openConnection();
PreparedStatement statement = conn.prepareStatement ( "SELECT value FROM `cloud`.`configuration` where name = ?" );
statement.setString( 1, configName );
statement.executeQuery();
ResultSet rs = statement.getResultSet ();
if (rs.next()) {
value = rs.getString(1);
}
}catch (Exception e) {
logger.warn("Failed to access CloudStack DB, got error: ", e);
} finally {
try{
closeConnection();
}catch(SQLException e){
}
}
return value;
}
private void openConnection()
throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
if (null == conn) {
Class.forName( "com.mysql.jdbc.Driver" ).newInstance();
conn = DriverManager.getConnection( "jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName, dbUser, dbPassword );
}
}
private void closeConnection() throws SQLException {
if (null != conn) conn.close();
conn = null;
}
}

View File

@ -9,6 +9,7 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.cloud.bridge.persist.CloudStackDao;
import com.cloud.bridge.persist.dao.UserCredentialsDao;
import com.cloud.bridge.util.ConfigurationHelper;
@ -18,6 +19,8 @@ public class EC2MainServlet extends HttpServlet{
public static final String EC2_REST_SERVLET_PATH="/rest/AmazonEC2/";
public static final String EC2_SOAP_SERVLET_PATH="/services/AmazonEC2/";
public static final String ENABLE_EC2_API="enable.ec2.api";
private static boolean isEC2APIEnabled = false;
/**
* We build the path to where the keystore holding the WS-Security X509 certificates
@ -26,6 +29,13 @@ public class EC2MainServlet extends HttpServlet{
public void init( ServletConfig config ) throws ServletException {
ConfigurationHelper.preConfigureConfigPathFromServletContext(config.getServletContext());
UserCredentialsDao.preCheckTableExistence();
// check if API is enabled
CloudStackDao csDao = new CloudStackDao();
String value = csDao.getConfigValue(ENABLE_EC2_API);
if(value != null){
isEC2APIEnabled = Boolean.valueOf(value);
}
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
@ -37,8 +47,13 @@ public class EC2MainServlet extends HttpServlet{
}
protected void doGetOrPost(HttpServletRequest request, HttpServletResponse response) {
String action = request.getParameter( "Action" );
if(action!=null){
String action = request.getParameter( "Action" );
if(!isEC2APIEnabled){
throw new RuntimeException("EC2 API is disabled.");
}
if(action != null){
//We presume it's a Query/Rest call
try {
RequestDispatcher dispatcher = request.getRequestDispatcher(EC2_REST_SERVLET_PATH);

View File

@ -55,6 +55,7 @@ import com.cloud.stack.models.CloudStackPasswordData;
import com.cloud.stack.models.CloudStackResourceLimit;
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.CloudStackUser;
@ -1285,9 +1286,17 @@ public class EC2Engine {
else
createInstances = request.getMaxCount();
// the mapping stuff
OfferingBundle offer = instanceTypeToOfferBundle( request.getInstanceType());
//find CS service Offering ID
String instanceType = "m1.small";
if(request.getInstanceType() != null){
instanceType = request.getInstanceType();
}
CloudStackServiceOffering svcOffering = getCSServiceOfferingId(instanceType);
if(svcOffering == null){
logger.info("No ServiceOffering found to be defined by name, please contact the administrator "+instanceType );
throw new EC2ServiceException(ClientError.Unsupported, "instanceType: [" + instanceType + "] not found!");
}
// zone stuff
String zoneId = toZoneId(request.getZoneName(), null);
@ -1304,7 +1313,7 @@ public class EC2Engine {
// now actually deploy the vms
for( int i=0; i < createInstances; i++ ) {
CloudStackUserVm resp = getApi().deployVirtualMachine(offer.getServiceOfferingId(),
CloudStackUserVm resp = getApi().deployVirtualMachine(svcOffering.getId(),
request.getTemplateId(), zoneId, null, null, null, null,
null, null, null, request.getKeyName(), null, (network != null ? network.getId() : null),
null, null, request.getSize().longValue(), request.getUserData());
@ -1324,7 +1333,7 @@ public class EC2Engine {
vm.setAccountName(resp.getAccountName());
vm.setDomainId(resp.getDomainId());
vm.setHypervisor(resp.getHypervisor());
vm.setServiceOffering( serviceOfferingIdToInstanceType( offer.getServiceOfferingId()));
vm.setServiceOffering( svcOffering.getName());
instances.addInstance(vm);
countCreated++;
}
@ -1576,6 +1585,36 @@ public class EC2Engine {
return found;
}
/**
*
*/
private CloudStackServiceOffering getCSServiceOfferingId(String instanceType) throws Exception{
try {
if (null == instanceType) instanceType = "m1.small";
List<CloudStackServiceOffering> svcOfferings = getApi().listServiceOfferings(null, null, null, null, null,
null, null);
if(svcOfferings == null || svcOfferings.isEmpty()){
logger.debug("No ServiceOffering found to be defined by name: "+instanceType );
return null;
}
for(CloudStackServiceOffering offering : svcOfferings){
if(instanceType.equalsIgnoreCase(offering.getName())){
return offering;
}
}
return null;
} catch(Exception e) {
logger.error( "listServiceOfferings - ", e);
throw new EC2ServiceException(ServerError.InternalError, e.getMessage());
}
}
/**
* Convert from the Cloud serviceOfferingId to the Amazon instanceType strings based
* on the loaded map.

View File

@ -23,8 +23,8 @@ import com.google.gson.annotations.SerializedName;
*
*/
public class CloudStackServiceOffering {
@SerializedName(ApiConstants.ID)
private Long id;
@SerializedName(ApiConstants.ID)
private String id;
@SerializedName(ApiConstants.CPU_NUMBER)
private Long cpuNumber;
@SerializedName(ApiConstants.CPU_SPEED)
@ -38,7 +38,7 @@ public class CloudStackServiceOffering {
@SerializedName(ApiConstants.DOMAIN)
private String domain;
@SerializedName(ApiConstants.DOMAIN_ID)
private Long domainId;
private String domainId;
@SerializedName(ApiConstants.HOST_TAGS)
private String hostTags;
@SerializedName(ApiConstants.IS_SYSTEM)
@ -68,9 +68,9 @@ public class CloudStackServiceOffering {
/**
* @return the id
*/
public Long getId() {
return id;
}
public String getId() {
return id;
}
/**
* @return the cpuNumber
@ -117,7 +117,7 @@ public class CloudStackServiceOffering {
/**
* @return the domainId
*/
public Long getDomainId() {
public String getDomainId() {
return domainId;
}

View File

@ -98,6 +98,7 @@
<delete dir="${tomcat.home}/webapps/awsapi" />
</target>
<path id="awsapi.classpath">
<path refid="deps.classpath" />
<path refid="thirdparty.classpath" />
<path refid="rampart.classpath" />
<path refid="dist.classpath" />

View File

@ -218,6 +218,7 @@ public enum Config {
ElasticLoadBalancerVmNumVcpu("Advanced", ManagementServer.class, Integer.class, "network.loadbalancer.basiczone.elb.vm.vcpu.num", "1", "Number of VCPU for the elastic load balancer vm", null),
ElasticLoadBalancerVmGcInterval("Advanced", ManagementServer.class, Integer.class, "network.loadbalancer.basiczone.elb.gc.interval.minutes", "30", "Garbage collection interval to destroy unused ELB vms in minutes. Minimum of 5", null),
SortKeyAlgorithm("Advanced", ManagementServer.class, Boolean.class, "sortkey.algorithm", "false", "Sort algorithm for those who use sort key(template, disk offering, service offering, network offering), true means ascending sort while false means descending sort", null),
EnableEC2API("Advanced", ManagementServer.class, Boolean.class, "enable.ec2.api", "false", "enable EC2 API on CloudStack", null),
// Ovm
OvmPublicNetwork("Hidden", ManagementServer.class, String.class, "ovm.public.network.device", null, "Specify the public bridge on host for public network", null),