mirror of https://github.com/apache/cloudstack.git
Refactor and fix upload certificate error message even though operation is successful
This commit is contained in:
parent
d39664a382
commit
1c71a9b867
|
|
@ -1,88 +1,90 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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 org.apache.cloudstack.api.command.admin.direct.download;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.direct.download.DirectDownloadManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = UploadTemplateDirectDownloadCertificate.APINAME,
|
||||
description = "Upload a certificate for HTTPS direct template download on KVM hosts",
|
||||
responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = true,
|
||||
responseHasSensitiveInfo = true,
|
||||
since = "4.11.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class UploadTemplateDirectDownloadCertificate extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
DirectDownloadManager directDownloadManager;
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(UploadTemplateDirectDownloadCertificate.class);
|
||||
public static final String APINAME = "uploadTemplateDirectDownloadCertificate";
|
||||
|
||||
@Parameter(name = ApiConstants.CERTIFICATE, type = BaseCmd.CommandType.STRING, required = true, length = 65535,
|
||||
description = "SSL certificate")
|
||||
private String certificate;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME , type = BaseCmd.CommandType.STRING, required = true,
|
||||
description = "Name for the uploaded certificate")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.HYPERVISOR, type = BaseCmd.CommandType.STRING, required = true, description = "Hypervisor type")
|
||||
private String hypervisor;
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
if (!hypervisor.equalsIgnoreCase("kvm")) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Currently supporting KVM hosts only");
|
||||
}
|
||||
|
||||
try {
|
||||
directDownloadManager.uploadCertificateToHosts(certificate, name);;
|
||||
setResponseObject(new SuccessResponse(getCommandName()));
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return UploadTemplateDirectDownloadCertificate.APINAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
}
|
||||
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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 org.apache.cloudstack.api.command.admin.direct.download;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.direct.download.DirectDownloadManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = UploadTemplateDirectDownloadCertificate.APINAME,
|
||||
description = "Upload a certificate for HTTPS direct template download on KVM hosts",
|
||||
responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = true,
|
||||
responseHasSensitiveInfo = true,
|
||||
since = "4.11.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class UploadTemplateDirectDownloadCertificate extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
DirectDownloadManager directDownloadManager;
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(UploadTemplateDirectDownloadCertificate.class);
|
||||
public static final String APINAME = "uploadTemplateDirectDownloadCertificate";
|
||||
|
||||
@Parameter(name = ApiConstants.CERTIFICATE, type = BaseCmd.CommandType.STRING, required = true, length = 65535,
|
||||
description = "SSL certificate")
|
||||
private String certificate;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME , type = BaseCmd.CommandType.STRING, required = true,
|
||||
description = "Name for the uploaded certificate")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.HYPERVISOR, type = BaseCmd.CommandType.STRING, required = true, description = "Hypervisor type")
|
||||
private String hypervisor;
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
if (!hypervisor.equalsIgnoreCase("kvm")) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Currently supporting KVM hosts only");
|
||||
}
|
||||
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
try {
|
||||
LOG.debug("Uploading certificate " + name + " to agents for Direct Download");
|
||||
boolean result = directDownloadManager.uploadCertificateToHosts(certificate, name, hypervisor);
|
||||
response.setSuccess(result);
|
||||
setResponseObject(response);
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return UploadTemplateDirectDownloadCertificate.APINAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,5 +27,5 @@ public interface DirectDownloadService {
|
|||
/**
|
||||
* Upload client certificate to each running host
|
||||
*/
|
||||
boolean uploadCertificateToHosts(String certificateCer, String certificateName);
|
||||
}
|
||||
boolean uploadCertificateToHosts(String certificateCer, String certificateName, String hypervisor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,22 +214,7 @@ public class DirectDownloadManagerImpl extends ManagerBase implements DirectDown
|
|||
DownloadProtocol protocol = getProtocolFromUrl(url);
|
||||
DirectDownloadCommand cmd = getDirectDownloadCommandFromProtocol(protocol, url, templateId, to, checksum, headers);
|
||||
|
||||
boolean downloaded = false;
|
||||
int retry = 3;
|
||||
Long[] hostsToRetry = getHostsToRetryOn(host.getClusterId(), host.getDataCenterId(), host.getHypervisorType(), hostId);
|
||||
int hostIndex = 0;
|
||||
Answer answer = null;
|
||||
Long hostToSendDownloadCmd = hostsToRetry[hostIndex];
|
||||
while (!downloaded && retry > 0) {
|
||||
s_logger.debug("Sending Direct download command to host " + hostToSendDownloadCmd);
|
||||
answer = agentManager.easySend(hostToSendDownloadCmd, cmd);
|
||||
downloaded = answer != null && answer.getResult();
|
||||
hostToSendDownloadCmd = hostsToRetry[(hostIndex + 1) % hostsToRetry.length];
|
||||
retry --;
|
||||
}
|
||||
if (!downloaded) {
|
||||
throw new CloudRuntimeException("Template " + templateId + " could not be downloaded on pool " + poolId + ", failing after trying on several hosts");
|
||||
}
|
||||
Answer answer = sendDirectDownloadCommand(cmd, templateId, poolId, host);
|
||||
|
||||
VMTemplateStoragePoolVO sPoolRef = vmTemplatePoolDao.findByPoolTemplate(poolId, templateId);
|
||||
if (sPoolRef == null) {
|
||||
|
|
@ -248,6 +233,35 @@ public class DirectDownloadManagerImpl extends ManagerBase implements DirectDown
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send direct download command for downloading template with ID templateId on storage pool with ID poolId.<br/>
|
||||
* At first, cmd is sent to host, in case of failure it will retry on other hosts before failing
|
||||
* @param cmd direct download command
|
||||
* @param templateId template id
|
||||
* @param poolId pool id
|
||||
* @param host first host to which send the command
|
||||
* @return download answer from any host which could handle cmd
|
||||
*/
|
||||
private Answer sendDirectDownloadCommand(DirectDownloadCommand cmd, long templateId, long poolId, HostVO host) {
|
||||
boolean downloaded = false;
|
||||
int retry = 3;
|
||||
Long[] hostsToRetry = getHostsToRetryOn(host.getClusterId(), host.getDataCenterId(), host.getHypervisorType(), host.getId());
|
||||
int hostIndex = 0;
|
||||
Answer answer = null;
|
||||
Long hostToSendDownloadCmd = hostsToRetry[hostIndex];
|
||||
while (!downloaded && retry > 0) {
|
||||
s_logger.debug("Sending Direct download command to host " + hostToSendDownloadCmd);
|
||||
answer = agentManager.easySend(hostToSendDownloadCmd, cmd);
|
||||
downloaded = answer != null && answer.getResult();
|
||||
hostToSendDownloadCmd = hostsToRetry[(hostIndex + 1) % hostsToRetry.length];
|
||||
retry --;
|
||||
}
|
||||
if (!downloaded) {
|
||||
throw new CloudRuntimeException("Template " + templateId + " could not be downloaded on pool " + poolId + ", failing after trying on several hosts");
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return DirectDownloadCommand according to the protocol
|
||||
* @param protocol
|
||||
|
|
@ -271,19 +285,28 @@ public class DirectDownloadManagerImpl extends ManagerBase implements DirectDown
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean uploadCertificateToHosts(String certificateCer, String certificateName) {
|
||||
List<HostVO> hostsQuery = hostDao.listAllHostsByType(Host.Type.Routing);
|
||||
List<HostVO> hosts = new ArrayList<>();
|
||||
for (HostVO host: hostsQuery) {
|
||||
if (host.getStatus().equals(Status.Up) &&
|
||||
host.getHypervisorType().equals(HypervisorType.KVM)) {
|
||||
hosts.add(host);
|
||||
/**
|
||||
* Return the list of running hosts to which upload certificates for Direct Download
|
||||
*/
|
||||
private List<HostVO> getRunningHostsToUploadCertificate(HypervisorType hypervisorType) {
|
||||
List<HostVO> resultingHosts = new ArrayList<>();
|
||||
for (HostVO host : hostDao.listAllHostsByType(Host.Type.Routing)) {
|
||||
if(host.getStatus().equals(Status.Up) && host.getHypervisorType().equals(hypervisorType)) {
|
||||
resultingHosts.add(host);
|
||||
}
|
||||
}
|
||||
for (HostVO host : hosts) {
|
||||
if (!uploadCertificate(certificateCer, certificateName, host.getId())) {
|
||||
throw new CloudRuntimeException("Uploading certificate " + certificateName + " failed on host: " + host.getId());
|
||||
return resultingHosts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean uploadCertificateToHosts(String certificateCer, String certificateName, String hypervisor) {
|
||||
HypervisorType hypervisorType = HypervisorType.getType(hypervisor);
|
||||
List<HostVO> hosts = getRunningHostsToUploadCertificate(hypervisorType);
|
||||
if (CollectionUtils.isNotEmpty(hosts)) {
|
||||
for (HostVO host : hosts) {
|
||||
if (!uploadCertificate(certificateCer, certificateName, host.getId())) {
|
||||
throw new CloudRuntimeException("Uploading certificate " + certificateName + " failed on host: " + host.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue