Merge branch 'netris-release' into netris-phase2

This commit is contained in:
nvazquez 2024-10-03 15:54:16 -03:00
commit 9b97a2a6f6
No known key found for this signature in database
GPG Key ID: 656E1BCC8CB54F84
47 changed files with 570 additions and 168 deletions

View File

@ -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);
@ -360,6 +360,6 @@ public interface NetworkModel {
boolean isSecurityGroupSupportedForZone(Long zoneId);
boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List<Long> networkIds,
boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, List<Long> networkIds,
List<Long> securityGroupsIds);
}

View File

@ -27,18 +27,7 @@
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
</parent>
<repositories>
<repository>
<id>juniper-tungsten-api</id>
<url>https://github.com/radu-todirica/tungsten-api/raw/master</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.juniper.tungsten</groupId>
<artifactId>juniper-tungsten-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
@ -282,11 +271,6 @@
<artifactId>cloud-plugin-network-ovs</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-tungsten</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-elb</artifactId>
@ -1113,6 +1097,11 @@
<artifactId>cloud-plugin-network-nsx</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-tungsten</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-api-vmware-sioc</artifactId>

4
debian/control vendored
View File

@ -3,7 +3,7 @@ Section: libs
Priority: extra
Maintainer: Wido den Hollander <wido@widodh.nl>
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

View File

@ -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;
@ -117,6 +120,8 @@ public class SystemVmTemplateRegistration {
@Inject
ImageStoreDao imageStoreDao;
@Inject
ImageStoreDetailsDao imageStoreDetailsDao;
@Inject
ClusterDao clusterDao;
@Inject
ConfigurationDao configurationDao;
@ -130,6 +135,7 @@ public class SystemVmTemplateRegistration {
templateDataStoreDao = new BasicTemplateDataStoreDaoImpl();
vmInstanceDao = new VMInstanceDaoImpl();
imageStoreDao = new ImageStoreDaoImpl();
imageStoreDetailsDao = new ImageStoreDetailsDaoImpl();
clusterDao = new ClusterDaoImpl();
configurationDao = new ConfigurationDaoImpl();
}
@ -142,6 +148,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);
@ -320,14 +334,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;
@ -427,14 +441,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";
@ -773,7 +786,8 @@ public class SystemVmTemplateRegistration {
throw new CloudRuntimeException("Failed to create temporary file path to mount the store");
}
Pair<String, Long> storeUrlAndId = getNfsStoreInZone(zoneId);
mountStore(storeUrlAndId.first(), filePath);
String nfsVersion = getNfsVersion(storeUrlAndId.second());
mountStore(storeUrlAndId.first(), filePath, nfsVersion);
List<String> hypervisorList = fetchAllHypervisors(zoneId);
for (String hypervisor : hypervisorList) {
Hypervisor.HypervisorType name = Hypervisor.HypervisorType.getType(hypervisor);
@ -784,7 +798,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);
@ -889,4 +903,17 @@ public class SystemVmTemplateRegistration {
}
});
}
public String getNfsVersion(long storeId) {
final String configKey = "secstorage.nfs.version";
final Map<String, String> 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;
}
}

View File

@ -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());
}
}
}

View File

@ -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);
}
}
});

View File

@ -45,5 +45,4 @@ public class CloudStackExtendedLifeCycleStart extends AbstractSmartLifeCycle imp
public void run() {
lifeCycle.startBeans();
}
}

View File

@ -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);
}
}
}

View File

@ -83,11 +83,6 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-tungsten</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -836,9 +836,8 @@ 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 (isDirectAccess(network)) {
throw new InvalidParameterValueException(String.format("%s parameter must be specified along with %s network or %s network",
ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, Network.GuestType.Shared, NetworkOffering.NetworkMode.ROUTED));
if (!Network.GuestType.Shared.equals(network.getGuestType()) || routedIpv4Manager.isRoutedNetwork(network)) {
throw new InvalidParameterValueException(String.format("%s parameter must be specified when network type is not %s or is %s network", ApiConstants.EXTERNAL_LOAD_BALANCER_IP_ADDRESS, Network.GuestType.Shared, NetworkOffering.NetworkMode.ROUTED));
}
}

View File

