mirror of https://github.com/apache/cloudstack.git
- 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:
parent
860aa58540
commit
38fffccb58
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Reference in New Issue