Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class ApiConstants {
public static final String ADAPTER_TYPE = "adaptertype";
public static final String ADDRESS = "address";
public static final String ALGORITHM = "algorithm";
public static final String ALIAS = "alias";
public static final String ALLOCATED_ONLY = "allocatedonly";
public static final String ANNOTATION = "annotation";
public static final String API_KEY = "apikey";
Expand Down Expand Up @@ -57,6 +58,10 @@ public class ApiConstants {
public static final String CERTIFICATE_CHAIN = "certchain";
public static final String CERTIFICATE_FINGERPRINT = "fingerprint";
public static final String CERTIFICATE_ID = "certid";
public static final String CERTIFICATE_ISSUER = "issuer";
public static final String CERTIFICATE_SERIALNUM = "serialnum";
public static final String CERTIFICATE_SUBJECT = "subject";
public static final String CERTIFICATE_VALIDITY = "validity";
public static final String ENABLED_REVOCATION_CHECK = "enabledrevocationcheck";
public static final String CONTROLLER = "controller";
public static final String CONTROLLER_UNIT = "controllerunit";
Expand Down Expand Up @@ -187,6 +192,7 @@ public class ApiConstants {
public static final String HOST_ID = "hostid";
public static final String HOST_IDS = "hostids";
public static final String HOST_NAME = "hostname";
public static final String HOSTS_MAP = "hostsmap";
public static final String HYPERVISOR = "hypervisor";
public static final String INLINE = "inline";
public static final String INSTANCE = "instance";
Expand Down Expand Up @@ -236,6 +242,7 @@ public class ApiConstants {
public static final String LEVEL = "level";
public static final String LENGTH = "length";
public static final String LIMIT_CPU_USE = "limitcpuuse";
public static final String LIST_HOSTS = "listhosts";
public static final String LOCK = "lock";
public static final String LUN = "lun";
public static final String LBID = "lbruleid";
Expand Down Expand Up @@ -321,6 +328,7 @@ public class ApiConstants {
public static final String RESOURCE_TYPE_NAME = "resourcetypename";
public static final String RESPONSE = "response";
public static final String REVERTABLE = "revertable";
public static final String REVOKED = "revoked";
public static final String REGISTERED = "registered";
public static final String QUALIFIERS = "qualifiers";
public static final String QUERY_FILTER = "queryfilter";
Expand Down
13 changes: 13 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@
import java.util.Set;

import com.cloud.server.ResourceIcon;
import com.cloud.utils.Pair;
import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
import org.apache.cloudstack.api.response.ResourceIconResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateHostStatusResponse;
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
import com.cloud.resource.RollingMaintenanceManager;
import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
import org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMap;
import org.apache.cloudstack.direct.download.DirectDownloadManager;
import org.apache.cloudstack.management.ManagementServerHost;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
Expand Down Expand Up @@ -491,4 +497,11 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine

ResourceIconResponse createResourceIconResponse(ResourceIcon resourceIcon);

DirectDownloadCertificateResponse createDirectDownloadCertificateResponse(DirectDownloadCertificate certificate);

List<DirectDownloadCertificateHostStatusResponse> createDirectDownloadCertificateHostMapResponse(List<DirectDownloadCertificateHostMap> hostMappings);

DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateHostStatusResponse(DirectDownloadManager.HostCertificateStatus status);

DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateProvisionResponse(Long certificateId, Long hostId, Pair<Boolean, String> result);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// 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.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
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.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DirectDownloadCertificateHostStatusResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
import org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMap;
import org.apache.cloudstack.direct.download.DirectDownloadManager;
import org.apache.log4j.Logger;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;

@APICommand(name = ListTemplateDirectDownloadCertificatesCmd.APINAME,
description = "List the uploaded certificates for direct download templates",
responseObject = DirectDownloadCertificateResponse.class,
since = "4.17.0",
authorized = {RoleType.Admin})
public class ListTemplateDirectDownloadCertificatesCmd extends BaseListCmd {

@Inject
DirectDownloadManager directDownloadManager;

@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DirectDownloadCertificateResponse.class,
description = "list direct download certificate by ID")
private Long id;

@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
description = "the zone where certificates are uploaded")
private Long zoneId;

@Parameter(name = ApiConstants.LIST_HOSTS, type = CommandType.BOOLEAN,
description = "if set to true: include the hosts where the certificate is uploaded to")
private Boolean listHosts;

private static final Logger LOG = Logger.getLogger(ListTemplateDirectDownloadCertificatesCmd.class);
public static final String APINAME = "listTemplateDirectDownloadCertificates";

public boolean isListHosts() {
return listHosts != null && listHosts;
}

private void createResponse(final List<DirectDownloadCertificate> certificates) {
final ListResponse<DirectDownloadCertificateResponse> response = new ListResponse<>();
final List<DirectDownloadCertificateResponse> responses = new ArrayList<>();
for (final DirectDownloadCertificate certificate : certificates) {
if (certificate == null) {
continue;
}
DirectDownloadCertificateResponse certificateResponse = _responseGenerator.createDirectDownloadCertificateResponse(certificate);
if (isListHosts()) {
List<DirectDownloadCertificateHostMap> hostMappings = directDownloadManager.getCertificateHostsMapping(certificate.getId());
List<DirectDownloadCertificateHostStatusResponse> hostMapResponses = _responseGenerator.createDirectDownloadCertificateHostMapResponse(hostMappings);
certificateResponse.setHostsMap(hostMapResponses);
}
responses.add(certificateResponse);
}
response.setResponses(responses);
response.setResponseName(getCommandName());
setResponseObject(response);
}

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
List<DirectDownloadCertificate> certificates = directDownloadManager.listDirectDownloadCertificates(id, zoneId);
createResponse(certificates);
}

@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}

@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// 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.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.utils.Pair;
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.response.DirectDownloadCertificateHostStatusResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.direct.download.DirectDownloadManager;

import javax.inject.Inject;

@APICommand(name = ProvisionTemplateDirectDownloadCertificateCmd.APINAME,
Comment thread
nvazquez marked this conversation as resolved.
description = "Provisions a host with a direct download certificate",
responseObject = DirectDownloadCertificateHostStatusResponse.class,
since = "4.17.0",
authorized = {RoleType.Admin})
public class ProvisionTemplateDirectDownloadCertificateCmd extends BaseCmd {

public static final String APINAME = "provisionTemplateDirectDownloadCertificate";

@Inject
DirectDownloadManager directDownloadManager;

@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DirectDownloadCertificateResponse.class,
Comment thread
nvazquez marked this conversation as resolved.
description = "the id of the direct download certificate to provision", required = true)
private Long id;

@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class,
Comment thread
nvazquez marked this conversation as resolved.
description = "the host to provision the certificate", required = true)
private Long hostId;

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
Pair<Boolean, String> result = directDownloadManager.provisionCertificate(id, hostId);
DirectDownloadCertificateHostStatusResponse response = _responseGenerator.createDirectDownloadCertificateProvisionResponse(id, hostId, result);
response.setResponseName(getCommandName());
setResponseObject(response);
}

