mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
making the logic more robust, testing more corner cases, improving efficiency and changing the schema
This commit is contained in:
parent
9c80911e52
commit
3752a4eb31
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user