From 727b3b0d5b26690d0eb6fbbdb9bc6ea8ee80ce4b Mon Sep 17 00:00:00 2001 From: Oleg Chuev <91337563+OlegChuev@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:28:46 +0300 Subject: [PATCH 01/17] Removed deprecated instruction MAINTAINER (#8846) Co-authored-by: dahn Co-authored-by: Wei Zhou --- tools/docker/Dockerfile | 3 +-- tools/docker/Dockerfile.marvin | 3 +-- tools/docker/Dockerfile.smokedev | 3 +-- ui/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 319e8f9b158..036054103a6 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -19,8 +19,7 @@ FROM ubuntu:22.04 -MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.18.3.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.18.3.0-SNAPSHOT" Author="Apache CloudStack " ARG DEBIAN_FRONTEND=noninteractive diff --git a/tools/docker/Dockerfile.marvin b/tools/docker/Dockerfile.marvin index 52bdd6a1ec3..1a670561237 100644 --- a/tools/docker/Dockerfile.marvin +++ b/tools/docker/Dockerfile.marvin @@ -19,8 +19,7 @@ # build for cloudstack_home_dir not this folder FROM python:2 -MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.18.3.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.18.3.0-SNAPSHOT" Author="Apache CloudStack " ENV WORK_DIR=/marvin diff --git a/tools/docker/Dockerfile.smokedev b/tools/docker/Dockerfile.smokedev index 881e1005678..f3d6f03a403 100644 --- a/tools/docker/Dockerfile.smokedev +++ b/tools/docker/Dockerfile.smokedev @@ -19,8 +19,7 @@ FROM ubuntu:16.04 -MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0-SNAPSHOT" Author="Apache CloudStack " RUN apt-get -y update && apt-get install -y \ genisoimage \ diff --git a/ui/Dockerfile b/ui/Dockerfile index d636ae5657e..f5556234e19 100644 --- a/ui/Dockerfile +++ b/ui/Dockerfile @@ -19,11 +19,11 @@ FROM node:14-bullseye AS build -MAINTAINER "Apache CloudStack" LABEL Description="Apache CloudStack UI; Modern role-base progressive UI for Apache CloudStack" LABEL Vendor="Apache.org" LABEL License=ApacheV2 LABEL Version=0.5.0 +LABEL Author="Apache CloudStack " WORKDIR /build From ee1cd91e988a470a932d2dd7a5bf5484ffe1c15f Mon Sep 17 00:00:00 2001 From: Felipe <124818914+FelipeM525@users.noreply.github.com> Date: Fri, 20 Sep 2024 04:59:38 -0300 Subject: [PATCH 02/17] fixed an issue where requests to the api createDomain were being sent with the field networkdomain as an empty string whenever the user typed something in the form and cleared it causing an exception (#9637) --- ui/src/views/iam/DomainActionForm.vue | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/src/views/iam/DomainActionForm.vue b/ui/src/views/iam/DomainActionForm.vue index 4d7c727d49e..ab53a5974e4 100644 --- a/ui/src/views/iam/DomainActionForm.vue +++ b/ui/src/views/iam/DomainActionForm.vue @@ -237,6 +237,11 @@ export default { const resourceName = params.displayname || params.displaytext || params.name || this.resource.name let hasJobId = false + Object.keys(params).forEach(key => { + if (params[key] === '') { + delete params[key] + } + }) api(this.action.api, params).then(json => { for (const obj in json) { if (obj.includes('response')) { From 9ce7ef49cf997766d19892f8b0aa63a6f5ab3d4c Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Fri, 20 Sep 2024 10:17:12 +0200 Subject: [PATCH 03/17] build/packaging: build tungsten plugin only if noredist is passed (#9006) --- client/pom.xml | 21 ++--- plugins/hypervisors/kvm/pom.xml | 5 -- .../agent/api/SetupTfRouteCommand.java | 64 ++++++++++++++ .../api/SetupTungstenVRouterCommand.java | 77 +++++++++++++++++ .../UpdateTungstenLoadbalancerSslCommand.java | 83 +++++++++++++++++++ ...pdateTungstenLoadbalancerStatsCommand.java | 71 ++++++++++++++++ plugins/network-elements/tungsten/pom.xml | 7 -- plugins/pom.xml | 2 +- server/pom.xml | 11 --- .../com/cloud/network/NetworkServiceImpl.java | 6 +- 10 files changed, 306 insertions(+), 41 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTfRouteCommand.java create mode 100644 plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTungstenVRouterCommand.java create mode 100644 plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerSslCommand.java create mode 100644 plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerStatsCommand.java diff --git a/client/pom.xml b/client/pom.xml index 9173e369560..53baebbc2b4 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -27,18 +27,7 @@ cloudstack 4.19.2.0-SNAPSHOT - - - juniper-tungsten-api - https://github.com/radu-todirica/tungsten-api/raw/master - - - - net.juniper.tungsten - juniper-tungsten-api - 2.0 - javax.servlet javax.servlet-api @@ -282,11 +271,6 @@ cloud-plugin-network-ovs ${project.version} - - org.apache.cloudstack - cloud-plugin-network-tungsten - ${project.version} - org.apache.cloudstack cloud-plugin-network-elb @@ -1088,6 +1072,11 @@ cloud-plugin-network-cisco-vnmc ${project.version} + + org.apache.cloudstack + cloud-plugin-network-tungsten + ${project.version} + org.apache.cloudstack cloud-plugin-api-vmware-sioc diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index ad684b6e65f..de5a02c7f7e 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -83,11 +83,6 @@ ${project.version} compile - - org.apache.cloudstack - cloud-plugin-network-tungsten - ${project.version} - diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTfRouteCommand.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTfRouteCommand.java new file mode 100644 index 00000000000..8ccbff96d79 --- /dev/null +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTfRouteCommand.java @@ -0,0 +1,64 @@ +// 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.network.tungsten.agent.api; + +import com.cloud.agent.api.Command; + +import java.util.Objects; + +public class SetupTfRouteCommand extends Command { + private final String privateIp; + private final String publicIp; + private final String srcNetwork; + + public SetupTfRouteCommand(final String privateIp, final String publicIp, final String srcNetwork) { + this.privateIp = privateIp; + this.publicIp = publicIp; + this.srcNetwork = srcNetwork; + } + + public String getPrivateIp() { + return privateIp; + } + + public String getPublicIp() { + return publicIp; + } + + public String getSrcNetwork() { + return srcNetwork; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + SetupTfRouteCommand that = (SetupTfRouteCommand) o; + return Objects.equals(privateIp, that.privateIp) && Objects.equals(publicIp, that.publicIp) && Objects.equals(srcNetwork, that.srcNetwork); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), privateIp, publicIp, srcNetwork); + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTungstenVRouterCommand.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTungstenVRouterCommand.java new file mode 100644 index 00000000000..00fc522363d --- /dev/null +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/SetupTungstenVRouterCommand.java @@ -0,0 +1,77 @@ +// 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.network.tungsten.agent.api; + +import com.cloud.agent.api.Command; + +import java.util.Objects; + +public class SetupTungstenVRouterCommand extends Command { + private final String oper; + private final String inf; + private final String subnet; + private final String route; + private final String vrf; + + public SetupTungstenVRouterCommand(final String oper, final String inf, final String subnet, final String route, + final String vrf) { + this.oper = oper; + this.inf = inf; + this.subnet = subnet; + this.route = route; + this.vrf = vrf; + } + + public String getOper() { + return oper; + } + + public String getInf() { + return inf; + } + + public String getSubnet() { + return subnet; + } + + public String getRoute() { + return route; + } + + public String getVrf() { + return vrf; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + SetupTungstenVRouterCommand that = (SetupTungstenVRouterCommand) o; + return Objects.equals(oper, that.oper) && Objects.equals(inf, that.inf) && Objects.equals(subnet, that.subnet) && Objects.equals(route, that.route) && Objects.equals(vrf, that.vrf); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), oper, inf, subnet, route, vrf); + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerSslCommand.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerSslCommand.java new file mode 100644 index 00000000000..5ab24c18aa0 --- /dev/null +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerSslCommand.java @@ -0,0 +1,83 @@ +// 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.network.tungsten.agent.api; + +import com.cloud.agent.api.Command; + +import java.util.Objects; + +public class UpdateTungstenLoadbalancerSslCommand extends Command { + private final String lbUuid; + private final String sslCertName; + private final String certificateKey; + private final String privateKey; + private final String privateIp; + private final String port; + + public UpdateTungstenLoadbalancerSslCommand(final String lbUuid, final String sslCertName, + final String certificateKey, final String privateKey, final String privateIp, final String port) { + this.lbUuid = lbUuid; + this.sslCertName = sslCertName; + this.certificateKey = certificateKey; + this.privateKey = privateKey; + this.privateIp = privateIp; + this.port = port; + } + + public String getLbUuid() { + return lbUuid; + } + + public String getSslCertName() { + return sslCertName; + } + + public String getCertificateKey() { + return certificateKey; + } + + public String getPrivateKey() { + return privateKey; + } + + public String getPrivateIp() { + return privateIp; + } + + public String getPort() { + return port; + } + + @Override + public boolean executeInSequence() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + UpdateTungstenLoadbalancerSslCommand that = (UpdateTungstenLoadbalancerSslCommand) o; + return Objects.equals(lbUuid, that.lbUuid) && Objects.equals(sslCertName, that.sslCertName) && Objects.equals(certificateKey, that.certificateKey) && Objects.equals(privateKey, that.privateKey) && Objects.equals(privateIp, that.privateIp) && Objects.equals(port, that.port); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), lbUuid, sslCertName, certificateKey, privateKey, privateIp, port); + } +} diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerStatsCommand.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerStatsCommand.java new file mode 100644 index 00000000000..d7b2088bcd7 --- /dev/null +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/network/tungsten/agent/api/UpdateTungstenLoadbalancerStatsCommand.java @@ -0,0 +1,71 @@ +// 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.network.tungsten.agent.api; + +import com.cloud.agent.api.Command; + +import java.util.Objects; + +public class UpdateTungstenLoadbalancerStatsCommand extends Command { + private final String lbUuid; + private final String lbStatsPort; + private final String lbStatsUri; + private final String lbStatsAuth; + + public UpdateTungstenLoadbalancerStatsCommand(final String lbUuid, final String lbStatsPort, + final String lbStatsUri, final String lbStatsAuth) { + this.lbUuid = lbUuid; + this.lbStatsPort = lbStatsPort; + this.lbStatsUri = lbStatsUri; + this.lbStatsAuth = lbStatsAuth; + } + + public String getLbUuid() { + return lbUuid; + } + + public String getLbStatsPort() { + return lbStatsPort; + } + + public String getLbStatsUri() { + return lbStatsUri; + } + + public String getLbStatsAuth() { + return lbStatsAuth; + } + + @Override + public boolean executeInSequence() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + UpdateTungstenLoadbalancerStatsCommand that = (UpdateTungstenLoadbalancerStatsCommand) o; + return Objects.equals(lbUuid, that.lbUuid) && Objects.equals(lbStatsPort, that.lbStatsPort) && Objects.equals(lbStatsUri, that.lbStatsUri) && Objects.equals(lbStatsAuth, that.lbStatsAuth); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), lbUuid, lbStatsPort, lbStatsUri, lbStatsAuth); + } +} diff --git a/plugins/network-elements/tungsten/pom.xml b/plugins/network-elements/tungsten/pom.xml index 2f0bb0f8076..92e520a0ffd 100644 --- a/plugins/network-elements/tungsten/pom.xml +++ b/plugins/network-elements/tungsten/pom.xml @@ -30,13 +30,6 @@ ../../pom.xml - - - juniper-tungsten-api - https://github.com/radu-todirica/tungsten-api/raw/master - - - net.juniper.tungsten diff --git a/plugins/pom.xml b/plugins/pom.xml index a7f0ebd5ed1..27d316f56c1 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -111,7 +111,6 @@ network-elements/stratosphere-ssp network-elements/brocade-vcs network-elements/vxlan - network-elements/tungsten outofbandmanagement-drivers/ipmitool outofbandmanagement-drivers/nested-cloudstack @@ -230,6 +229,7 @@ hypervisors/vmware network-elements/cisco-vnmc network-elements/juniper-contrail + network-elements/tungsten diff --git a/server/pom.xml b/server/pom.xml index 782d194fe9e..df4ebdb8237 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -26,12 +26,6 @@ cloudstack 4.19.2.0-SNAPSHOT - - - juniper-tungsten-api - https://github.com/radu-todirica/tungsten-api/raw/master - - @@ -187,11 +181,6 @@ metrics-jvm 3.0.2 - - net.juniper.tungsten - juniper-tungsten-api - 2.0 - diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 0fa5a0d6db3..d0711a9fcf9 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -4042,7 +4042,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C addDefaultInternalLbProviderToPhysicalNetwork(pNetwork.getId()); //Add tungsten network service provider - addDefaultTungstenProviderToPhysicalNetwork(pNetwork.getId()); + try { + addDefaultTungstenProviderToPhysicalNetwork(pNetwork.getId()); + } catch (Exception ex) { + s_logger.warn("Failed to add Tungsten provider to physical network due to:" + ex.getMessage()); + } // Add the config drive provider addConfigDriveToPhysicalNetwork(pNetwork.getId()); From 0a93dcec74281869c4b2f98f0a2889d3824cfe50 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Fri, 20 Sep 2024 17:23:28 +0530 Subject: [PATCH 04/17] ui: load project list with minimum details (#9711) This calls listProjects with details=min in the global header menu. Signed-off-by: Rohit Yadav --- ui/src/components/header/ProjectMenu.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/components/header/ProjectMenu.vue b/ui/src/components/header/ProjectMenu.vue index e2f365344d9..6fb0c3af350 100644 --- a/ui/src/components/header/ProjectMenu.vue +++ b/ui/src/components/header/ProjectMenu.vue @@ -81,7 +81,7 @@ export default { const projects = [] const getNextPage = () => { this.loading = true - api('listProjects', { listAll: true, page: page, pageSize: 500, showIcon: true }).then(json => { + api('listProjects', { listAll: true, page: page, pageSize: 500, details: 'min', showIcon: true }).then(json => { if (json?.listprojectsresponse?.project) { projects.push(...json.listprojectsresponse.project) } From 9df783ca4be80ac028b4df985ddc9d723e024171 Mon Sep 17 00:00:00 2001 From: Vishesh Date: Fri, 20 Sep 2024 20:13:54 +0530 Subject: [PATCH 05/17] Filter out networks without access while getting networks with SG with free IPs (#9596) --- api/src/main/java/com/cloud/network/NetworkModel.java | 2 +- .../src/main/java/com/cloud/network/NetworkModelImpl.java | 8 +++++++- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 4 ++-- .../test/java/com/cloud/network/MockNetworkModelImpl.java | 2 +- .../src/test/java/com/cloud/vpc/MockNetworkModelImpl.java | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/cloud/network/NetworkModel.java b/api/src/main/java/com/cloud/network/NetworkModel.java index 699dcbf6c50..ed3506c0da1 100644 --- a/api/src/main/java/com/cloud/network/NetworkModel.java +++ b/api/src/main/java/com/cloud/network/NetworkModel.java @@ -149,7 +149,7 @@ public interface NetworkModel { boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services); - Network getNetworkWithSGWithFreeIPs(Long zoneId); + Network getNetworkWithSGWithFreeIPs(Account account, Long zoneId); Network getNetworkWithSecurityGroupEnabled(Long zoneId); diff --git a/server/src/main/java/com/cloud/network/NetworkModelImpl.java b/server/src/main/java/com/cloud/network/NetworkModelImpl.java index 4088e9539ea..23018ab72fd 100644 --- a/server/src/main/java/com/cloud/network/NetworkModelImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkModelImpl.java @@ -789,13 +789,19 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi } @Override - public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + public NetworkVO getNetworkWithSGWithFreeIPs(Account account, Long zoneId) { List networks = _networksDao.listByZoneSecurityGroup(zoneId); if (networks == null || networks.isEmpty()) { return null; } NetworkVO ret_network = null; for (NetworkVO nw : networks) { + try { + checkAccountNetworkPermissions(account, nw); + } catch (PermissionDeniedException e) { + continue; + } + List vlans = _vlanDao.listVlansByNetworkId(nw.getId()); for (VlanVO vlan : vlans) { if (_ipAddressDao.countFreeIpsInVlan(vlan.getId()) > 0) { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 3b48378b985..9d5a1be894b 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -3653,7 +3653,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // If no network is specified, find system security group enabled network if (networkIdList == null || networkIdList.isEmpty()) { - Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId()); + Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(owner, zone.getId()); if (networkWithSecurityGroup == null) { throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getUuid()); } @@ -8536,7 +8536,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir private Network getNetworkForOvfNetworkMapping(DataCenter zone, Account owner) throws InsufficientCapacityException, ResourceAllocationException { Network network = null; if (zone.isSecurityGroupEnabled()) { - network = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId()); + network = _networkModel.getNetworkWithSGWithFreeIPs(owner, zone.getId()); if (network == null) { throw new InvalidParameterValueException("No network with security enabled is found in zone ID: " + zone.getUuid()); } diff --git a/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java b/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java index 395be635aea..79f6e8dad35 100644 --- a/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java +++ b/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java @@ -237,7 +237,7 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long) */ @Override - public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + public NetworkVO getNetworkWithSGWithFreeIPs(Account account, Long zoneId) { // TODO Auto-generated method stub return null; } diff --git a/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java b/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java index ad332c00fa4..f0fb6d56a40 100644 --- a/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java @@ -248,7 +248,7 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long) */ @Override - public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) { + public NetworkVO getNetworkWithSGWithFreeIPs(Account account, Long zoneId) { // TODO Auto-generated method stub return null; } From d15a074425166e94642a38318aca327af782140c Mon Sep 17 00:00:00 2001 From: dahn Date: Mon, 23 Sep 2024 10:26:29 +0200 Subject: [PATCH 06/17] Revert "list by displayname instead of name (#8503)" (#9720) This reverts commit 2e9986c6a63af0d07e3c416153ddfdebb9a9a74d. --- ui/src/config/section/compute.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index 4dc1f164514..9bf8c949144 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -46,7 +46,7 @@ export default { return filters }, columns: () => { - const fields = ['displayname', 'state', 'ipaddress'] + const fields = ['name', 'state', 'ipaddress'] const metricsFields = ['cpunumber', 'cputotal', 'cpuused', 'memorytotal', { memoryused: (record) => { @@ -74,7 +74,7 @@ export default { fields.push('zonename') return fields }, - searchFilters: ['displayname', 'zoneid', 'domainid', 'account', 'groupid', 'tags'], + searchFilters: ['name', 'zoneid', 'domainid', 'account', 'groupid', 'tags'], details: () => { var fields = ['name', 'displayname', 'id', 'state', 'ipaddress', 'ip6address', 'templatename', 'ostypename', 'serviceofferingname', 'isdynamicallyscalable', 'haenable', 'hypervisor', 'boottype', 'bootmode', 'account', From 2398b5c8c99437745cbbbdc87373fbb1ed93538a Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 24 Sep 2024 09:18:05 +0200 Subject: [PATCH 07/17] server: apply network ACL even if there is no network ACLs in the ACL list (#9374) --- .../cloudstack/network/topology/AdvancedNetworkTopology.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java b/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java index fc29fcca998..8ee5d12c69a 100644 --- a/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java +++ b/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java @@ -228,11 +228,6 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { public boolean applyNetworkACLs(final Network network, final List rules, final VirtualRouter router, final boolean isPrivateGateway) throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - s_logger.debug("No network ACLs to be applied for network " + network.getId()); - return true; - } - s_logger.debug("APPLYING NETWORK ACLs RULES"); final String typeString = "network acls"; From 53aa92199b2a71168140ae63267a9040f5330dd8 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 25 Sep 2024 20:17:16 +0530 Subject: [PATCH 08/17] server: fix nfs version option during mount (#9559) Signed-off-by: Abhishek Kumar --- .../upgrade/SystemVmTemplateRegistration.java | 42 +++++++++++++++---- .../com/cloud/storage/StorageManagerImpl.java | 8 +++- .../diagnostics/DiagnosticsServiceImpl.java | 3 +- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java b/engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java index 1ee42674480..671fb8c95d5 100644 --- a/engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java +++ b/engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java @@ -49,8 +49,11 @@ import com.cloud.vm.dao.VMInstanceDaoImpl; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -83,7 +86,6 @@ import java.util.stream.Collectors; public class SystemVmTemplateRegistration { private static final Logger LOGGER = Logger.getLogger(SystemVmTemplateRegistration.class); - private static final String MOUNT_COMMAND = "sudo mount -t nfs %s %s"; private static final String UMOUNT_COMMAND = "sudo umount %s"; private static final String RELATIVE_TEMPLATE_PATH = "./engine/schema/dist/systemvm-templates/"; private static final String ABSOLUTE_TEMPLATE_PATH = "/usr/share/cloudstack-management/templates/systemvm/"; @@ -116,6 +118,8 @@ public class SystemVmTemplateRegistration { @Inject ImageStoreDao imageStoreDao; @Inject + ImageStoreDetailsDao imageStoreDetailsDao; + @Inject ClusterDao clusterDao; @Inject ConfigurationDao configurationDao; @@ -129,6 +133,7 @@ public class SystemVmTemplateRegistration { templateDataStoreDao = new BasicTemplateDataStoreDaoImpl(); vmInstanceDao = new VMInstanceDaoImpl(); imageStoreDao = new ImageStoreDaoImpl(); + imageStoreDetailsDao = new ImageStoreDetailsDaoImpl(); clusterDao = new ClusterDaoImpl(); configurationDao = new ConfigurationDaoImpl(); } @@ -141,6 +146,14 @@ public class SystemVmTemplateRegistration { this.systemVmTemplateVersion = systemVmTemplateVersion; } + public static String getMountCommand(String nfsVersion, String device, String dir) { + String cmd = "sudo mount -t nfs"; + if (StringUtils.isNotBlank(nfsVersion)) { + cmd = String.format("%s -o vers=%s", cmd, nfsVersion); + } + return String.format("%s %s %s", cmd, device, dir); + } + public String getSystemVmTemplateVersion() { if (StringUtils.isEmpty(systemVmTemplateVersion)) { return String.format("%s.%s", CS_MAJOR_VERSION, CS_TINY_VERSION); @@ -319,14 +332,14 @@ public class SystemVmTemplateRegistration { } }; - public static boolean validateIfSeeded(String url, String path) { + public static boolean validateIfSeeded(String url, String path, String nfsVersion) { String filePath = null; try { filePath = Files.createTempDirectory(TEMPORARY_SECONDARY_STORE).toString(); if (filePath == null) { throw new CloudRuntimeException("Failed to create temporary directory to mount secondary store"); } - mountStore(url, filePath); + mountStore(url, filePath, nfsVersion); int lastIdx = path.lastIndexOf(File.separator); String partialDirPath = path.substring(0, lastIdx); String templatePath = filePath + File.separator + partialDirPath; @@ -426,14 +439,13 @@ public class SystemVmTemplateRegistration { return new Pair<>(url, storeId); } - public static void mountStore(String storeUrl, String path) { + public static void mountStore(String storeUrl, String path, String nfsVersion) { try { if (storeUrl != null) { URI uri = new URI(UriUtils.encodeURIComponent(storeUrl)); String host = uri.getHost(); String mountPath = uri.getPath(); - String mount = String.format(MOUNT_COMMAND, host + ":" + mountPath, path); - Script.runSimpleBashScript(mount); + Script.runSimpleBashScript(getMountCommand(nfsVersion, host + ":" + mountPath, path)); } } catch (Exception e) { String msg = "NFS Store URL is not in the correct format"; @@ -772,7 +784,8 @@ public class SystemVmTemplateRegistration { throw new CloudRuntimeException("Failed to create temporary file path to mount the store"); } Pair storeUrlAndId = getNfsStoreInZone(zoneId); - mountStore(storeUrlAndId.first(), filePath); + String nfsVersion = getNfsVersion(storeUrlAndId.second()); + mountStore(storeUrlAndId.first(), filePath, nfsVersion); List hypervisorList = fetchAllHypervisors(zoneId); for (String hypervisor : hypervisorList) { Hypervisor.HypervisorType name = Hypervisor.HypervisorType.getType(hypervisor); @@ -783,7 +796,7 @@ public class SystemVmTemplateRegistration { VMTemplateVO templateVO = vmTemplateDao.findById(templateId); TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByTemplate(templateId, DataStoreRole.Image); String installPath = templateDataStoreVO.getInstallPath(); - if (validateIfSeeded(storeUrlAndId.first(), installPath)) { + if (validateIfSeeded(storeUrlAndId.first(), installPath, nfsVersion)) { continue; } else if (templateVO != null) { registerTemplate(hypervisorAndTemplateName, storeUrlAndId, templateVO, templateDataStoreVO, filePath); @@ -888,4 +901,17 @@ public class SystemVmTemplateRegistration { } }); } + + public String getNfsVersion(long storeId) { + final String configKey = "secstorage.nfs.version"; + final Map storeDetails = imageStoreDetailsDao.getDetails(storeId); + if (storeDetails != null && storeDetails.containsKey(configKey)) { + return storeDetails.get(configKey); + } + ConfigurationVO globalNfsVersion = configurationDao.findByName(configKey); + if (globalNfsVersion != null) { + return globalNfsVersion.getValue(); + } + return null; + } } diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 73b9ac8960d..f966098c959 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -391,6 +391,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C ConfigDepot configDepot; @Inject ConfigurationDao configurationDao; + @Inject + private ImageStoreDetailsUtil imageStoreDetailsUtil; protected List _discoverers; @@ -3425,6 +3427,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new CloudRuntimeException("Failed to create temporary file path to mount the store"); } Pair storeUrlAndId = new Pair<>(url, store.getId()); + String nfsVersion = imageStoreDetailsUtil.getNfsVersion(store.getId()); for (HypervisorType hypervisorType : hypSet) { try { if (HypervisorType.Simulator == hypervisorType) { @@ -3441,7 +3444,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C templateVO = _templateStoreDao.findByTemplate(templateId, DataStoreRole.Image); if (templateVO != null) { try { - if (SystemVmTemplateRegistration.validateIfSeeded(url, templateVO.getInstallPath())) { + if (SystemVmTemplateRegistration.validateIfSeeded( + url, templateVO.getInstallPath(), nfsVersion)) { continue; } } catch (Exception e) { @@ -3449,7 +3453,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } } } - SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath); + SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath, nfsVersion); if (templateVO != null && vmTemplateVO != null) { systemVmTemplateRegistration.registerTemplate(hypervisorAndTemplateName, storeUrlAndId, vmTemplateVO, templateVO, filePath); } else { diff --git a/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java b/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java index 72f4a3c5b86..b4081333e87 100644 --- a/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java @@ -480,7 +480,8 @@ public class DiagnosticsServiceImpl extends ManagerBase implements PluggableServ private void cleanupOldDiagnosticFiles(DataStore store) { String mountPoint = null; - mountPoint = serviceImpl.mountManager.getMountPoint(store.getUri(), null); + mountPoint = serviceImpl.mountManager.getMountPoint(store.getUri(), + serviceImpl.imageStoreDetailsUtil.getNfsVersion(store.getId())); if (StringUtils.isNotBlank(mountPoint)) { File directory = new File(mountPoint + File.separator + DIAGNOSTICS_DIRECTORY); if (directory.isDirectory()) { From 4ce86711f96e52b1aec251d72993052c6945ecea Mon Sep 17 00:00:00 2001 From: mprokopchuk Date: Thu, 26 Sep 2024 00:37:18 -0700 Subject: [PATCH 09/17] PowerFlex on demand disable config key (#9664) * Introduced configuration key "powerflex.connect.on.demand" to enable/disable PowerFlex on-demand connection from Host to Storage Pool feature. * Update plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java --------- Co-authored-by: Suresh Kumar Anaparti --- .../manager/ScaleIOSDCManagerImpl.java | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java index 92fe1d83761..4d3a78f6875 100644 --- a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java +++ b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/manager/ScaleIOSDCManagerImpl.java @@ -24,6 +24,8 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.datastore.client.ScaleIOGatewayClient; import org.apache.cloudstack.storage.datastore.client.ScaleIOGatewayClientConnectionPool; @@ -51,9 +53,18 @@ import com.cloud.utils.db.GlobalLock; import com.cloud.utils.exception.CloudRuntimeException; @Component -public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { +public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager, Configurable { private Logger logger = LogManager.getLogger(getClass()); + static ConfigKey ConnectOnDemand = new ConfigKey<>("Storage", + Boolean.class, + "powerflex.connect.on.demand", + Boolean.FALSE.toString(), + "Connect PowerFlex client on Host when first Volume is mapped to SDC and disconnect when last Volume is unmapped from SDC," + + " otherwise no action (that is connection remains in the same state whichever it is, connected or disconnected).", + Boolean.TRUE, + ConfigKey.Scope.Zone); + @Inject AgentManager agentManager; @Inject @@ -94,6 +105,11 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { @Override public String prepareSDC(Host host, DataStore dataStore) { + if (Boolean.FALSE.equals(ConnectOnDemand.valueIn(host.getDataCenterId()))) { + logger.debug(String.format("On-demand connect/disconnect config %s disabled in the zone %d, no need to prepare SDC (check for connected SDC)", ConnectOnDemand.key(), host.getDataCenterId())); + return getConnectedSdc(host, dataStore); + } + String systemId = storagePoolDetailsDao.findDetail(dataStore.getId(), ScaleIOGatewayClient.STORAGE_POOL_SYSTEM_ID).getValue(); if (systemId == null) { throw new CloudRuntimeException("Unable to prepare SDC, failed to get the system id for PowerFlex storage pool: " + dataStore.getName()); @@ -116,7 +132,7 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { long poolId = dataStore.getId(); long hostId = host.getId(); - String sdcId = getConnectedSdc(poolId, hostId); + String sdcId = getConnectedSdc(host, dataStore); if (StringUtils.isNotBlank(sdcId)) { logger.debug(String.format("SDC %s already connected for the pool: %d on host: %d, no need to prepare/start it", sdcId, poolId, hostId)); return sdcId; @@ -227,6 +243,11 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { @Override public boolean stopSDC(Host host, DataStore dataStore) { + if (Boolean.FALSE.equals(ConnectOnDemand.valueIn(host.getDataCenterId()))) { + logger.debug(String.format("On-demand connect/disconnect config %s disabled in the zone %d, no need to unprepare SDC", ConnectOnDemand.key(), host.getDataCenterId())); + return true; + } + String systemId = storagePoolDetailsDao.findDetail(dataStore.getId(), ScaleIOGatewayClient.STORAGE_POOL_SYSTEM_ID).getValue(); if (systemId == null) { throw new CloudRuntimeException("Unable to unprepare SDC, failed to get the system id for PowerFlex storage pool: " + dataStore.getName()); @@ -248,7 +269,7 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { long poolId = dataStore.getId(); long hostId = host.getId(); - String sdcId = getConnectedSdc(poolId, hostId); + String sdcId = getConnectedSdc(host, dataStore); if (StringUtils.isBlank(sdcId)) { logger.debug("SDC not connected, no need to unprepare it"); return true; @@ -297,7 +318,10 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { } } - private String getConnectedSdc(long poolId, long hostId) { + private String getConnectedSdc(Host host, DataStore dataStore) { + long poolId = dataStore.getId(); + long hostId = host.getId(); + try { StoragePoolHostVO poolHostVO = storagePoolHostDao.findByPoolHost(poolId, hostId); if (poolHostVO == null) { @@ -344,4 +368,14 @@ public class ScaleIOSDCManagerImpl implements ScaleIOSDCManager { private ScaleIOGatewayClient getScaleIOClient(final Long storagePoolId) throws Exception { return ScaleIOGatewayClientConnectionPool.getInstance().getClient(storagePoolId, storagePoolDetailsDao); } + + @Override + public String getConfigComponentName() { + return ScaleIOSDCManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[]{ConnectOnDemand}; + } } From bb820f799b0c2628c23c2e520086a3a0ecbfc095 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 26 Sep 2024 13:37:25 +0200 Subject: [PATCH 10/17] CKS: fix creation on shared network if HA is enabled (#8588) --- .../cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java index 4bd6ec65fc3..c98bfd828e3 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java @@ -737,7 +737,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne if (network == null) { throw new InvalidParameterValueException(String.format("%s parameter must be specified along with %s parameter", ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, ApiConstants.NETWORK_ID)); } - if (Network.GuestType.Shared.equals(network.getGuestType())) { + if (!Network.GuestType.Shared.equals(network.getGuestType())) { throw new InvalidParameterValueException(String.format("%s parameter must be specified along with %s type of network", ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, Network.GuestType.Shared.toString())); } } From 04c428cb2f7af7151f5f8ed9bf14e3f140be7ba4 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Fri, 27 Sep 2024 14:09:27 +0200 Subject: [PATCH 11/17] CKS: add ConfigDrive to cloud-init datasource_list in systemvm template (#7650) * CKS: add ConfigDrive to cloud-init datasource_list in systemvm template * systemvm template: update debian 11.7.0 iso url * CKS: get K8S iso by LABEL=CDROM if config drive ISO is attached * Revert "CKS: add ConfigDrive to cloud-init datasource_list in systemvm template" This reverts commit b6863a5ce1b9757d7c5bbf3ba9720e2b61410c7d. * CKS: patch cloud-init in opt/cloud/bin/setup/cksnode.sh * PR7650: move ConfigDrive before CloudStack in datasource list * Revert "CKS: patch cloud-init in opt/cloud/bin/setup/cksnode.sh" This reverts commit 75be03c6aaf58e3939f59c657d84c6495538d3c2. * CKS: fix ConfigDrive --- .../src/main/resources/conf/k8s-control-node-add.yml | 2 +- .../src/main/resources/conf/k8s-control-node.yml | 2 +- .../kubernetes-service/src/main/resources/conf/k8s-node.yml | 2 +- .../src/main/resources/script/upgrade-kubernetes.sh | 2 +- systemvm/debian/opt/cloud/bin/setup/cksnode.sh | 6 ++++++ 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml index 429e2eff098..6819723b3f0 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml @@ -66,7 +66,7 @@ write_files: break fi set +e - output=`blkid -o device -t TYPE=iso9660` + output=`blkid -o device -t LABEL=CDROM` set -e if [ "$output" != "" ]; then while read -r line; do diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml index 4bc2c2c6d3e..90be8957d44 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml @@ -86,7 +86,7 @@ write_files: break fi set +e - output=`blkid -o device -t TYPE=iso9660` + output=`blkid -o device -t LABEL=CDROM` set -e if [ "$output" != "" ]; then while read -r line; do diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml index ad5bb9d19a6..ac80e8576ff 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml @@ -66,7 +66,7 @@ write_files: break fi set +e - output=`blkid -o device -t TYPE=iso9660` + output=`blkid -o device -t LABEL=CDROM` set -e if [ "$output" != "" ]; then while read -r line; do diff --git a/plugins/integrations/kubernetes-service/src/main/resources/script/upgrade-kubernetes.sh b/plugins/integrations/kubernetes-service/src/main/resources/script/upgrade-kubernetes.sh index c092f53359d..480b002ef17 100755 --- a/plugins/integrations/kubernetes-service/src/main/resources/script/upgrade-kubernetes.sh +++ b/plugins/integrations/kubernetes-service/src/main/resources/script/upgrade-kubernetes.sh @@ -54,7 +54,7 @@ while true; do break fi set +e - output=`blkid -o device -t TYPE=iso9660` + output=`blkid -o device -t LABEL=CDROM` set -e if [ "$output" != "" ]; then while read -r line; do diff --git a/systemvm/debian/opt/cloud/bin/setup/cksnode.sh b/systemvm/debian/opt/cloud/bin/setup/cksnode.sh index aa5d466c96a..e1541f6d0bd 100755 --- a/systemvm/debian/opt/cloud/bin/setup/cksnode.sh +++ b/systemvm/debian/opt/cloud/bin/setup/cksnode.sh @@ -59,6 +59,12 @@ setup_k8s_node() { rm -f /etc/logrotate.d/cloud + # Enable cloud-init without any aid from ds-identify + echo "policy: enabled" > /etc/cloud/ds-identify.cfg + + # Add ConfigDrive to datasource_list + sed -i "s/datasource_list: .*/datasource_list: ['ConfigDrive', 'CloudStack']/g" /etc/cloud/cloud.cfg.d/cloudstack.cfg + log_it "Starting cloud-init services" systemctl enable --now --no-block containerd if [ -f /home/cloud/success ]; then From 67ce326a8e50d41fd5c351044d97fe15d504b63b Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Sat, 28 Sep 2024 08:54:45 +0200 Subject: [PATCH 12/17] Fix ISO url in test_usage.py (#9739) --- test/integration/smoke/test_usage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/smoke/test_usage.py b/test/integration/smoke/test_usage.py index 2100859ba52..1a6ff37cedb 100644 --- a/test/integration/smoke/test_usage.py +++ b/test/integration/smoke/test_usage.py @@ -95,7 +95,7 @@ class Services: "iso": { "displaytext": "Test ISO", "name": "Test ISO", - "url": "http://people.apache.org/~tsp/dummy.iso", + "url": "http://download.cloudstack.org/testing/marvin/dummy.iso", # Source URL where ISO is located "isextractable": True, "isfeatured": True, From c15947143430bf6b9b254a50a578281b1af859ba Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Mon, 30 Sep 2024 14:39:45 +0530 Subject: [PATCH 13/17] Shutdown expunged resources cleanup executor properly, and allow other components to configure/start/stop on error (#9723) --- .../com/cloud/cluster/ClusterManagerImpl.java | 6 ++--- .../CloudStackExtendedLifeCycle.java | 22 ++++++++++++++++--- .../CloudStackExtendedLifeCycleStart.java | 1 - .../factory/CloudStackSpringContext.java | 4 +++- .../resource/ResourceCleanupServiceImpl.java | 4 +++- 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java index 050c2a7a1aa..32fdf782696 100644 --- a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java +++ b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java @@ -294,7 +294,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } } } catch (final Throwable e) { - logger.error("Unexcpeted exception: ", e); + logger.error("Unexpected exception: ", e); } } } @@ -346,7 +346,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } }); } catch (final Throwable e) { - logger.error("Unexcpeted exception: ", e); + logger.error("Unexpected exception: ", e); } } } @@ -384,7 +384,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C } executeAsync(peerName, agentId, cmds, true); } catch (final Exception e) { - logger.warn("Caught exception while talkign to " + peer.getMsid()); + logger.warn("Caught exception while talking to " + peer.getMsid()); } } } diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java index 15c1ccac5d9..b913033259c 100644 --- a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycle.java @@ -69,7 +69,12 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector { with(new WithComponentLifeCycle() { @Override public void with(ComponentLifecycle lifecycle) { - lifecycle.start(); + logger.info("starting bean {}.", lifecycle.getName()); + try { + lifecycle.start(); + } catch (Exception e) { + logger.error("Error on starting bean {} - {}", lifecycle.getName(), e.getMessage(), e); + } if (lifecycle instanceof ManagementBean) { ManagementBean mbean = (ManagementBean)lifecycle; @@ -93,13 +98,21 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector { } public void stopBeans() { + logger.info("Stopping CloudStack Components"); + with(new WithComponentLifeCycle() { @Override public void with(ComponentLifecycle lifecycle) { - logger.info("stopping bean " + lifecycle.getName()); - lifecycle.stop(); + logger.info("stopping bean {}.", lifecycle.getName()); + try { + lifecycle.stop(); + } catch (Exception e) { + logger.error("Error on stopping bean {} - {}", lifecycle.getName(), e.getMessage(), e); + } } }); + + logger.info("Done Stopping CloudStack Components"); } private void configure() { @@ -109,10 +122,13 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector { @Override public void with(ComponentLifecycle lifecycle) { try { + logger.info("configuring bean {}.", lifecycle.getName()); lifecycle.configure(lifecycle.getName(), lifecycle.getConfigParams()); } catch (ConfigurationException e) { logger.error("Failed to configure " + lifecycle.getName(), e); throw new CloudRuntimeException(e); + } catch (Exception e) { + logger.error("Error on configuring bean {} - {}", lifecycle.getName(), e.getMessage(), e); } } }); diff --git a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java index 0dc72f93195..85d25ffd9a4 100644 --- a/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java +++ b/framework/spring/lifecycle/src/main/java/org/apache/cloudstack/spring/lifecycle/CloudStackExtendedLifeCycleStart.java @@ -45,5 +45,4 @@ public class CloudStackExtendedLifeCycleStart extends AbstractSmartLifeCycle imp public void run() { lifeCycle.startBeans(); } - } diff --git a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java index 8bbbc35f7e5..361a66fe1ba 100644 --- a/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java +++ b/framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/factory/CloudStackSpringContext.java @@ -77,8 +77,10 @@ public class CloudStackSpringContext { for (String appName : contextMap.keySet()) { ApplicationContext contex = contextMap.get(appName); if (contex instanceof ConfigurableApplicationContext) { - logger.trace("registering shutdown hook for bean "+ appName); + logger.trace("Registering shutdown hook for bean {}.", appName); ((ConfigurableApplicationContext)contex).registerShutdownHook(); + } else { + logger.warn("Shutdown hook not registered for bean {}.", appName); } } } diff --git a/server/src/main/java/org/apache/cloudstack/resource/ResourceCleanupServiceImpl.java b/server/src/main/java/org/apache/cloudstack/resource/ResourceCleanupServiceImpl.java index c4abbb04514..50c4de36b7f 100644 --- a/server/src/main/java/org/apache/cloudstack/resource/ResourceCleanupServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/resource/ResourceCleanupServiceImpl.java @@ -579,7 +579,9 @@ public class ResourceCleanupServiceImpl extends ManagerBase implements ResourceC @Override public boolean stop() { purgeExpungedResourcesJobExecutor.shutdown(); - expungedResourcesCleanupExecutor.shutdownNow(); + if (expungedResourcesCleanupExecutor != null) { + expungedResourcesCleanupExecutor.shutdownNow(); + } return true; } From 046870ef764a2f9fdf091920369f09f05ea0b053 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 30 Sep 2024 14:13:10 +0200 Subject: [PATCH 14/17] debian12: update debian/control (#9738) --- debian/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 8a098e97165..ed4f95d8e49 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: libs Priority: extra Maintainer: Wido den Hollander Build-Depends: debhelper (>= 9), openjdk-17-jdk | java17-sdk | java17-jdk | zulu-17 | openjdk-11-jdk | java11-sdk | java11-jdk | zulu-11, genisoimage, - python-mysql.connector | python3-mysql.connector, maven (>= 3) | maven3, + python-mysql.connector | python3-mysql.connector | mysql-connector-python-py3, maven (>= 3) | maven3, python (>= 2.7) | python2 (>= 2.7), python3 (>= 3), python-setuptools, python3-setuptools, nodejs (>= 12), lsb-release, dh-systemd | debhelper (>= 13) Standards-Version: 3.8.1 @@ -17,7 +17,7 @@ Description: A common package which contains files which are shared by several C Package: cloudstack-management Architecture: all -Depends: ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), net-tools, sudo, python3-mysql.connector, augeas-tools, mysql-client | mariadb-client, adduser, bzip2, ipmitool, file, gawk, iproute2, qemu-utils, rng-tools, python3-dnspython, lsb-release, init-system-helpers (>= 1.14~), python3-setuptools +Depends: ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), net-tools, sudo, python3-mysql.connector | mysql-connector-python-py3, augeas-tools, mysql-client | mariadb-client, adduser, bzip2, ipmitool, file, gawk, iproute2, qemu-utils, rng-tools, python3-dnspython, lsb-release, init-system-helpers (>= 1.14~), python3-setuptools Conflicts: cloud-server, cloud-client, cloud-client-ui Description: CloudStack server library The CloudStack management server From 00fe5f14719d22c429d609657887198d93c1b98f Mon Sep 17 00:00:00 2001 From: dahn Date: Tue, 1 Oct 2024 10:25:31 +0200 Subject: [PATCH 15/17] cleanup validations for VPN connection creation (#9195) --- .../network/vpn/Site2SiteVpnManagerImpl.java | 114 ++++++++++-------- ui/src/views/network/VpcTab.vue | 8 +- 2 files changed, 67 insertions(+), 55 deletions(-) diff --git a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index 51d5f9cf97b..3efe9a8788f 100644 --- a/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -23,11 +23,12 @@ import java.util.Map; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.annotation.AnnotationService; -import org.apache.cloudstack.annotation.dao.AnnotationDao; +import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import org.apache.cloudstack.annotation.AnnotationService; +import org.apache.cloudstack.annotation.dao.AnnotationDao; import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd; import org.apache.cloudstack.api.command.user.vpn.CreateVpnCustomerGatewayCmd; import org.apache.cloudstack.api.command.user.vpn.CreateVpnGatewayCmd; @@ -46,7 +47,6 @@ import com.cloud.configuration.Config; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Site2SiteCustomerGateway; @@ -108,7 +108,6 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn @Inject private AnnotationDao annotationDao; - String _name; int _connLimit; int _subnetsLimit; @@ -255,7 +254,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn @Override @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_CREATE, eventDescription = "creating s2s vpn connection", create = true) - public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException { + public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) { Account caller = CallContext.current().getCallingAccount(); Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); @@ -263,27 +262,15 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn _accountMgr.checkAccess(caller, null, false, owner); Long customerGatewayId = cmd.getCustomerGatewayId(); - Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId); - if (customerGateway == null) { - throw new InvalidParameterValueException("Unable to found specified Site to Site VPN customer gateway " + customerGatewayId + " !"); - } - _accountMgr.checkAccess(caller, null, false, customerGateway); + Site2SiteCustomerGateway customerGateway = getAndValidateSite2SiteCustomerGateway(customerGatewayId, caller); Long vpnGatewayId = cmd.getVpnGatewayId(); - Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(vpnGatewayId); - if (vpnGateway == null) { - throw new InvalidParameterValueException("Unable to found specified Site to Site VPN gateway " + vpnGatewayId + " !"); - } - _accountMgr.checkAccess(caller, null, false, vpnGateway); + Site2SiteVpnGateway vpnGateway = getAndValidateSite2SiteVpnGateway(vpnGatewayId, caller); - if (customerGateway.getAccountId() != vpnGateway.getAccountId() || customerGateway.getDomainId() != vpnGateway.getDomainId()) { - throw new InvalidParameterValueException("VPN connection can only be esitablished between same account's VPN gateway and customer gateway!"); - } + validateVpnConnectionOfTheRightAccount(customerGateway, vpnGateway); + validateVpnConnectionDoesntExist(vpnGatewayId, customerGatewayId); + validatePrerequisiteVpnGateway(vpnGateway); - if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGatewayId, customerGatewayId) != null) { - throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " and vpn gateway id " + vpnGatewayId + - " already existed!"); - } String[] cidrList = customerGateway.getGuestCidrList().split(","); // Remote sub nets cannot overlap VPC's sub net @@ -326,13 +313,51 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn return conn; } + private Site2SiteCustomerGateway getAndValidateSite2SiteCustomerGateway(Long customerGatewayId, Account caller) { + Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId); + if (customerGateway == null) { + throw new InvalidParameterValueException(String.format("Unable to find specified Site to Site VPN customer gateway %s !", customerGatewayId)); + } + _accountMgr.checkAccess(caller, null, false, customerGateway); + return customerGateway; + } + + private Site2SiteVpnGateway getAndValidateSite2SiteVpnGateway(Long vpnGatewayId, Account caller) { + Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(vpnGatewayId); + if (vpnGateway == null) { + throw new InvalidParameterValueException(String.format("Unable to find specified Site to Site VPN gateway %s !", vpnGatewayId)); + } + _accountMgr.checkAccess(caller, null, false, vpnGateway); + return vpnGateway; + } + + private void validateVpnConnectionOfTheRightAccount(Site2SiteCustomerGateway customerGateway, Site2SiteVpnGateway vpnGateway) { + if (customerGateway.getAccountId() != vpnGateway.getAccountId() || customerGateway.getDomainId() != vpnGateway.getDomainId()) { + throw new InvalidParameterValueException("VPN connection can only be established between same account's VPN gateway and customer gateway!"); + } + } + + private void validateVpnConnectionDoesntExist(Long vpnGatewayId, Long customerGatewayId) { + if (_vpnConnectionDao.findByVpnGatewayIdAndCustomerGatewayId(vpnGatewayId, customerGatewayId) != null) { + throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " and vpn gateway id " + vpnGatewayId + + " already existed!"); + } + } + + private void validatePrerequisiteVpnGateway(Site2SiteVpnGateway vpnGateway) { + // check if gateway has been defined on the VPC + if (_vpnGatewayDao.findByVpcId(vpnGateway.getVpcId()) == null) { + throw new InvalidParameterValueException("we can not create a VPN connection for a VPC that does not have a VPN gateway defined"); + } + } + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_CREATE, eventDescription = "starting s2s vpn connection", async = true) public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException { Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id); if (conn == null) { - throw new CloudRuntimeException("Unable to acquire lock on " + conn); + throw new CloudRuntimeException("Unable to acquire lock for starting of VPN connection with ID " + id); } try { if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) { @@ -382,11 +407,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn Account caller = CallContext.current().getCallingAccount(); Long id = cmd.getId(); - Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(id); - if (customerGateway == null) { - throw new InvalidParameterValueException("Fail to find customer gateway with " + id + " !"); - } - _accountMgr.checkAccess(caller, null, false, customerGateway); + Site2SiteCustomerGateway customerGateway = getAndValidateSite2SiteCustomerGateway(id, caller); return doDeleteCustomerGateway(customerGateway); } @@ -394,7 +415,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn protected boolean doDeleteCustomerGateway(Site2SiteCustomerGateway gw) { long id = gw.getId(); List vpnConnections = _vpnConnectionDao.listByCustomerGatewayId(id); - if (vpnConnections != null && vpnConnections.size() != 0) { + if (!CollectionUtils.isEmpty(vpnConnections)) { throw new InvalidParameterValueException("Unable to delete VPN customer gateway with id " + id + " because there is still related VPN connections!"); } annotationDao.removeByEntityType(AnnotationService.EntityType.VPN_CUSTOMER_GATEWAY.name(), gw.getUuid()); @@ -404,7 +425,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn protected void doDeleteVpnGateway(Site2SiteVpnGateway gw) { List conns = _vpnConnectionDao.listByVpnGatewayId(gw.getId()); - if (conns != null && conns.size() != 0) { + if (!CollectionUtils.isEmpty(conns)) { throw new InvalidParameterValueException("Unable to delete VPN gateway " + gw.getId() + " because there is still related VPN connections!"); } _vpnGatewayDao.remove(gw.getId()); @@ -417,12 +438,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn Account caller = CallContext.current().getCallingAccount(); Long id = cmd.getId(); - Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(id); - if (vpnGateway == null) { - throw new InvalidParameterValueException("Fail to find vpn gateway with " + id + " !"); - } - - _accountMgr.checkAccess(caller, null, false, vpnGateway); + Site2SiteVpnGateway vpnGateway = getAndValidateSite2SiteVpnGateway(id, caller); doDeleteVpnGateway(vpnGateway); return true; @@ -578,7 +594,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn private void stopVpnConnection(Long id) throws ResourceUnavailableException { Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id); if (conn == null) { - throw new CloudRuntimeException("Unable to acquire lock on " + conn); + throw new CloudRuntimeException("Unable to acquire lock for stopping of VPN connection with ID " + id); } try { if (conn.getState() == State.Pending) { @@ -639,10 +655,9 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn String keyword = cmd.getKeyword(); Account caller = CallContext.current().getCallingAccount(); - List permittedAccounts = new ArrayList(); + List permittedAccounts = new ArrayList<>(); - Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + Ternary domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null); _accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false); domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); @@ -667,7 +682,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn } Pair, Integer> result = _customerGatewayDao.searchAndCount(sc, searchFilter); - return new Pair, Integer>(result.first(), result.second()); + return new Pair<>(result.first(), result.second()); } @Override @@ -684,10 +699,9 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn long pageSizeVal = cmd.getPageSizeVal(); Account caller = CallContext.current().getCallingAccount(); - List permittedAccounts = new ArrayList(); + List permittedAccounts = new ArrayList<>(); - Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + Ternary domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null); _accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false); domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); @@ -717,7 +731,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn } Pair, Integer> result = _vpnGatewayDao.searchAndCount(sc, searchFilter); - return new Pair, Integer>(result.first(), result.second()); + return new Pair<>(result.first(), result.second()); } @Override @@ -734,10 +748,9 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn long pageSizeVal = cmd.getPageSizeVal(); Account caller = CallContext.current().getCallingAccount(); - List permittedAccounts = new ArrayList(); + List permittedAccounts = new ArrayList<>(); - Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + Ternary domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null); _accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false); domainId = domainIdRecursiveListProject.first(); isRecursive = domainIdRecursiveListProject.second(); @@ -771,7 +784,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn } Pair, Integer> result = _vpnConnectionDao.searchAndCount(sc, searchFilter); - return new Pair, Integer>(result.first(), result.second()); + return new Pair<>(result.first(), result.second()); } @Override @@ -818,7 +831,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn @Override public List getConnectionsForRouter(DomainRouterVO router) { - List conns = new ArrayList(); + List conns = new ArrayList<>(); // One router for one VPC Long vpcId = router.getVpcId(); if (router.getVpcId() == null) { @@ -831,7 +844,6 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn @Override public boolean deleteCustomerGatewayByAccount(long accountId) { boolean result = true; - ; List gws = _customerGatewayDao.listByAccountId(accountId); for (Site2SiteCustomerGatewayVO gw : gws) { result = result & doDeleteCustomerGateway(gw); diff --git a/ui/src/views/network/VpcTab.vue b/ui/src/views/network/VpcTab.vue index 4603e0abf69..657d3c133ac 100644 --- a/ui/src/views/network/VpcTab.vue +++ b/ui/src/views/network/VpcTab.vue @@ -795,12 +795,12 @@ export default { this.formRef.value.validate().then(() => { const values = toRaw(this.form) - - api('createVpnConnection', { - s2svpngatewayid: this.vpnGateways[0].id, + const params = { + s2svpngatewayid: this.vpnGateways[0] ? this.vpnGateways[0].id : null, s2scustomergatewayid: values.vpncustomergateway, passive: values.passive ? values.passive : false - }).then(response => { + } + api('createVpnConnection', params).then(response => { this.$pollJob({ jobId: response.createvpnconnectionresponse.jobid, title: this.$t('label.vpn.connection'), From 28f425a9f97bee9ed505017c119e865cd4ff0a73 Mon Sep 17 00:00:00 2001 From: Felipe <124818914+FelipeM525@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:37:47 -0300 Subject: [PATCH 16/17] Hide UserData field from the EditVM view for VMs that do not offer it (#9731) * added a v-if directive within the EditVm view to not show the field userdata if the vm's network does not offer the feature * added the parameter listall:true to the requests made to listNetworks and listVirtualMachines --- ui/src/views/compute/EditVM.vue | 35 +++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/ui/src/views/compute/EditVM.vue b/ui/src/views/compute/EditVM.vue index 550c4645ed6..876bc7819b4 100644 --- a/ui/src/views/compute/EditVM.vue +++ b/ui/src/views/compute/EditVM.vue @@ -84,7 +84,7 @@ }" :options="groups.opts" /> - + @@ -143,6 +143,7 @@ export default { return { serviceOffering: {}, template: {}, + userDataEnabled: false, securityGroupsEnabled: false, dynamicScalingVmConfig: false, loading: false, @@ -289,15 +290,37 @@ export default { return decodedData.toString('utf-8') }, fetchUserData () { - const params = { - id: this.resource.id, - userdata: true + let networkId + this.resource.nic.forEach(nic => { + if (nic.isdefault) { + networkId = nic.networkid + } + }) + if (!networkId) { + return } + const listNetworkParams = { + id: networkId, + listall: true + } + api(`listNetworks`, listNetworkParams).then(json => { + json.listnetworksresponse.network[0].service.forEach(service => { + if (service.name === 'UserData') { + this.userDataEnabled = true - api('listVirtualMachines', params).then(json => { - this.form.userdata = this.decodeUserData(json.listvirtualmachinesresponse.virtualmachine[0].userdata || '') + const listVmParams = { + id: this.resource.id, + userdata: true, + listall: true + } + api('listVirtualMachines', listVmParams).then(json => { + this.form.userdata = atob(json.listvirtualmachinesresponse.virtualmachine[0].userdata || '') + }) + } + }) }) }, + handleSubmit () { this.formRef.value.validate().then(() => { const values = toRaw(this.form) From 2e4dd69fa179c58c6d785c681d4bafd5000e2d42 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Wed, 2 Oct 2024 09:25:29 -0400 Subject: [PATCH 17/17] API: Fix listing Userdata by keyword or name (#9751) --- .../src/main/java/com/cloud/server/ManagementServerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java index 5ac34fba1d5..c032019510f 100644 --- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java +++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java @@ -4753,7 +4753,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("keyword", sb.entity().getName(), SearchCriteria.Op.LIKE); final SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -4766,7 +4766,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe } if (keyword != null) { - sc.setParameters("name", "%" + keyword + "%"); + sc.setParameters("keyword", "%" + keyword + "%"); } final Pair, Integer> result = userDataDao.searchAndCount(sc, searchFilter);