@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}

@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,26 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateHostStatusResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
import org.apache.cloudstack.direct.download.DirectDownloadManager;
import org.apache.cloudstack.direct.download.DirectDownloadManager.HostCertificateStatus;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;

@APICommand(name = RevokeTemplateDirectDownloadCertificateCmd.APINAME,
description = "Revoke a certificate alias from a KVM host",
responseObject = SuccessResponse.class,
requestHasSensitiveInfo = true,
responseHasSensitiveInfo = true,
description = "Revoke a direct download certificate from hosts in a zone",
responseObject = DirectDownloadCertificateHostStatusResponse.class,
since = "4.13",
authorized = {RoleType.Admin})
public class RevokeTemplateDirectDownloadCertificateCmd extends BaseCmd {
Expand All @@ -54,35 +60,63 @@ public class RevokeTemplateDirectDownloadCertificateCmd extends BaseCmd {
private static final Logger LOG = Logger.getLogger(RevokeTemplateDirectDownloadCertificateCmd.class);
public static final String APINAME = "revokeTemplateDirectDownloadCertificate";

@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, required = true,
Comment thread
nvazquez marked this conversation as resolved.
description = "alias of the SSL certificate")
@Parameter(name = ApiConstants.ID, type = CommandType.UUID,
entityType = DirectDownloadCertificateResponse.class,
description = "id of the certificate")
private Long certificateId;
Comment thread
nvazquez marked this conversation as resolved.

@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING,
description = "(optional) alias of the SSL certificate")
private String certificateAlias;

@Parameter(name = ApiConstants.HYPERVISOR, type = BaseCmd.CommandType.STRING, required = true,
description = "hypervisor type")
@Parameter(name = ApiConstants.HYPERVISOR, type = BaseCmd.CommandType.STRING,
description = "(optional) hypervisor type")
private String hypervisor;

@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
description = "zone to revoke certificate", required = true)
description = "(optional) zone to revoke certificate", required = true)
private Long zoneId;

@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class,
description = "(optional) the host ID to revoke certificate")
private Long hostId;

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
if (!hypervisor.equalsIgnoreCase("kvm")) {
private void createResponse(final List<HostCertificateStatus> hostsRevokeStatusList) {
final ListResponse<DirectDownloadCertificateHostStatusResponse> response = new ListResponse<>();
final List<DirectDownloadCertificateHostStatusResponse> responses = new ArrayList<>();
for (final HostCertificateStatus status : hostsRevokeStatusList) {
if (status == null) {
continue;
}
DirectDownloadCertificateHostStatusResponse revokeResponse =
_responseGenerator.createDirectDownloadCertificateHostStatusResponse(status);
responses.add(revokeResponse);
}
response.setResponses(responses);
response.setResponseName(getCommandName());
setResponseObject(response);
}

private void validateParameters() {
if (ObjectUtils.allNull(certificateId, certificateAlias, hypervisor) ||
certificateId == null && !ObjectUtils.allNotNull(certificateAlias, hypervisor)) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Please specify the hypervisor and the" +
"certificate name to revoke or the certificate ID");
}
if (StringUtils.isNotBlank(hypervisor) && !hypervisor.equalsIgnoreCase("kvm")) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Currently supporting KVM hosts only");
}
SuccessResponse response = new SuccessResponse(getCommandName());
}

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
validateParameters();
try {
LOG.debug("Revoking certificate " + certificateAlias + " from " + hypervisor + " hosts");
boolean result = directDownloadManager.revokeCertificateAlias(certificateAlias, hypervisor, zoneId, hostId);
response.setSuccess(result);
setResponseObject(response);
DirectDownloadCertificate certificate = directDownloadManager.findDirectDownloadCertificateByIdOrHypervisorAndAlias(certificateId, certificateAlias, hypervisor, zoneId);
List<HostCertificateStatus> hostsResult = directDownloadManager.revokeCertificate(certificate, zoneId, hostId);
createResponse(hostsResult);
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed revoking certificate: " + e.getMessage());
}
}

Expand Down
Loading