@ -406,7 +406,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
if (StringUtils.isNotBlank(kubernetesCluster.getKeyPair())) {
keypairs.add(kubernetesCluster.getKeyPair());
}
if (kubernetesCluster.getSecurityGroupId() != null && networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) {
if (kubernetesCluster.getSecurityGroupId() != null && networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) {
List<Long> securityGroupIds = new ArrayList<>();
securityGroupIds.add(kubernetesCluster.getSecurityGroupId());
nodeVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner,

View File

@ -217,7 +217,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
keypairs.add(kubernetesCluster.getKeyPair());
}
if (kubernetesCluster.getSecurityGroupId() != null &&
networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds,
networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds,
List.of(kubernetesCluster.getSecurityGroupId()))) {
List<Long> securityGroupIds = new ArrayList<>();
securityGroupIds.add(kubernetesCluster.getSecurityGroupId());
@ -294,7 +294,8 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
keypairs.add(kubernetesCluster.getKeyPair());
}
if (kubernetesCluster.getSecurityGroupId() != null &&
networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) {
networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds,
List.of(kubernetesCluster.getSecurityGroupId()))) {
List<Long> securityGroupIds = new ArrayList<>();
securityGroupIds.add(kubernetesCluster.getSecurityGroupId());
additionalControlVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -30,13 +30,6 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<repositories>
<repository>
<id>juniper-tungsten-api</id>
<url>https://github.com/radu-todirica/tungsten-api/raw/master</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.juniper.tungsten</groupId>

View File

@ -114,7 +114,6 @@
<module>network-elements/stratosphere-ssp</module>
<module>network-elements/brocade-vcs</module>
<module>network-elements/vxlan</module>
<module>network-elements/tungsten</module>
<module>outofbandmanagement-drivers/ipmitool</module>
<module>outofbandmanagement-drivers/nested-cloudstack</module>
@ -236,6 +235,7 @@
<module>network-elements/cisco-vnmc</module>
<module>network-elements/nsx</module>
<module>network-elements/juniper-contrail</module>
<module>network-elements/tungsten</module>
</modules>
</profile>
<profile>

View File

@ -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<Boolean> 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};
}
}

View File

@ -26,12 +26,6 @@
<artifactId>cloudstack</artifactId>
<version>4.20.0.0-SNAPSHOT</version>
</parent>
<repositories>
<repository>
<id>juniper-tungsten-api</id>
<url>https://github.com/radu-todirica/tungsten-api/raw/master</url>
</repository>
</repositories>
<dependencies>
<dependency>
@ -197,11 +191,6 @@
<artifactId>metrics-jvm</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>net.juniper.tungsten</groupId>
<artifactId>juniper-tungsten-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -788,13 +788,19 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
}
@Override
public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) {
public NetworkVO getNetworkWithSGWithFreeIPs(Account account, Long zoneId) {
List<NetworkVO> 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<VlanVO> vlans = _vlanDao.listVlansByNetworkId(nw.getId());
for (VlanVO vlan : vlans) {
if (_ipAddressDao.countFreeIpsInVlan(vlan.getId()) > 0) {
@ -2775,7 +2781,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
}
@Override
public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List<Long> networkIds,
public boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone,
List<Long> networkIds,
List<Long> securityGroupsIds) {
if (zone.isSecurityGroupEnabled()) {
return true;
@ -2791,7 +2798,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
}
}
} else if (CollectionUtils.isNotEmpty(securityGroupsIds)) {
Network networkWithSecurityGroup = getNetworkWithSGWithFreeIPs(zone.getId());
Network networkWithSecurityGroup = getNetworkWithSGWithFreeIPs(account, zone.getId());
return networkWithSecurityGroup != null;
}
return false;

View File

@ -4220,7 +4220,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) {
logger.warn("Failed to add Tungsten provider to physical network due to:" + ex.getMessage());
}
// Add the config drive provider
addConfigDriveToPhysicalNetwork(pNetwork.getId());

View File

@ -1812,7 +1812,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
null, null, true, null, affinityGroupIdList, customParameters, null, null, null,
null, true, overrideDiskOfferingId);
} else {
if (networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds,
if (networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds,
Collections.emptyList())) {
vm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, null,
owner, vmHostName,vmHostName, diskOfferingId, dataDiskSize, null,

View File

@ -23,10 +23,11 @@ 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.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;
@ -45,7 +46,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;
@ -106,7 +106,6 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
@Inject
private AnnotationDao annotationDao;
String _name;
int _connLimit;
int _subnetsLimit;
@ -253,7 +252,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());
@ -261,27 +260,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
@ -324,13 +311,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) {
@ -380,11 +405,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);
}
@ -392,7 +413,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
protected boolean doDeleteCustomerGateway(Site2SiteCustomerGateway gw) {
long id = gw.getId();
List<Site2SiteVpnConnectionVO> 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());
@ -402,7 +423,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
protected void doDeleteVpnGateway(Site2SiteVpnGateway gw) {
List<Site2SiteVpnConnectionVO> 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());
@ -415,12 +436,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;
@ -576,7 +592,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) {
@ -637,10 +653,9 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
String keyword = cmd.getKeyword();
Account caller = CallContext.current().getCallingAccount();
List<Long> permittedAccounts = new ArrayList<Long>();
List<Long> permittedAccounts = new ArrayList<>();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
ListProjectResourcesCriteria>(domainId, isRecursive, null);
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@ -665,7 +680,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
}
Pair<List<Site2SiteCustomerGatewayVO>, Integer> result = _customerGatewayDao.searchAndCount(sc, searchFilter);
return new Pair<List<? extends Site2SiteCustomerGateway>, Integer>(result.first(), result.second());
return new Pair<>(result.first(), result.second());
}
@Override
@ -682,10 +697,9 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
long pageSizeVal = cmd.getPageSizeVal();
Account caller = CallContext.current().getCallingAccount();
List<Long> permittedAccounts = new ArrayList<Long>();
List<Long> permittedAccounts = new ArrayList<>();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
ListProjectResourcesCriteria>(domainId, isRecursive, null);
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@ -715,7 +729,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
}
Pair<List<Site2SiteVpnGatewayVO>, Integer> result = _vpnGatewayDao.searchAndCount(sc, searchFilter);
return new Pair<List<? extends Site2SiteVpnGateway>, Integer>(result.first(), result.second());
return new Pair<>(result.first(), result.second());
}
@Override
@ -732,10 +746,9 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
long pageSizeVal = cmd.getPageSizeVal();
Account caller = CallContext.current().getCallingAccount();
List<Long> permittedAccounts = new ArrayList<Long>();
List<Long> permittedAccounts = new ArrayList<>();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
ListProjectResourcesCriteria>(domainId, isRecursive, null);
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@ -769,7 +782,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
}
Pair<List<Site2SiteVpnConnectionVO>, Integer> result = _vpnConnectionDao.searchAndCount(sc, searchFilter);
return new Pair<List<? extends Site2SiteVpnConnection>, Integer>(result.first(), result.second());
return new Pair<>(result.first(), result.second());
}
@Override
@ -816,7 +829,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
@Override
public List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router) {
List<Site2SiteVpnConnectionVO> conns = new ArrayList<Site2SiteVpnConnectionVO>();
List<Site2SiteVpnConnectionVO> conns = new ArrayList<>();
// One router for one VPC
Long vpcId = router.getVpcId();
if (router.getVpcId() == null) {
@ -829,7 +842,6 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn
@Override
public boolean deleteCustomerGatewayByAccount(long accountId) {
boolean result = true;
;
List<Site2SiteCustomerGatewayVO> gws = _customerGatewayDao.listByAccountId(accountId);
for (Site2SiteCustomerGatewayVO gw : gws) {
result = result & doDeleteCustomerGateway(gw);

View File

@ -4859,7 +4859,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<UserDataVO> sc = sb.create();
_accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
@ -4872,7 +4872,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
}
if (keyword != null) {
sc.setParameters("name", "%" + keyword + "%");
sc.setParameters("keyword", "%" + keyword + "%");
}
final Pair<List<UserDataVO>, Integer> result = userDataDao.searchAndCount(sc, searchFilter);

View File

@ -389,6 +389,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
ConfigDepot configDepot;
@Inject
ConfigurationDao configurationDao;
@Inject
private ImageStoreDetailsUtil imageStoreDetailsUtil;
protected List<StoragePoolDiscoverer> _discoverers;
@ -3488,6 +3490,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
throw new CloudRuntimeException("Failed to create temporary file path to mount the store");
}
Pair<String, Long> storeUrlAndId = new Pair<>(url, store.getId());
String nfsVersion = imageStoreDetailsUtil.getNfsVersion(store.getId());
for (HypervisorType hypervisorType : hypSet) {
try {
if (HypervisorType.Simulator == hypervisorType) {
@ -3504,7 +3507,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) {
@ -3512,7 +3516,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 {

View File

@ -3126,11 +3126,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Network defaultNetwork = null;
try {
DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
if (zone.getNetworkType() == NetworkType.Basic) {
// Get default guest network in Basic zone
defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
} else if (_networkModel.checkSecurityGroupSupportForNetwork(zone, Collections.emptyList(), securityGroupIdList)) {
} else if (_networkModel.checkSecurityGroupSupportForNetwork(_accountMgr.getActiveAccountById(vm.getAccountId()), zone, Collections.emptyList(), securityGroupIdList)) {
NicVO defaultNic = _nicDao.findDefaultNicForVM(vm.getId());
if (defaultNic != null) {
defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
@ -3759,7 +3758,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());
}
@ -6205,7 +6204,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, overrideDiskOfferingId);
}
} else {
if (_networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds,
if (_networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds,
cmd.getSecurityGroupIdList())) {
vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd, zone, template, owner), owner, name,
displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, userDataId, userDataDetails, sshKeyPairNames, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard,
@ -7629,7 +7628,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Set<NetworkVO> applicableNetworks = new LinkedHashSet<>();
Map<Long, String> requestedIPv4ForNics = new HashMap<>();
Map<Long, String> requestedIPv6ForNics = new HashMap<>();
if (_networkModel.checkSecurityGroupSupportForNetwork(zone, networkIdList, securityGroupIdList)) { // advanced zone with security groups
if (_networkModel.checkSecurityGroupSupportForNetwork(newAccount, zone, networkIdList, securityGroupIdList)) { // advanced zone with security groups
// cleanup the old security groups
_securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
// if networkIdList is null and the first network of vm is shared network, then keep it if possible
@ -8859,7 +8858,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() || _networkModel.isSecurityGroupSupportedForZone(zone.getId())) {
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());
}

View File

@ -478,7 +478,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()) {

View File

@ -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;
}

View File

@ -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;
}
@ -950,7 +950,7 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
}
@Override
public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List<Long> networkIds, List<Long> securityGroupsIds) {
public boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, List<Long> networkIds, List<Long> securityGroupsIds) {
return false;
}
}

