making the logic more robust, testing more corner cases, improving efficiency and changing the schema

This commit is contained in:
root 2010-10-28 09:42:17 -07:00 committed by abhishek
parent 9c80911e52
commit 3752a4eb31
9 changed files with 107 additions and 73 deletions

View File

@ -36,6 +36,9 @@ public class CertificateVO {
@Column(name="certificate",length=65535)
private String certificate;
@Column(name="updated")
private String updated;
public CertificateVO() {}
public Long getId() {
@ -48,4 +51,12 @@ public class CertificateVO {
public void setCertificate(String certificate) {
this.certificate = certificate;
}
public String getUpdated(){
return this.updated;
}
public void setUpdated(String updated){
this.updated = updated;
}
}

View File

@ -22,5 +22,5 @@ import com.cloud.certificate.CertificateVO;
import com.cloud.utils.db.GenericDao;
public interface CertificateDao extends GenericDao<CertificateVO, Long> {
public Long persistCustomCertToDb(String certPath);
public Long persistCustomCertToDb(String certPath, CertificateVO cert);
}

View File

@ -24,7 +24,7 @@ public class CertificateDaoImpl extends GenericDaoBase<CertificateVO, Long> imp
}
@Override
public Long persistCustomCertToDb(String certPath){
public Long persistCustomCertToDb(String certPath, CertificateVO cert){
BufferedInputStream f = null;
String certStr = null;
try
@ -33,10 +33,10 @@ public class CertificateDaoImpl extends GenericDaoBase<CertificateVO, Long> imp
f = new BufferedInputStream(new FileInputStream(certPath));
f.read(buffer);
certStr = new String(buffer);
CertificateVO certRec = new CertificateVO();
certRec.setCertificate(certStr);
this.persist(certRec);
return certRec.getId();
cert.setCertificate(certStr);
cert.setUpdated("t");
update(cert.getId(),cert);
return cert.getId();
} catch (FileNotFoundException e) {
s_logger.warn("Unable to read the certificate: "+e);
return new Long(0);

View File

@ -80,7 +80,7 @@ public abstract class BaseCmd {
public static final int NET_DELETE_LB_RULE_ERROR = 567;
public static final int NET_CONFLICT_LB_RULE_ERROR = 568;
public static final int NET_LIST_ERROR = 570;
public static final int CUSTOM_CERT_UPDATE_ERROR = 571;
public static final int STORAGE_RESOURCE_IN_USE = 580;
public static final DateFormat INPUT_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

View File

@ -23,7 +23,7 @@ import com.cloud.api.ApiConstants;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.StatusResponse;
import com.cloud.api.response.CustomCertificateResponse;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
@ -40,14 +40,12 @@ public class UploadCustomCertificateCmd extends BaseAsyncCmd {
return path;
}
@Override @SuppressWarnings("unchecked")
public StatusResponse getResponse() {
Boolean status = (Boolean)getResponseObject();
StatusResponse response = new StatusResponse();
response.setStatus(status);
response.setResponseName(getName());
public CustomCertificateResponse getResponse() {
String updatedCpIdList = (String)getResponseObject();
CustomCertificateResponse response = new CustomCertificateResponse();
response.setResponseName(s_name);
response.setUpdatedConsoleProxyIdList(updatedCpIdList);
return response;
}

View File

@ -2446,10 +2446,9 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
public boolean applyCustomCertToNewProxy(StartupProxyCommand cmd){
//this is the case for updating cust cert on each new starting proxy, if such cert exists
//get cert from db
List<CertificateVO> certList = _certDao.listAll();
CertificateVO cert = _certDao.listAll().get(0);
if(certList.size()>0){
CertificateVO cert = certList.get(0);//there will only be 1 cert in db for now
if(cert.getUpdated().equals("t")){
String certStr = cert.getCertificate();
long proxyVmId = (cmd).getProxyVmId();
ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
@ -2466,14 +2465,14 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
long eventId = saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_PROXY_REBOOT, "rebooting console proxy with Id: "+consoleProxy.getId());
rebootProxy(consoleProxy.getId(), eventId);
//when cp reboots, the context will be reinit with the new cert
s_logger.info("Successfully rebooted console proxy resource after custom certificate application");
s_logger.info("Successfully rebooted console proxy resource after custom certificate application for proxy:"+cmd.getProxyVmId());
return true;
}
} catch (AgentUnavailableException e) {
s_logger.warn("Unable to send update certificate command to the console proxy resource", e);
s_logger.warn("Unable to send update certificate command to the console proxy resource for proxy:"+cmd.getProxyVmId(), e);
return false;
} catch (OperationTimedoutException e) {
s_logger.warn("Unable to send update certificate command to the console proxy resource", e);
s_logger.warn("Unable to send update certificate command to the console proxy resource for proxy:"+cmd.getProxyVmId(), e);
return false;
}
}

View File

@ -24,6 +24,8 @@ import java.util.List;
import java.util.Map;
import com.cloud.alert.AlertVO;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.AssignPortForwardingServiceCmd;
import com.cloud.api.commands.CreateDomainCmd;
import com.cloud.api.commands.CreateUserCmd;
import com.cloud.api.commands.DeleteDomainCmd;
@ -1117,5 +1119,5 @@ public interface ManagementServer {
*/
String[] getHypervisors(ListHypervisorsCmd cmd);
boolean uploadCertificate(UploadCustomCertificateCmd cmd) throws ResourceAllocationException;
String uploadCertificate(UploadCustomCertificateCmd cmd) throws ServerApiException;
}

View File

@ -5865,58 +5865,79 @@ public class ManagementServerImpl implements ManagementServer {
return event.getId();
}
@Override
public boolean uploadCertificate(UploadCustomCertificateCmd cmd) throws ResourceAllocationException {
//limit no.of certs uploaded to 1
if(_certDao.listAll().size()>0){
throw new ResourceAllocationException("There is already a custom certificate in the db");
}
String certificatePath = cmd.getPath();
Long certVOId = _certDao.persistCustomCertToDb(certificatePath);//0 implies failure
@Override @DB
public String uploadCertificate(UploadCustomCertificateCmd cmd) throws ServerApiException{
try
{
CertificateVO cert = _certDao.listAll().get(0); //always 1 record in db
if(cert.getUpdated().equals("t")){
if(s_logger.isDebugEnabled())
s_logger.debug("A custom certificate already exists in the DB, will replace it with the new one being uploaded");
}else{
if(s_logger.isDebugEnabled())
s_logger.debug("No custom certificate exists in the DB, will upload a new one");
}
String certificatePath = cmd.getPath();
CertificateVO lockedCert = _certDao.acquire(cert.getId());
Long certVOId = _certDao.persistCustomCertToDb(certificatePath,lockedCert);//0 implies failure
if (certVOId!=null && certVOId!=0)
{
//certficate uploaded to db successfully
//get a list of all Console proxies from the cp table
List<ConsoleProxyVO> cpList = _consoleProxyDao.listAll();
//get a list of all hosts in host table for type cp
List<HostVO> cpHosts = _hostDao.listByType(com.cloud.host.Host.Type.ConsoleProxy);
//create a hashmap for fast lookup
Map<String,Long> hostNameToHostIdMap = new HashMap<String, Long>();
//updated console proxies list
List<ConsoleProxyVO> updatedCpList = new ArrayList<ConsoleProxyVO>();
for(HostVO cpHost : cpHosts){
hostNameToHostIdMap.put(cpHost.getName(), cpHost.getId());
}
for(ConsoleProxyVO cp : cpList)
{
Long cpHostId = hostNameToHostIdMap.get(cp.getName());//there will always be a cphost for a cpvm
//now send a command to each console proxy
UpdateCertificateCommand certCmd = new UpdateCertificateCommand(_certDao.findById(certVOId).getCertificate());
try {
Answer updateCertAns = _agentMgr.send(cpHostId, certCmd);
if(updateCertAns.getResult() == true)
{
//we have the cert copied over on cpvm
long eventId = saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_PROXY_REBOOT, "rebooting console proxy with Id: "+cp.getId());
_consoleProxyMgr.rebootProxy(cp.getId(), eventId);
//when cp reboots, the context will be reinit with the new cert
}
} catch (AgentUnavailableException e) {
s_logger.warn("Unable to send update certificate command to the console proxy resource as agent is unavailable", e);
} catch (OperationTimedoutException e) {
s_logger.warn("Unable to send update certificate command to the console proxy resource as there was a timeout", e);
}
}
return true;
}
else
{
return false;
}
if (certVOId!=null && certVOId!=0)
{
//certficate uploaded to db successfully
//get a list of all Console proxies from the cp table
List<ConsoleProxyVO> cpList = _consoleProxyDao.listAll();
if(cpList.size() == 0){
throw new ServerApiException(BaseCmd.CUSTOM_CERT_UPDATE_ERROR, "Unable to find any console proxies in the system for certificate update");
}
//get a list of all hosts in host table for type cp
List<HostVO> cpHosts = _hostDao.listByType(com.cloud.host.Host.Type.ConsoleProxy);
if(cpHosts.size() == 0){
throw new ServerApiException(BaseCmd.CUSTOM_CERT_UPDATE_ERROR, "Unable to find any console proxy hosts in the system for certificate update");
}
//create a hashmap for fast lookup
Map<String,Long> hostNameToHostIdMap = new HashMap<String, Long>();
//updated console proxies id list
List<Long> updatedCpIdList = new ArrayList<Long>();
for(HostVO cpHost : cpHosts){
hostNameToHostIdMap.put(cpHost.getName(), cpHost.getId());
}
for(ConsoleProxyVO cp : cpList)
{
Long cpHostId = hostNameToHostIdMap.get(cp.getName());
//now send a command to each console proxy
UpdateCertificateCommand certCmd = new UpdateCertificateCommand(_certDao.findById(certVOId).getCertificate());
try {
Answer updateCertAns = _agentMgr.send(cpHostId, certCmd);
if(updateCertAns.getResult() == true)
{
//we have the cert copied over on cpvm
long eventId = saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_PROXY_REBOOT, "rebooting console proxy with Id: "+cp.getId());
_consoleProxyMgr.rebootProxy(cp.getId(), eventId);
//when cp reboots, the context will be reinit with the new cert
if(s_logger.isDebugEnabled())
s_logger.debug("Successfully updated custom certificate on console proxy vm id:"+cp.getId()+" ,console proxy host id:"+cpHostId);
updatedCpIdList.add(cp.getId());
}
} catch (AgentUnavailableException e) {
s_logger.warn("Unable to send update certificate command to the console proxy resource as agent is unavailable for console proxy vm id:"+cp.getId()+" ,console proxy host id:"+cpHostId, e);
} catch (OperationTimedoutException e) {
s_logger.warn("Unable to send update certificate command to the console proxy resource as there was a timeout for console proxy vm id:"+cp.getId()+" ,console proxy host id:"+cpHostId, e);
}
}
_certDao.release(lockedCert.getId());
return ("Updated:"+updatedCpIdList.size()+" out of:"+cpList.size());
}
else
{
return null;
}
} catch (Exception e) {
s_logger.warn("Failed to persist custom certificate to the db");
}
return null;
}
@Override

View File

@ -134,9 +134,12 @@ CREATE TABLE `cloud`.`account_network_ref` (
CREATE TABLE `cloud`.`certificate` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`certificate` text COMMENT 'the actual custom certificate being stored in the db',
`updated` varchar(1) COMMENT 'status of the certificate',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `cloud`.`certificate` (id,certificate,updated) VALUES ('1',null,'f');
CREATE TABLE `cloud`.`nics` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
`instance_id` bigint unsigned NOT NULL COMMENT 'vm instance id',