From b7e99a31cdcd3d74ca12aca617cbf1bd0afe60b6 Mon Sep 17 00:00:00 2001 From: nvazquez Date: Thu, 15 Nov 2018 12:26:04 -0300 Subject: [PATCH 1/4] Prevent regenerating keystore and add background task to upload certificates --- ...dTemplateDirectDownloadCertificateCmd.java | 22 ++- .../download/DirectDownloadCertificate.java | 29 ++++ .../download/DirectDownloadManager.java | 9 +- ...spring-engine-schema-core-daos-context.xml | 2 + .../META-INF/db/schema-41120to41130.sql | 44 +++++ .../src/com/cloud/host/dao/HostDao.java | 2 + .../src/com/cloud/host/dao/HostDaoImpl.java | 10 ++ .../DirectDownloadCertificateDao.java | 28 +++ .../DirectDownloadCertificateDaoImpl.java | 58 +++++++ .../DirectDownloadCertificateHostMapDao.java | 23 +++ ...rectDownloadCertificateHostMapDaoImpl.java | 39 +++++ .../DirectDownloadCertificateHostMapVO.java | 72 ++++++++ .../download/DirectDownloadCertificateVO.java | 119 +++++++++++++ .../download/DirectDownloadService.java | 4 +- scripts/util/keystore-cert-import | 23 +-- scripts/util/keystore-setup | 29 ++-- .../download/DirectDownloadManagerImpl.java | 163 +++++++++++++++--- 17 files changed, 617 insertions(+), 59 deletions(-) create mode 100644 api/src/org/apache/cloudstack/direct/download/DirectDownloadCertificate.java create mode 100644 engine/schema/resources/META-INF/db/schema-41120to41130.sql create mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDaoImpl.java create mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDaoImpl.java create mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapVO.java create mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateVO.java diff --git a/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java b/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java index 416d26452e72..cef512c583c1 100755 --- a/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java @@ -16,11 +16,6 @@ // 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; @@ -29,6 +24,7 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.direct.download.DirectDownloadManager; import org.apache.log4j.Logger; @@ -39,7 +35,7 @@ description = "Upload a certificate for HTTPS direct template download on KVM hosts", responseObject = SuccessResponse.class, requestHasSensitiveInfo = true, - responseHasSensitiveInfo = true, + responseHasSensitiveInfo = false, since = "4.11.0", authorized = {RoleType.Admin}) public class UploadTemplateDirectDownloadCertificateCmd extends BaseCmd { @@ -61,16 +57,24 @@ public class UploadTemplateDirectDownloadCertificateCmd extends BaseCmd { @Parameter(name = ApiConstants.HYPERVISOR, type = BaseCmd.CommandType.STRING, required = true, description = "Hypervisor type") private String hypervisor; + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, + description = "Zone to upload certificate", required = true) + private Long zoneId; + @Override - public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { + public void execute() { if (!hypervisor.equalsIgnoreCase("kvm")) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Currently supporting KVM hosts only"); } - SuccessResponse response = new SuccessResponse(getCommandName()); + if (name.equalsIgnoreCase("cloud")) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Please provide a different alias name for the certificate"); + } + try { LOG.debug("Uploading certificate " + name + " to agents for Direct Download"); - boolean result = directDownloadManager.uploadCertificateToHosts(certificate, name, hypervisor); + boolean result = directDownloadManager.uploadCertificateToHosts(certificate, name, hypervisor, zoneId); + SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); setResponseObject(response); } catch (Exception e) { diff --git a/api/src/org/apache/cloudstack/direct/download/DirectDownloadCertificate.java b/api/src/org/apache/cloudstack/direct/download/DirectDownloadCertificate.java new file mode 100644 index 000000000000..d42be5f6610f --- /dev/null +++ b/api/src/org/apache/cloudstack/direct/download/DirectDownloadCertificate.java @@ -0,0 +1,29 @@ +// 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.direct.download; + +import com.cloud.hypervisor.Hypervisor; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +public interface DirectDownloadCertificate extends InternalIdentity, Identity { + + String getCertificate(); + String getAlias(); + Hypervisor.HypervisorType getHypervisorType(); + +} diff --git a/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java b/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java index b3f0841a6e89..1cd9c517d327 100644 --- a/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java +++ b/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java @@ -19,7 +19,14 @@ import com.cloud.utils.component.PluggableService; import org.apache.cloudstack.framework.agent.direct.download.DirectDownloadService; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; -public interface DirectDownloadManager extends DirectDownloadService, PluggableService { +public interface DirectDownloadManager extends DirectDownloadService, PluggableService, Configurable { + ConfigKey DirectDownloadCertificateUploadInterval = new ConfigKey<>("Advanced", Long.class, + "direct.download.certificate.background.task.interval", + "24", + "The Direct Download framework background interval in hours.", + true); } diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 84c27583925b..477708ae6f6e 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -356,4 +356,6 @@ + + diff --git a/engine/schema/resources/META-INF/db/schema-41120to41130.sql b/engine/schema/resources/META-INF/db/schema-41120to41130.sql new file mode 100644 index 000000000000..01197d93c615 --- /dev/null +++ b/engine/schema/resources/META-INF/db/schema-41120to41130.sql @@ -0,0 +1,44 @@ +-- 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. + +--; +-- Schema upgrade from 4.11.2.0 to 4.11.3.0 +--; + +CREATE TABLE `cloud`.`direct_download_certificate` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `uuid` varchar(40) NOT NULL, + `alias` varchar(255) NOT NULL, + `certificate` text NOT NULL, + `hypervisor_type` varchar(45) NOT NULL, + `zone_id` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `i_direct_download_certificate_alias` (`alias`), + KEY `fk_direct_download_certificate__zone_id` (`zone_id`), + CONSTRAINT `fk_direct_download_certificate__zone_id` FOREIGN KEY (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`direct_download_certificate_host_map` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `certificate_id` bigint(20) unsigned NOT NULL, + `host_id` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `fk_direct_download_certificate_host_map__host_id` (`host_id`), + KEY `fk_direct_download_certificate_host_map__certificate_id` (`certificate_id`), + CONSTRAINT `fk_direct_download_certificate_host_map__host_id` FOREIGN KEY (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_direct_download_certificate_host_map__certificate_id` FOREIGN KEY (`certificate_id`) REFERENCES `direct_download_certificate` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/engine/schema/src/com/cloud/host/dao/HostDao.java b/engine/schema/src/com/cloud/host/dao/HostDao.java index 71c9cd23867d..76c4d8f4e13e 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDao.java +++ b/engine/schema/src/com/cloud/host/dao/HostDao.java @@ -107,4 +107,6 @@ public interface HostDao extends GenericDao, StateDao listAllHostsUpByZoneAndHypervisor(long zoneId, HypervisorType hypervisorType); } diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java index e48bfd58a6a8..56bf00789b7d 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Objects; import java.util.TimeZone; +import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.inject.Inject; @@ -1192,6 +1193,15 @@ public HostVO findHostInZoneToExecuteCommand(long zoneId, HypervisorType hypervi } } + @Override + public List listAllHostsUpByZoneAndHypervisor(long zoneId, HypervisorType hypervisorType) { + return listByDataCenterIdAndHypervisorType(zoneId, hypervisorType) + .stream() + .filter(x -> x.getStatus().equals(Status.Up) && + x.getType() == Host.Type.Routing) + .collect(Collectors.toList()); + } + private ResultSet executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(HypervisorType hypervisorType, long zoneId, TransactionLegacy tx, String sql) throws SQLException { PreparedStatement pstmt = tx.prepareAutoCloseStatement(sql); pstmt.setString(1, Objects.toString(hypervisorType)); diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDao.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDao.java new file mode 100644 index 000000000000..95a4249e65b1 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDao.java @@ -0,0 +1,28 @@ +// 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.direct.download; + +import com.cloud.hypervisor.Hypervisor; +import com.cloud.utils.db.GenericDao; + +import java.util.List; + +public interface DirectDownloadCertificateDao extends GenericDao { + DirectDownloadCertificateVO findByAlias(String alias); + List listByHypervisorType(Hypervisor.HypervisorType hypervisorType); + List listByZone(long zoneId); +} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDaoImpl.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDaoImpl.java new file mode 100644 index 000000000000..58b3bbc3812e --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDaoImpl.java @@ -0,0 +1,58 @@ +// 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.direct.download; + +import com.cloud.hypervisor.Hypervisor; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +import java.util.List; + +public class DirectDownloadCertificateDaoImpl extends GenericDaoBase implements DirectDownloadCertificateDao { + + private final SearchBuilder certificateSearchBuilder; + + public DirectDownloadCertificateDaoImpl() { + certificateSearchBuilder = createSearchBuilder(); + certificateSearchBuilder.and("alias", certificateSearchBuilder.entity().getAlias(), SearchCriteria.Op.EQ); + certificateSearchBuilder.and("hypervisor_type", certificateSearchBuilder.entity().getHypervisorType(), SearchCriteria.Op.EQ); + certificateSearchBuilder.and("zone_id", certificateSearchBuilder.entity().getZoneId(), SearchCriteria.Op.EQ); + certificateSearchBuilder.done(); + } + + @Override + public DirectDownloadCertificateVO findByAlias(String alias) { + SearchCriteria sc = certificateSearchBuilder.create(); + sc.setParameters("alias", alias); + return findOneBy(sc); + } + + @Override + public List listByHypervisorType(Hypervisor.HypervisorType hypervisorType) { + SearchCriteria sc = certificateSearchBuilder.create(); + sc.setParameters("hypervisor_type", hypervisorType); + return listBy(sc); + } + + @Override + public List listByZone(long zoneId) { + SearchCriteria sc = certificateSearchBuilder.create(); + sc.setParameters("zone_id", zoneId); + return listBy(sc); + } +} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDao.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDao.java new file mode 100644 index 000000000000..56d0032c7f1b --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDao.java @@ -0,0 +1,23 @@ +// 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.direct.download; + +import com.cloud.utils.db.GenericDao; + +public interface DirectDownloadCertificateHostMapDao extends GenericDao { + DirectDownloadCertificateHostMapVO findByCertificateAndHost(long certificateId, long hostId); +} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDaoImpl.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDaoImpl.java new file mode 100644 index 000000000000..6697bdb8122d --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDaoImpl.java @@ -0,0 +1,39 @@ +// 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.direct.download; + +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +public class DirectDownloadCertificateHostMapDaoImpl extends GenericDaoBase implements DirectDownloadCertificateHostMapDao { + private final SearchBuilder mapSearchBuilder; + + public DirectDownloadCertificateHostMapDaoImpl() { + mapSearchBuilder = createSearchBuilder(); + mapSearchBuilder.and("certificate_id", mapSearchBuilder.entity().getCertificateId(), SearchCriteria.Op.EQ); + mapSearchBuilder.and("host_id", mapSearchBuilder.entity().getHostId(), SearchCriteria.Op.EQ); + mapSearchBuilder.done(); + } + @Override + public DirectDownloadCertificateHostMapVO findByCertificateAndHost(long certificateId, long hostId) { + SearchCriteria sc = mapSearchBuilder.create(); + sc.setParameters("certificate_id", certificateId); + sc.setParameters("host_id", hostId); + return findOneBy(sc); + } +} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapVO.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapVO.java new file mode 100644 index 000000000000..b8a7a8ad4494 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapVO.java @@ -0,0 +1,72 @@ +// 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.direct.download; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "direct_download_certificate_host_map") +public class DirectDownloadCertificateHostMapVO { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "host_id") + private Long hostId; + + @Column(name = "certificate_id") + private Long certificateId; + + public DirectDownloadCertificateHostMapVO() { + } + + public DirectDownloadCertificateHostMapVO(Long certificateId, Long hostId) { + this.certificateId = certificateId; + this.hostId = hostId; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getHostId() { + return hostId; + } + + public void setHostId(Long hostId) { + this.hostId = hostId; + } + + public Long getCertificateId() { + return certificateId; + } + + public void setCertificateId(Long certificateId) { + this.certificateId = certificateId; + } +} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateVO.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateVO.java new file mode 100644 index 000000000000..1e43e164ba40 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateVO.java @@ -0,0 +1,119 @@ +// 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.direct.download; + +import com.cloud.hypervisor.Hypervisor; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.UUID; + +@Entity +@Table(name = "direct_download_certificate") +public class DirectDownloadCertificateVO implements DirectDownloadCertificate { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "uuid") + private String uuid; + + @Column(name = "alias") + private String alias; + + @Column(name = "certificate", length = 65535) + private String certificate; + + @Column(name = "hypervisor_type") + private Hypervisor.HypervisorType hypervisorType; + + @Column(name = "zone_id") + private Long zoneId; + + public DirectDownloadCertificateVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public void setId(Long id) { + this.id = id; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public void setCertificate(String certificate) { + this.certificate = certificate; + } + + public void setHypervisorType(Hypervisor.HypervisorType hypervisorType) { + this.hypervisorType = hypervisorType; + } + + public DirectDownloadCertificateVO(String alias, String certificate, + Hypervisor.HypervisorType hypervisorType, Long zoneId) { + this(); + this.alias = alias; + this.certificate = certificate; + this.hypervisorType = hypervisorType; + this.zoneId = zoneId; + } + + @Override + public String getCertificate() { + return certificate; + } + + @Override + public String getAlias() { + return alias; + } + + @Override + public Hypervisor.HypervisorType getHypervisorType() { + return hypervisorType; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { + return uuid; + } + + public Long getZoneId() { + return zoneId; + } + + public void setZoneId(Long zoneId) { + this.zoneId = zoneId; + } + +} diff --git a/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java b/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java index f3153e3470e9..15264c50af0b 100644 --- a/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java +++ b/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java @@ -27,5 +27,7 @@ public interface DirectDownloadService { /** * Upload client certificate to each running host */ - boolean uploadCertificateToHosts(String certificateCer, String certificateName, String hypervisor); + boolean uploadCertificateToHosts(String certificateCer, String certificateName, String hypervisor, Long zoneId); + + boolean uploadCertificate(long certificateId, long hostId); } diff --git a/scripts/util/keystore-cert-import b/scripts/util/keystore-cert-import index 424ab4a718e5..459f8366ee46 100755 --- a/scripts/util/keystore-cert-import +++ b/scripts/util/keystore-cert-import @@ -38,9 +38,6 @@ if [ -z "${KS_PASS// }" ]; then exit 1 fi -# Use a new keystore file -NEW_KS_FILE="$KS_FILE.new" - # Import certificate if [ ! -z "${CERT// }" ]; then echo "$CERT" > "$CERT_FILE" @@ -54,8 +51,8 @@ fi # Import cacerts into the keystore awk '/-----BEGIN CERTIFICATE-----?/{n++}{print > "cloudca." n }' "$CACERT_FILE" for caChain in $(ls cloudca.*); do - keytool -delete -noprompt -alias "$caChain" -keystore "$NEW_KS_FILE" -storepass "$KS_PASS" > /dev/null 2>&1 || true - keytool -import -noprompt -storepass "$KS_PASS" -trustcacerts -alias "$caChain" -file "$caChain" -keystore "$NEW_KS_FILE" > /dev/null 2>&1 + keytool -delete -noprompt -alias "$caChain" -keystore "$KS_FILE" -storepass "$KS_PASS" > /dev/null 2>&1 || true + keytool -import -noprompt -storepass "$KS_PASS" -trustcacerts -alias "$caChain" -file "$caChain" -keystore "$KS_FILE" > /dev/null 2>&1 done rm -f cloudca.* @@ -63,21 +60,19 @@ rm -f cloudca.* if [ ! -z "${PRIVKEY// }" ]; then echo "$PRIVKEY" > "$PRIVKEY_FILE" # Re-initialize keystore when private key is provided - keytool -delete -noprompt -alias "$ALIAS" -keystore "$NEW_KS_FILE" -storepass "$KS_PASS" 2>/dev/null || true - openssl pkcs12 -export -name "$ALIAS" -in "$CERT_FILE" -inkey "$PRIVKEY_FILE" -out "$NEW_KS_FILE.p12" -password pass:"$KS_PASS" > /dev/null 2>&1 - keytool -importkeystore -srckeystore "$NEW_KS_FILE.p12" -destkeystore "$NEW_KS_FILE" -srcstoretype PKCS12 -alias "$ALIAS" -deststorepass "$KS_PASS" -destkeypass "$KS_PASS" -srcstorepass "$KS_PASS" -srckeypass "$KS_PASS" > /dev/null 2>&1 + keytool -delete -noprompt -alias "$ALIAS" -keystore "$KS_FILE" -storepass "$KS_PASS" 2>/dev/null || true + openssl pkcs12 -export -name "$ALIAS" -in "$CERT_FILE" -inkey "$PRIVKEY_FILE" -out "$KS_FILE.p12" -password pass:"$KS_PASS" > /dev/null 2>&1 + keytool -importkeystore -srckeystore "$KS_FILE.p12" -destkeystore "$KS_FILE" -srcstoretype PKCS12 -alias "$ALIAS" -deststorepass "$KS_PASS" -destkeypass "$KS_PASS" -srcstorepass "$KS_PASS" -srckeypass "$KS_PASS" > /dev/null 2>&1 else # Import certificate into the keystore - keytool -import -storepass "$KS_PASS" -alias "$ALIAS" -file "$CERT_FILE" -keystore "$NEW_KS_FILE" > /dev/null 2>&1 || true + keytool -import -storepass "$KS_PASS" -alias "$ALIAS" -file "$CERT_FILE" -keystore "$KS_FILE" > /dev/null 2>&1 || true # Export private key from keystore rm -f "$PRIVKEY_FILE" - keytool -importkeystore -srckeystore "$NEW_KS_FILE" -destkeystore "$NEW_KS_FILE.p12" -deststoretype PKCS12 -srcalias "$ALIAS" -deststorepass "$KS_PASS" -destkeypass "$KS_PASS" -srcstorepass "$KS_PASS" -srckeypass "$KS_PASS" > /dev/null 2>&1 - openssl pkcs12 -in "$NEW_KS_FILE.p12" -nodes -nocerts -nomac -password pass:"$KS_PASS" 2>/dev/null | openssl rsa -out "$PRIVKEY_FILE" > /dev/null 2>&1 + keytool -importkeystore -srckeystore "$KS_FILE" -destkeystore "$KS_FILE.p12" -deststoretype PKCS12 -srcalias "$ALIAS" -deststorepass "$KS_PASS" -destkeypass "$KS_PASS" -srcstorepass "$KS_PASS" -srckeypass "$KS_PASS" > /dev/null 2>&1 + openssl pkcs12 -in "$KS_FILE.p12" -nodes -nocerts -nomac -password pass:"$KS_PASS" 2>/dev/null | openssl rsa -out "$PRIVKEY_FILE" > /dev/null 2>&1 fi -# Commit the new keystore -rm -f "$NEW_KS_FILE.p12" -mv -f "$NEW_KS_FILE" "$KS_FILE" +rm -f "$KS_FILE.p12" # Secure libvirtd on cert import if [ -f "$LIBVIRTD_FILE" ]; then diff --git a/scripts/util/keystore-setup b/scripts/util/keystore-setup index ce963363c1d7..3234d8f57bdf 100755 --- a/scripts/util/keystore-setup +++ b/scripts/util/keystore-setup @@ -17,7 +17,7 @@ # under the License. PROPS_FILE="$1" -KS_FILE="$2.new" +KS_FILE="$2" KS_PASS="$3" KS_VALIDITY="$4" CSR_FILE="$5" @@ -35,18 +35,19 @@ if [ -f "$PROPS_FILE" ]; then fi fi -# Generate keystore -rm -f "$KS_FILE" -CN=$(hostname --fqdn) -keytool -genkey -storepass "$KS_PASS" -keypass "$KS_PASS" -alias "$ALIAS" -keyalg RSA -validity "$KS_VALIDITY" -dname cn="$CN",ou="cloudstack",o="cloudstack",c="cloudstack" -keystore "$KS_FILE" > /dev/null 2>&1 +# Generate keystore if it does not exist +if [ ! -f "$KS_FILE" ]; then + CN=$(hostname --fqdn) + keytool -genkey -storepass "$KS_PASS" -keypass "$KS_PASS" -alias "$ALIAS" -keyalg RSA -validity "$KS_VALIDITY" -dname cn="$CN",ou="cloudstack",o="cloudstack",c="cloudstack" -keystore "$KS_FILE" > /dev/null 2>&1 -# Generate CSR -rm -f "$CSR_FILE" -addresses=$(ip address | grep inet | awk '{print $2}' | sed 's/\/.*//g' | grep -v '^169.254.' | grep -v '^127.0.0.1' | grep -v '^::1' | sed 's/^/ip:/g' | tr '\r\n' ',') -keytool -certreq -storepass "$KS_PASS" -alias "$ALIAS" -file $CSR_FILE -keystore "$KS_FILE" -ext san="$addresses" > /dev/null 2>&1 -cat "$CSR_FILE" + # Generate CSR + rm -f "$CSR_FILE" + addresses=$(ip address | grep inet | awk '{print $2}' | sed 's/\/.*//g' | grep -v '^169.254.' | grep -v '^127.0.0.1' | grep -v '^::1' | sed 's/^/ip:/g' | tr '\r\n' ',') + keytool -certreq -storepass "$KS_PASS" -alias "$ALIAS" -file $CSR_FILE -keystore "$KS_FILE" -ext san="$addresses" > /dev/null 2>&1 + cat "$CSR_FILE" -# Fix file permissions -chmod 600 $KS_FILE -chmod 600 $PROPS_FILE -chmod 600 $CSR_FILE + # Fix file permissions + chmod 600 $KS_FILE + chmod 600 $PROPS_FILE + chmod 600 $CSR_FILE +fi \ No newline at end of file diff --git a/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java b/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java index d2aa67540f32..928173c98acc 100755 --- a/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java +++ b/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java @@ -22,6 +22,8 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; import com.cloud.event.ActionEventUtils; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; @@ -53,6 +55,7 @@ import java.util.Collections; import java.util.stream.Collectors; import javax.inject.Inject; +import javax.naming.ConfigurationException; import com.cloud.utils.security.CertificateHelper; import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand; @@ -68,6 +71,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.cloudstack.poll.BackgroundPollManager; +import org.apache.cloudstack.poll.BackgroundPollTask; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; @@ -75,6 +82,8 @@ import org.apache.commons.collections.MapUtils; import org.apache.log4j.Logger; import sun.security.x509.X509CertImpl; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; public class DirectDownloadManagerImpl extends ManagerBase implements DirectDownloadManager { @@ -85,17 +94,25 @@ public class DirectDownloadManagerImpl extends ManagerBase implements DirectDown protected final static String LINE_SEPARATOR = "\n"; @Inject - VMTemplateDao vmTemplateDao; + private VMTemplateDao vmTemplateDao; @Inject - PrimaryDataStoreDao primaryDataStoreDao; + private PrimaryDataStoreDao primaryDataStoreDao; @Inject - HostDao hostDao; + private HostDao hostDao; @Inject - AgentManager agentManager; + private AgentManager agentManager; @Inject - VMTemplatePoolDao vmTemplatePoolDao; + private VMTemplatePoolDao vmTemplatePoolDao; @Inject - DataStoreManager dataStoreManager; + private DataStoreManager dataStoreManager; + @Inject + private DirectDownloadCertificateDao directDownloadCertificateDao; + @Inject + private DirectDownloadCertificateHostMapDao directDownloadCertificateHostMapDao; + @Inject + private BackgroundPollManager backgroundPollManager; + @Inject + private DataCenterDao dataCenterDao; @Override public List> getCommands() { @@ -311,12 +328,8 @@ private DirectDownloadCommand getDirectDownloadCommandFromProtocol(DownloadProto /** * Return the list of running hosts to which upload certificates for Direct Download */ - private List getRunningHostsToUploadCertificate(HypervisorType hypervisorType) { - return hostDao.listAllHostsByType(Host.Type.Routing) - .stream() - .filter(x -> x.getStatus().equals(Status.Up) && - x.getHypervisorType().equals(hypervisorType)) - .collect(Collectors.toList()); + private List getRunningHostsToUploadCertificate(Long zoneId, HypervisorType hypervisorType) { + return hostDao.listAllHostsUpByZoneAndHypervisor(zoneId, hypervisorType); } /** @@ -365,42 +378,152 @@ protected void certificateSanity(String certificatePem) { } @Override - public boolean uploadCertificateToHosts(String certificateCer, String alias, String hypervisor) { + public boolean uploadCertificateToHosts(String certificateCer, String alias, String hypervisor, Long zoneId) { HypervisorType hypervisorType = HypervisorType.getType(hypervisor); - List hosts = getRunningHostsToUploadCertificate(hypervisorType); + List hosts = getRunningHostsToUploadCertificate(zoneId, hypervisorType); String certificatePem = getPretifiedCertificate(certificateCer); certificateSanity(certificatePem); - s_logger.info("Attempting to upload certificate: " + alias + " to " + hosts.size() + " hosts"); + DirectDownloadCertificateVO certificateVO = directDownloadCertificateDao.findByAlias(alias); + if (certificateVO != null) { + throw new CloudRuntimeException("Certificate alias " + alias + " has been already created"); + } + certificateVO = new DirectDownloadCertificateVO(alias, certificateCer, hypervisorType, zoneId); + directDownloadCertificateDao.persist(certificateVO); + + s_logger.info("Attempting to upload certificate: " + alias + " to " + hosts.size() + " hosts on zone " + zoneId); + int hostCount = 0; if (CollectionUtils.isNotEmpty(hosts)) { for (HostVO host : hosts) { - if (!uploadCertificate(certificatePem, alias, host.getId())) { + if (!uploadCertificate(certificateVO.getId(), host.getId())) { String msg = "Could not upload certificate " + alias + " on host: " + host.getName() + " (" + host.getUuid() + ")"; s_logger.error(msg); throw new CloudRuntimeException(msg); } + hostCount++; } } + s_logger.info("Certificate was successfully uploaded to " + hostCount + " hosts on zone " + zoneId); return true; } /** * Upload and import certificate to hostId on keystore */ - protected boolean uploadCertificate(String certificate, String certificateName, long hostId) { - SetupDirectDownloadCertificateCommand cmd = new SetupDirectDownloadCertificateCommand(certificate, certificateName); + public boolean uploadCertificate(long certificateId, long hostId) { + DirectDownloadCertificateHostMapVO map = directDownloadCertificateHostMapDao.findByCertificateAndHost(certificateId, hostId); + if (map != null) { + s_logger.debug("Certificate " + certificateId + " is already uploaded on host " + hostId); + return true; + } + + DirectDownloadCertificateVO certificateVO = directDownloadCertificateDao.findById(certificateId); + if (certificateVO == null) { + throw new CloudRuntimeException("Could not find certificate with id " + certificateId + " to upload to host: " + hostId); + } + + String certificate = certificateVO.getCertificate(); + String alias = certificateVO.getAlias(); + + s_logger.debug("Uploading certificate: " + certificateId + "(" + alias + ") to host " + hostId); + SetupDirectDownloadCertificateCommand cmd = new SetupDirectDownloadCertificateCommand(certificate, alias); Answer answer = agentManager.easySend(hostId, cmd); if (answer == null || !answer.getResult()) { - String msg = "Certificate " + certificateName + " could not be added to host " + hostId; + String msg = "Certificate " + alias + " could not be added to host " + hostId; if (answer != null) { msg += " due to: " + answer.getDetails(); } s_logger.error(msg); return false; } - s_logger.info("Certificate " + certificateName + " successfully uploaded to host: " + hostId); + + DirectDownloadCertificateHostMapVO mapVO = new DirectDownloadCertificateHostMapVO(certificateId, hostId); + directDownloadCertificateHostMapDao.persist(mapVO); + + s_logger.info("Certificate " + alias + " successfully uploaded to host: " + hostId); + return true; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + backgroundPollManager.submitTask(new DirectDownloadCertificateUploadBackgroundTask(this, + hostDao, dataCenterDao, directDownloadCertificateDao, directDownloadCertificateHostMapDao)); return true; } + @Override + public String getConfigComponentName() { + return DirectDownloadManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[]{ + DirectDownloadCertificateUploadInterval + }; + } + + public static final class DirectDownloadCertificateUploadBackgroundTask extends ManagedContextRunnable implements BackgroundPollTask { + private DirectDownloadManager directDownloadManager; + private HostDao hostDao; + private DirectDownloadCertificateDao directDownloadCertificateDao; + private DirectDownloadCertificateHostMapDao directDownloadCertificateHostMapDao; + private DataCenterDao dataCenterDao; + + public DirectDownloadCertificateUploadBackgroundTask( + final DirectDownloadManager caManager, + final HostDao hostDao, + final DataCenterDao dataCenterDao, + final DirectDownloadCertificateDao directDownloadCertificateDao, + final DirectDownloadCertificateHostMapDao directDownloadCertificateHostMapDao) { + this.directDownloadManager = caManager; + this.hostDao = hostDao; + this.dataCenterDao = dataCenterDao; + this.directDownloadCertificateDao = directDownloadCertificateDao; + this.directDownloadCertificateHostMapDao = directDownloadCertificateHostMapDao; + } + + @Override + protected void runInContext() { + try { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Direct Download Manager background task is running..."); + } + final DateTime now = DateTime.now(DateTimeZone.UTC); + List enabledZones = dataCenterDao.listEnabledZones(); + for (DataCenterVO zone : enabledZones) { + List zoneCertificates = directDownloadCertificateDao.listByZone(zone.getId()); + if (CollectionUtils.isNotEmpty(zoneCertificates)) { + for (DirectDownloadCertificateVO certificateVO : zoneCertificates) { + List hostsToUpload = hostDao.listAllHostsUpByZoneAndHypervisor(certificateVO.getZoneId(), certificateVO.getHypervisorType()); + if (CollectionUtils.isNotEmpty(hostsToUpload)) { + for (HostVO hostVO : hostsToUpload) { + DirectDownloadCertificateHostMapVO mapping = directDownloadCertificateHostMapDao.findByCertificateAndHost(certificateVO.getId(), hostVO.getId()); + if (mapping == null) { + s_logger.debug("Certificate " + certificateVO.getId() + + " (" + certificateVO.getAlias() + ") was not uploaded to host: " + hostVO.getId() + + " uploading it"); + boolean result = directDownloadManager.uploadCertificate(certificateVO.getId(), hostVO.getId()); + s_logger.debug("Certificate " + certificateVO.getAlias() + " " + + (result ? "uploaded" : "could not be uploaded") + + " to host " + hostVO.getId()); + } + } + } + } + } + } + } catch (final Throwable t) { + s_logger.error("Error trying to run Direct Download background task", t); + } + } + + @Override + public Long getDelay() { + return DirectDownloadCertificateUploadInterval.value() + * 60L * 60L * 1000L; //From hours to milliseconds + } + } + } From 07a550c4927d480f4f3ca99db44ed5365ba2067e Mon Sep 17 00:00:00 2001 From: nvazquez Date: Tue, 4 Jun 2019 15:26:44 -0300 Subject: [PATCH 2/4] Remove background task to upload certificates --- ...dTemplateDirectDownloadCertificateCmd.java | 13 +- .../download/DirectDownloadCertificate.java | 29 ---- .../download/DirectDownloadManager.java | 9 +- ...spring-engine-schema-core-daos-context.xml | 2 - .../META-INF/db/schema-41120to41130.sql | 44 ----- .../src/com/cloud/host/dao/HostDao.java | 2 - .../src/com/cloud/host/dao/HostDaoImpl.java | 10 -- .../DirectDownloadCertificateDao.java | 28 ---- .../DirectDownloadCertificateDaoImpl.java | 58 ------- .../DirectDownloadCertificateHostMapDao.java | 23 --- ...rectDownloadCertificateHostMapDaoImpl.java | 39 ----- .../DirectDownloadCertificateHostMapVO.java | 72 -------- .../download/DirectDownloadCertificateVO.java | 119 -------------- .../download/DirectDownloadService.java | 4 +- .../download/DirectDownloadManagerImpl.java | 155 +++--------------- 15 files changed, 24 insertions(+), 583 deletions(-) delete mode 100644 api/src/org/apache/cloudstack/direct/download/DirectDownloadCertificate.java delete mode 100644 engine/schema/resources/META-INF/db/schema-41120to41130.sql delete mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDao.java delete mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDaoImpl.java delete mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDao.java delete mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDaoImpl.java delete mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapVO.java delete mode 100644 engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateVO.java diff --git a/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java b/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java index cef512c583c1..c93fca2d300d 100755 --- a/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java @@ -24,7 +24,6 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.response.SuccessResponse; -import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.direct.download.DirectDownloadManager; import org.apache.log4j.Logger; @@ -35,7 +34,7 @@ description = "Upload a certificate for HTTPS direct template download on KVM hosts", responseObject = SuccessResponse.class, requestHasSensitiveInfo = true, - responseHasSensitiveInfo = false, + responseHasSensitiveInfo = true, since = "4.11.0", authorized = {RoleType.Admin}) public class UploadTemplateDirectDownloadCertificateCmd extends BaseCmd { @@ -57,23 +56,15 @@ public class UploadTemplateDirectDownloadCertificateCmd extends BaseCmd { @Parameter(name = ApiConstants.HYPERVISOR, type = BaseCmd.CommandType.STRING, required = true, description = "Hypervisor type") private String hypervisor; - @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, - description = "Zone to upload certificate", required = true) - private Long zoneId; - @Override public void execute() { if (!hypervisor.equalsIgnoreCase("kvm")) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Currently supporting KVM hosts only"); } - if (name.equalsIgnoreCase("cloud")) { - throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Please provide a different alias name for the certificate"); - } - try { LOG.debug("Uploading certificate " + name + " to agents for Direct Download"); - boolean result = directDownloadManager.uploadCertificateToHosts(certificate, name, hypervisor, zoneId); + boolean result = directDownloadManager.uploadCertificateToHosts(certificate, name, hypervisor); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/direct/download/DirectDownloadCertificate.java b/api/src/org/apache/cloudstack/direct/download/DirectDownloadCertificate.java deleted file mode 100644 index d42be5f6610f..000000000000 --- a/api/src/org/apache/cloudstack/direct/download/DirectDownloadCertificate.java +++ /dev/null @@ -1,29 +0,0 @@ -// 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.direct.download; - -import com.cloud.hypervisor.Hypervisor; -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.api.InternalIdentity; - -public interface DirectDownloadCertificate extends InternalIdentity, Identity { - - String getCertificate(); - String getAlias(); - Hypervisor.HypervisorType getHypervisorType(); - -} diff --git a/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java b/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java index 1cd9c517d327..b3f0841a6e89 100644 --- a/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java +++ b/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java @@ -19,14 +19,7 @@ import com.cloud.utils.component.PluggableService; import org.apache.cloudstack.framework.agent.direct.download.DirectDownloadService; -import org.apache.cloudstack.framework.config.ConfigKey; -import org.apache.cloudstack.framework.config.Configurable; -public interface DirectDownloadManager extends DirectDownloadService, PluggableService, Configurable { +public interface DirectDownloadManager extends DirectDownloadService, PluggableService { - ConfigKey DirectDownloadCertificateUploadInterval = new ConfigKey<>("Advanced", Long.class, - "direct.download.certificate.background.task.interval", - "24", - "The Direct Download framework background interval in hours.", - true); } diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 477708ae6f6e..84c27583925b 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -356,6 +356,4 @@ - - diff --git a/engine/schema/resources/META-INF/db/schema-41120to41130.sql b/engine/schema/resources/META-INF/db/schema-41120to41130.sql deleted file mode 100644 index 01197d93c615..000000000000 --- a/engine/schema/resources/META-INF/db/schema-41120to41130.sql +++ /dev/null @@ -1,44 +0,0 @@ --- 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. - ---; --- Schema upgrade from 4.11.2.0 to 4.11.3.0 ---; - -CREATE TABLE `cloud`.`direct_download_certificate` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `uuid` varchar(40) NOT NULL, - `alias` varchar(255) NOT NULL, - `certificate` text NOT NULL, - `hypervisor_type` varchar(45) NOT NULL, - `zone_id` bigint(20) unsigned NOT NULL, - PRIMARY KEY (`id`), - KEY `i_direct_download_certificate_alias` (`alias`), - KEY `fk_direct_download_certificate__zone_id` (`zone_id`), - CONSTRAINT `fk_direct_download_certificate__zone_id` FOREIGN KEY (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`direct_download_certificate_host_map` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `certificate_id` bigint(20) unsigned NOT NULL, - `host_id` bigint(20) unsigned NOT NULL, - PRIMARY KEY (`id`), - KEY `fk_direct_download_certificate_host_map__host_id` (`host_id`), - KEY `fk_direct_download_certificate_host_map__certificate_id` (`certificate_id`), - CONSTRAINT `fk_direct_download_certificate_host_map__host_id` FOREIGN KEY (`host_id`) REFERENCES `host` (`id`) ON DELETE CASCADE, - CONSTRAINT `fk_direct_download_certificate_host_map__certificate_id` FOREIGN KEY (`certificate_id`) REFERENCES `direct_download_certificate` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/engine/schema/src/com/cloud/host/dao/HostDao.java b/engine/schema/src/com/cloud/host/dao/HostDao.java index 76c4d8f4e13e..71c9cd23867d 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDao.java +++ b/engine/schema/src/com/cloud/host/dao/HostDao.java @@ -107,6 +107,4 @@ public interface HostDao extends GenericDao, StateDao listAllHostsUpByZoneAndHypervisor(long zoneId, HypervisorType hypervisorType); } diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java index 56bf00789b7d..e48bfd58a6a8 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java @@ -26,7 +26,6 @@ import java.util.Map; import java.util.Objects; import java.util.TimeZone; -import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.inject.Inject; @@ -1193,15 +1192,6 @@ public HostVO findHostInZoneToExecuteCommand(long zoneId, HypervisorType hypervi } } - @Override - public List listAllHostsUpByZoneAndHypervisor(long zoneId, HypervisorType hypervisorType) { - return listByDataCenterIdAndHypervisorType(zoneId, hypervisorType) - .stream() - .filter(x -> x.getStatus().equals(Status.Up) && - x.getType() == Host.Type.Routing) - .collect(Collectors.toList()); - } - private ResultSet executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(HypervisorType hypervisorType, long zoneId, TransactionLegacy tx, String sql) throws SQLException { PreparedStatement pstmt = tx.prepareAutoCloseStatement(sql); pstmt.setString(1, Objects.toString(hypervisorType)); diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDao.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDao.java deleted file mode 100644 index 95a4249e65b1..000000000000 --- a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDao.java +++ /dev/null @@ -1,28 +0,0 @@ -// 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.direct.download; - -import com.cloud.hypervisor.Hypervisor; -import com.cloud.utils.db.GenericDao; - -import java.util.List; - -public interface DirectDownloadCertificateDao extends GenericDao { - DirectDownloadCertificateVO findByAlias(String alias); - List listByHypervisorType(Hypervisor.HypervisorType hypervisorType); - List listByZone(long zoneId); -} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDaoImpl.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDaoImpl.java deleted file mode 100644 index 58b3bbc3812e..000000000000 --- a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateDaoImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -// 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.direct.download; - -import com.cloud.hypervisor.Hypervisor; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; - -import java.util.List; - -public class DirectDownloadCertificateDaoImpl extends GenericDaoBase implements DirectDownloadCertificateDao { - - private final SearchBuilder certificateSearchBuilder; - - public DirectDownloadCertificateDaoImpl() { - certificateSearchBuilder = createSearchBuilder(); - certificateSearchBuilder.and("alias", certificateSearchBuilder.entity().getAlias(), SearchCriteria.Op.EQ); - certificateSearchBuilder.and("hypervisor_type", certificateSearchBuilder.entity().getHypervisorType(), SearchCriteria.Op.EQ); - certificateSearchBuilder.and("zone_id", certificateSearchBuilder.entity().getZoneId(), SearchCriteria.Op.EQ); - certificateSearchBuilder.done(); - } - - @Override - public DirectDownloadCertificateVO findByAlias(String alias) { - SearchCriteria sc = certificateSearchBuilder.create(); - sc.setParameters("alias", alias); - return findOneBy(sc); - } - - @Override - public List listByHypervisorType(Hypervisor.HypervisorType hypervisorType) { - SearchCriteria sc = certificateSearchBuilder.create(); - sc.setParameters("hypervisor_type", hypervisorType); - return listBy(sc); - } - - @Override - public List listByZone(long zoneId) { - SearchCriteria sc = certificateSearchBuilder.create(); - sc.setParameters("zone_id", zoneId); - return listBy(sc); - } -} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDao.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDao.java deleted file mode 100644 index 56d0032c7f1b..000000000000 --- a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDao.java +++ /dev/null @@ -1,23 +0,0 @@ -// 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.direct.download; - -import com.cloud.utils.db.GenericDao; - -public interface DirectDownloadCertificateHostMapDao extends GenericDao { - DirectDownloadCertificateHostMapVO findByCertificateAndHost(long certificateId, long hostId); -} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDaoImpl.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDaoImpl.java deleted file mode 100644 index 6697bdb8122d..000000000000 --- a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapDaoImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -// 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.direct.download; - -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; - -public class DirectDownloadCertificateHostMapDaoImpl extends GenericDaoBase implements DirectDownloadCertificateHostMapDao { - private final SearchBuilder mapSearchBuilder; - - public DirectDownloadCertificateHostMapDaoImpl() { - mapSearchBuilder = createSearchBuilder(); - mapSearchBuilder.and("certificate_id", mapSearchBuilder.entity().getCertificateId(), SearchCriteria.Op.EQ); - mapSearchBuilder.and("host_id", mapSearchBuilder.entity().getHostId(), SearchCriteria.Op.EQ); - mapSearchBuilder.done(); - } - @Override - public DirectDownloadCertificateHostMapVO findByCertificateAndHost(long certificateId, long hostId) { - SearchCriteria sc = mapSearchBuilder.create(); - sc.setParameters("certificate_id", certificateId); - sc.setParameters("host_id", hostId); - return findOneBy(sc); - } -} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapVO.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapVO.java deleted file mode 100644 index b8a7a8ad4494..000000000000 --- a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateHostMapVO.java +++ /dev/null @@ -1,72 +0,0 @@ -// 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.direct.download; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name = "direct_download_certificate_host_map") -public class DirectDownloadCertificateHostMapVO { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - @Column(name = "host_id") - private Long hostId; - - @Column(name = "certificate_id") - private Long certificateId; - - public DirectDownloadCertificateHostMapVO() { - } - - public DirectDownloadCertificateHostMapVO(Long certificateId, Long hostId) { - this.certificateId = certificateId; - this.hostId = hostId; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getHostId() { - return hostId; - } - - public void setHostId(Long hostId) { - this.hostId = hostId; - } - - public Long getCertificateId() { - return certificateId; - } - - public void setCertificateId(Long certificateId) { - this.certificateId = certificateId; - } -} diff --git a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateVO.java b/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateVO.java deleted file mode 100644 index 1e43e164ba40..000000000000 --- a/engine/schema/src/org/apache/cloudstack/direct/download/DirectDownloadCertificateVO.java +++ /dev/null @@ -1,119 +0,0 @@ -// 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.direct.download; - -import com.cloud.hypervisor.Hypervisor; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import java.util.UUID; - -@Entity -@Table(name = "direct_download_certificate") -public class DirectDownloadCertificateVO implements DirectDownloadCertificate { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private Long id; - - @Column(name = "uuid") - private String uuid; - - @Column(name = "alias") - private String alias; - - @Column(name = "certificate", length = 65535) - private String certificate; - - @Column(name = "hypervisor_type") - private Hypervisor.HypervisorType hypervisorType; - - @Column(name = "zone_id") - private Long zoneId; - - public DirectDownloadCertificateVO() { - this.uuid = UUID.randomUUID().toString(); - } - - public void setId(Long id) { - this.id = id; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public void setAlias(String alias) { - this.alias = alias; - } - - public void setCertificate(String certificate) { - this.certificate = certificate; - } - - public void setHypervisorType(Hypervisor.HypervisorType hypervisorType) { - this.hypervisorType = hypervisorType; - } - - public DirectDownloadCertificateVO(String alias, String certificate, - Hypervisor.HypervisorType hypervisorType, Long zoneId) { - this(); - this.alias = alias; - this.certificate = certificate; - this.hypervisorType = hypervisorType; - this.zoneId = zoneId; - } - - @Override - public String getCertificate() { - return certificate; - } - - @Override - public String getAlias() { - return alias; - } - - @Override - public Hypervisor.HypervisorType getHypervisorType() { - return hypervisorType; - } - - @Override - public long getId() { - return id; - } - - @Override - public String getUuid() { - return uuid; - } - - public Long getZoneId() { - return zoneId; - } - - public void setZoneId(Long zoneId) { - this.zoneId = zoneId; - } - -} diff --git a/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java b/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java index 15264c50af0b..f3153e3470e9 100644 --- a/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java +++ b/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java @@ -27,7 +27,5 @@ public interface DirectDownloadService { /** * Upload client certificate to each running host */ - boolean uploadCertificateToHosts(String certificateCer, String certificateName, String hypervisor, Long zoneId); - - boolean uploadCertificate(long certificateId, long hostId); + boolean uploadCertificateToHosts(String certificateCer, String certificateName, String hypervisor); } diff --git a/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java b/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java index 928173c98acc..2584f75ded3b 100755 --- a/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java +++ b/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java @@ -22,8 +22,6 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.dao.DataCenterDao; import com.cloud.event.ActionEventUtils; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; @@ -55,7 +53,6 @@ import java.util.Collections; import java.util.stream.Collectors; import javax.inject.Inject; -import javax.naming.ConfigurationException; import com.cloud.utils.security.CertificateHelper; import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand; @@ -71,10 +68,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore; -import org.apache.cloudstack.framework.config.ConfigKey; -import org.apache.cloudstack.managed.context.ManagedContextRunnable; -import org.apache.cloudstack.poll.BackgroundPollManager; -import org.apache.cloudstack.poll.BackgroundPollTask; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; @@ -82,8 +75,6 @@ import org.apache.commons.collections.MapUtils; import org.apache.log4j.Logger; import sun.security.x509.X509CertImpl; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; public class DirectDownloadManagerImpl extends ManagerBase implements DirectDownloadManager { @@ -105,14 +96,6 @@ public class DirectDownloadManagerImpl extends ManagerBase implements DirectDown private VMTemplatePoolDao vmTemplatePoolDao; @Inject private DataStoreManager dataStoreManager; - @Inject - private DirectDownloadCertificateDao directDownloadCertificateDao; - @Inject - private DirectDownloadCertificateHostMapDao directDownloadCertificateHostMapDao; - @Inject - private BackgroundPollManager backgroundPollManager; - @Inject - private DataCenterDao dataCenterDao; @Override public List> getCommands() { @@ -328,8 +311,12 @@ private DirectDownloadCommand getDirectDownloadCommandFromProtocol(DownloadProto /** * Return the list of running hosts to which upload certificates for Direct Download */ - private List getRunningHostsToUploadCertificate(Long zoneId, HypervisorType hypervisorType) { - return hostDao.listAllHostsUpByZoneAndHypervisor(zoneId, hypervisorType); + private List getRunningHostsToUploadCertificate(HypervisorType hypervisorType) { + return hostDao.listAllHostsByType(Host.Type.Routing) + .stream() + .filter(x -> x.getStatus().equals(Status.Up) && + x.getHypervisorType().equals(hypervisorType)) + .collect(Collectors.toList()); } /** @@ -378,25 +365,22 @@ protected void certificateSanity(String certificatePem) { } @Override - public boolean uploadCertificateToHosts(String certificateCer, String alias, String hypervisor, Long zoneId) { + public boolean uploadCertificateToHosts(String certificateCer, String alias, String hypervisor) { + if (alias.equalsIgnoreCase("cloud")) { + throw new CloudRuntimeException("Please provide a different alias name for the certificate"); + } + HypervisorType hypervisorType = HypervisorType.getType(hypervisor); - List hosts = getRunningHostsToUploadCertificate(zoneId, hypervisorType); + List hosts = getRunningHostsToUploadCertificate(hypervisorType); String certificatePem = getPretifiedCertificate(certificateCer); certificateSanity(certificatePem); - DirectDownloadCertificateVO certificateVO = directDownloadCertificateDao.findByAlias(alias); - if (certificateVO != null) { - throw new CloudRuntimeException("Certificate alias " + alias + " has been already created"); - } - certificateVO = new DirectDownloadCertificateVO(alias, certificateCer, hypervisorType, zoneId); - directDownloadCertificateDao.persist(certificateVO); - - s_logger.info("Attempting to upload certificate: " + alias + " to " + hosts.size() + " hosts on zone " + zoneId); + s_logger.info("Attempting to upload certificate: " + alias + " to " + hosts.size() + " hosts"); int hostCount = 0; if (CollectionUtils.isNotEmpty(hosts)) { for (HostVO host : hosts) { - if (!uploadCertificate(certificateVO.getId(), host.getId())) { + if (!uploadCertificate(certificatePem, alias, host.getId())) { String msg = "Could not upload certificate " + alias + " on host: " + host.getName() + " (" + host.getUuid() + ")"; s_logger.error(msg); throw new CloudRuntimeException(msg); @@ -404,126 +388,27 @@ public boolean uploadCertificateToHosts(String certificateCer, String alias, Str hostCount++; } } - s_logger.info("Certificate was successfully uploaded to " + hostCount + " hosts on zone " + zoneId); + s_logger.info("Certificate was successfully uploaded to " + hostCount + " hosts"); return true; } /** * Upload and import certificate to hostId on keystore */ - public boolean uploadCertificate(long certificateId, long hostId) { - DirectDownloadCertificateHostMapVO map = directDownloadCertificateHostMapDao.findByCertificateAndHost(certificateId, hostId); - if (map != null) { - s_logger.debug("Certificate " + certificateId + " is already uploaded on host " + hostId); - return true; - } - - DirectDownloadCertificateVO certificateVO = directDownloadCertificateDao.findById(certificateId); - if (certificateVO == null) { - throw new CloudRuntimeException("Could not find certificate with id " + certificateId + " to upload to host: " + hostId); - } - - String certificate = certificateVO.getCertificate(); - String alias = certificateVO.getAlias(); - - s_logger.debug("Uploading certificate: " + certificateId + "(" + alias + ") to host " + hostId); - SetupDirectDownloadCertificateCommand cmd = new SetupDirectDownloadCertificateCommand(certificate, alias); + protected boolean uploadCertificate(String certificate, String certificateName, long hostId) { + s_logger.debug("Uploading certificate: " + certificateName + " to host " + hostId); + SetupDirectDownloadCertificateCommand cmd = new SetupDirectDownloadCertificateCommand(certificate, certificateName); Answer answer = agentManager.easySend(hostId, cmd); if (answer == null || !answer.getResult()) { - String msg = "Certificate " + alias + " could not be added to host " + hostId; + String msg = "Certificate " + certificateName + " could not be added to host " + hostId; if (answer != null) { msg += " due to: " + answer.getDetails(); } s_logger.error(msg); return false; } - - DirectDownloadCertificateHostMapVO mapVO = new DirectDownloadCertificateHostMapVO(certificateId, hostId); - directDownloadCertificateHostMapDao.persist(mapVO); - - s_logger.info("Certificate " + alias + " successfully uploaded to host: " + hostId); + s_logger.info("Certificate " + certificateName + " successfully uploaded to host: " + hostId); return true; } - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - backgroundPollManager.submitTask(new DirectDownloadCertificateUploadBackgroundTask(this, - hostDao, dataCenterDao, directDownloadCertificateDao, directDownloadCertificateHostMapDao)); - return true; - } - - @Override - public String getConfigComponentName() { - return DirectDownloadManager.class.getSimpleName(); - } - - @Override - public ConfigKey[] getConfigKeys() { - return new ConfigKey[]{ - DirectDownloadCertificateUploadInterval - }; - } - - public static final class DirectDownloadCertificateUploadBackgroundTask extends ManagedContextRunnable implements BackgroundPollTask { - private DirectDownloadManager directDownloadManager; - private HostDao hostDao; - private DirectDownloadCertificateDao directDownloadCertificateDao; - private DirectDownloadCertificateHostMapDao directDownloadCertificateHostMapDao; - private DataCenterDao dataCenterDao; - - public DirectDownloadCertificateUploadBackgroundTask( - final DirectDownloadManager caManager, - final HostDao hostDao, - final DataCenterDao dataCenterDao, - final DirectDownloadCertificateDao directDownloadCertificateDao, - final DirectDownloadCertificateHostMapDao directDownloadCertificateHostMapDao) { - this.directDownloadManager = caManager; - this.hostDao = hostDao; - this.dataCenterDao = dataCenterDao; - this.directDownloadCertificateDao = directDownloadCertificateDao; - this.directDownloadCertificateHostMapDao = directDownloadCertificateHostMapDao; - } - - @Override - protected void runInContext() { - try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Direct Download Manager background task is running..."); - } - final DateTime now = DateTime.now(DateTimeZone.UTC); - List enabledZones = dataCenterDao.listEnabledZones(); - for (DataCenterVO zone : enabledZones) { - List zoneCertificates = directDownloadCertificateDao.listByZone(zone.getId()); - if (CollectionUtils.isNotEmpty(zoneCertificates)) { - for (DirectDownloadCertificateVO certificateVO : zoneCertificates) { - List hostsToUpload = hostDao.listAllHostsUpByZoneAndHypervisor(certificateVO.getZoneId(), certificateVO.getHypervisorType()); - if (CollectionUtils.isNotEmpty(hostsToUpload)) { - for (HostVO hostVO : hostsToUpload) { - DirectDownloadCertificateHostMapVO mapping = directDownloadCertificateHostMapDao.findByCertificateAndHost(certificateVO.getId(), hostVO.getId()); - if (mapping == null) { - s_logger.debug("Certificate " + certificateVO.getId() + - " (" + certificateVO.getAlias() + ") was not uploaded to host: " + hostVO.getId() + - " uploading it"); - boolean result = directDownloadManager.uploadCertificate(certificateVO.getId(), hostVO.getId()); - s_logger.debug("Certificate " + certificateVO.getAlias() + " " + - (result ? "uploaded" : "could not be uploaded") + - " to host " + hostVO.getId()); - } - } - } - } - } - } - } catch (final Throwable t) { - s_logger.error("Error trying to run Direct Download background task", t); - } - } - - @Override - public Long getDelay() { - return DirectDownloadCertificateUploadInterval.value() - * 60L * 60L * 1000L; //From hours to milliseconds - } - } - } From e1d8555bc7f5c4d3a8dfe4a1360d2c048ae51a6b Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 5 Jun 2019 16:03:38 +0530 Subject: [PATCH 3/4] keystore-setup: delete old key in jks Signed-off-by: Rohit Yadav --- scripts/util/keystore-setup | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/scripts/util/keystore-setup b/scripts/util/keystore-setup index 3234d8f57bdf..65f04c48d579 100755 --- a/scripts/util/keystore-setup +++ b/scripts/util/keystore-setup @@ -35,19 +35,20 @@ if [ -f "$PROPS_FILE" ]; then fi fi -# Generate keystore if it does not exist -if [ ! -f "$KS_FILE" ]; then - CN=$(hostname --fqdn) - keytool -genkey -storepass "$KS_PASS" -keypass "$KS_PASS" -alias "$ALIAS" -keyalg RSA -validity "$KS_VALIDITY" -dname cn="$CN",ou="cloudstack",o="cloudstack",c="cloudstack" -keystore "$KS_FILE" > /dev/null 2>&1 +if [ -f "$KS_FILE" ]; then + keytool -delete -noprompt -alias "$ALIAS" -keystore "$KS_FILE" -storepass "$KS_PASS" > /dev/null 2>&1 || true +fi + +CN=$(hostname --fqdn) +keytool -genkey -storepass "$KS_PASS" -keypass "$KS_PASS" -alias "$ALIAS" -keyalg RSA -validity "$KS_VALIDITY" -dname cn="$CN",ou="cloudstack",o="cloudstack",c="cloudstack" -keystore "$KS_FILE" > /dev/null 2>&1 - # Generate CSR - rm -f "$CSR_FILE" - addresses=$(ip address | grep inet | awk '{print $2}' | sed 's/\/.*//g' | grep -v '^169.254.' | grep -v '^127.0.0.1' | grep -v '^::1' | sed 's/^/ip:/g' | tr '\r\n' ',') - keytool -certreq -storepass "$KS_PASS" -alias "$ALIAS" -file $CSR_FILE -keystore "$KS_FILE" -ext san="$addresses" > /dev/null 2>&1 - cat "$CSR_FILE" +# Generate CSR +rm -f "$CSR_FILE" +addresses=$(ip address | grep inet | awk '{print $2}' | sed 's/\/.*//g' | grep -v '^169.254.' | grep -v '^127.0.0.1' | grep -v '^::1' | sed 's/^/ip:/g' | tr '\r\n' ',') +keytool -certreq -storepass "$KS_PASS" -alias "$ALIAS" -file $CSR_FILE -keystore "$KS_FILE" -ext san="$addresses" > /dev/null 2>&1 +cat "$CSR_FILE" - # Fix file permissions - chmod 600 $KS_FILE - chmod 600 $PROPS_FILE - chmod 600 $CSR_FILE -fi \ No newline at end of file +# Fix file permissions +chmod 600 $KS_FILE +chmod 600 $PROPS_FILE +chmod 600 $CSR_FILE From 78318060e5cf241a435b8610c589e6ac04fa67fd Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 5 Jun 2019 16:24:10 +0530 Subject: [PATCH 4/4] also don't allow ca-cert alias Signed-off-by: Rohit Yadav --- .../cloudstack/direct/download/DirectDownloadManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java b/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java index 2584f75ded3b..99860934cd56 100755 --- a/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java +++ b/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java @@ -366,7 +366,7 @@ protected void certificateSanity(String certificatePem) { @Override public boolean uploadCertificateToHosts(String certificateCer, String alias, String hypervisor) { - if (alias.equalsIgnoreCase("cloud")) { + if (alias != null && (alias.equalsIgnoreCase("cloud") || alias.startsWith("cloudca"))) { throw new CloudRuntimeException("Please provide a different alias name for the certificate"); }