View File

@ -1318,7 +1318,8 @@ public class AutoScaleManagerImplTest {
when(userVmService.createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), any(),
any(), any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), any(), any(), any(),
any(), any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock);
when(networkModel.checkSecurityGroupSupportForNetwork(zoneMock, List.of(networkId), Collections.emptyList())).thenReturn(true);
when(networkModel.checkSecurityGroupSupportForNetwork(account, zoneMock,
List.of(networkId), Collections.emptyList())).thenReturn(true);
long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock);
@ -1367,7 +1368,8 @@ public class AutoScaleManagerImplTest {
when(userVmService.createAdvancedVirtualMachine(any(), any(), any(), any(), any(), any(), any(),
any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), eq(true), any(), any(), any(),
any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock);
when(networkModel.checkSecurityGroupSupportForNetwork(zoneMock, List.of(networkId), Collections.emptyList())).thenReturn(false);
when(networkModel.checkSecurityGroupSupportForNetwork(account, zoneMock,
List.of(networkId), Collections.emptyList())).thenReturn(false);
long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock);

View File

@ -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;
}
@ -966,7 +966,8 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
}
@Override
public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List<Long> networkIds, List<Long> securityGroupsIds) {
public boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone,
List<Long> networkIds, List<Long> securityGroupsIds) {
return false;
}
}

View File

@ -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

View File

@ -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,

View File

@ -19,8 +19,7 @@
FROM ubuntu:22.04
MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0.0-SNAPSHOT"
LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0.0-SNAPSHOT" Author="Apache CloudStack <dev@cloudstack.apache.org>"
ARG DEBIAN_FRONTEND=noninteractive

View File

@ -19,8 +19,7 @@
# build for cloudstack_home_dir not this folder
FROM python:2
MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0.0-SNAPSHOT"
LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0.0-SNAPSHOT" Author="Apache CloudStack <dev@cloudstack.apache.org>"
ENV WORK_DIR=/marvin

View File

@ -19,8 +19,7 @@
FROM ubuntu:16.04
MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0-SNAPSHOT"
LABEL Vendor="Apache.org" License="ApacheV2" Version="4.20.0-SNAPSHOT" Author="Apache CloudStack <dev@cloudstack.apache.org>"
RUN apt-get -y update && apt-get install -y \
genisoimage \

View File

@ -19,11 +19,11 @@
FROM node:14-bullseye AS build
MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
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 <dev@cloudstack.apache.org>"
WORKDIR /build

View File

@ -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)
}

View File

@ -47,7 +47,7 @@ export default {
return filters
},
columns: () => {
const fields = ['displayname', 'state', 'ipaddress']
const fields = ['name', 'state', 'ipaddress']
const metricsFields = ['cpunumber', 'cputotal', 'cpuused', 'memorytotal',
{
memoryused: (record) => {
@ -77,7 +77,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',

View File

@ -84,7 +84,7 @@
}"
:options="groups.opts" />
</a-form-item>
<a-form-item>
<a-form-item v-if="userDataEnabled">
<template #label>
<tooltip-label :title="$t('label.userdata')" :tooltip="apiParams.userdata.description"/>
</template>
@ -150,6 +150,7 @@ export default {
return {
serviceOffering: {},
template: {},
userDataEnabled: false,
securityGroupsEnabled: false,
dynamicScalingVmConfig: false,
loading: false,
@ -297,15 +298,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)

View File

@ -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')) {

View File

@ -800,12 +800,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'),