mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.11'
This commit is contained in:
commit
9146d7b7a0
@ -56,6 +56,7 @@ public interface VirtualMachineProfile {
|
||||
public static final Param VmSshPubKey = new Param("VmSshPubKey");
|
||||
public static final Param ControlNic = new Param("ControlNic");
|
||||
public static final Param ReProgramGuestNetworks = new Param("RestartNetwork");
|
||||
public static final Param RollingRestart = new Param("RollingRestart");
|
||||
public static final Param PxeSeverType = new Param("PxeSeverType");
|
||||
public static final Param HaTag = new Param("HaTag");
|
||||
public static final Param HaOperation = new Param("HaOperation");
|
||||
@ -173,4 +174,6 @@ public interface VirtualMachineProfile {
|
||||
|
||||
Float getMemoryOvercommitRatio();
|
||||
|
||||
boolean isRollingRestart();
|
||||
|
||||
}
|
||||
|
||||
@ -263,6 +263,11 @@ public class VirtualMachineProfileImpl implements VirtualMachineProfile {
|
||||
return memoryOvercommitRatio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRollingRestart() {
|
||||
return Boolean.TRUE.equals(getParameter(VirtualMachineProfile.Param.RollingRestart));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String[]> getVmData() {
|
||||
return vmData;
|
||||
|
||||
@ -26,11 +26,12 @@ public class ConfigDrive {
|
||||
public static final String openStackConfigDriveName = "/openstack/latest/";
|
||||
|
||||
/**
|
||||
* This is the path to iso file relative to mount point
|
||||
* @return config drive iso file path
|
||||
* Creates the path to ISO file relative to mount point.
|
||||
* The config driver path will have the following formated: {@link #CONFIGDRIVEDIR} + / + instanceName + / + {@link #CONFIGDRIVEFILENAME}
|
||||
*
|
||||
* @return config drive ISO file path
|
||||
*/
|
||||
public static String createConfigDrivePath(final String instanceName) {
|
||||
public static String createConfigDrivePath(String instanceName) {
|
||||
return ConfigDrive.CONFIGDRIVEDIR + "/" + instanceName + "/" + ConfigDrive.CONFIGDRIVEFILENAME;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -23,9 +23,7 @@ import static com.cloud.network.NetworkModel.CONFIGDATA_FILE;
|
||||
import static com.cloud.network.NetworkModel.PASSWORD_FILE;
|
||||
import static com.cloud.network.NetworkModel.USERDATA_FILE;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@ -42,7 +40,6 @@ import org.joda.time.Duration;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@ -51,30 +48,45 @@ public class ConfigDriveBuilder {
|
||||
|
||||
public static final Logger LOG = Logger.getLogger(ConfigDriveBuilder.class);
|
||||
|
||||
private static void writeFile(final File folder, final String file, final String content) {
|
||||
if (folder == null || Strings.isNullOrEmpty(file)) {
|
||||
return;
|
||||
}
|
||||
final File vendorDataFile = new File(folder, file);
|
||||
try (final FileWriter fw = new FileWriter(vendorDataFile); final BufferedWriter bw = new BufferedWriter(fw)) {
|
||||
bw.write(content);
|
||||
/**
|
||||
* Writes a content {@link String} to a file that is going to be created in a folder. We will not append to the file if it already exists. Therefore, its content will be overwritten.
|
||||
* Moreover, the charset used is {@link com.cloud.utils.StringUtils#getPreferredCharset()}.
|
||||
*
|
||||
* We expect the folder object and the file not to be null/empty.
|
||||
*/
|
||||
static void writeFile(File folder, String file, String content) {
|
||||
try {
|
||||
FileUtils.write(new File(folder, file), content, com.cloud.utils.StringUtils.getPreferredCharset(), false);
|
||||
} catch (IOException ex) {
|
||||
throw new CloudRuntimeException("Failed to create config drive file " + file, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static String fileToBase64String(final File isoFile) throws IOException {
|
||||
/**
|
||||
* Read the content of a {@link File} and convert it to a String in base 64.
|
||||
* We expect the content of the file to be encoded using {@link StandardCharsets#US_ASC}
|
||||
*/
|
||||
public static String fileToBase64String(File isoFile) throws IOException {
|
||||
byte[] encoded = Base64.encodeBase64(FileUtils.readFileToByteArray(isoFile));
|
||||
return new String(encoded, StandardCharsets.US_ASCII);
|
||||
}
|
||||
|
||||
public static File base64StringToFile(final String encodedIsoData, final String folder, final String fileName) throws IOException {
|
||||
/**
|
||||
* Writes a String encoded in base 64 to a file in the given folder.
|
||||
* The content will be decoded and then written to the file. Be aware that we will overwrite the content of the file if it already exists.
|
||||
* Moreover, the content will must be encoded in {@link StandardCharsets#US_ASCII} before it is encoded in base 64.
|
||||
*/
|
||||
public static File base64StringToFile(String encodedIsoData, String folder, String fileName) throws IOException {
|
||||
byte[] decoded = Base64.decodeBase64(encodedIsoData.getBytes(StandardCharsets.US_ASCII));
|
||||
Path destPath = Paths.get(folder, fileName);
|
||||
return Files.write(destPath, decoded).toFile();
|
||||
}
|
||||
|
||||
public static String buildConfigDrive(final List<String[]> vmData, final String isoFileName, final String driveLabel) {
|
||||
/**
|
||||
* This method will build the metadata files required by OpenStack driver. Then, an ISO is going to be generated and returned as a String in base 64.
|
||||
* If vmData is null, we throw a {@link CloudRuntimeException}. Moreover, {@link IOException} are captured and re-thrown as {@link CloudRuntimeException}.
|
||||
*/
|
||||
public static String buildConfigDrive(List<String[]> vmData, String isoFileName, String driveLabel) {
|
||||
if (vmData == null) {
|
||||
throw new CloudRuntimeException("No VM metadata provided");
|
||||
}
|
||||
@ -86,103 +98,180 @@ public class ConfigDriveBuilder {
|
||||
tempDirName = tempDir.toString();
|
||||
|
||||
File openStackFolder = new File(tempDirName + ConfigDrive.openStackConfigDriveName);
|
||||
if (openStackFolder.exists() || openStackFolder.mkdirs()) {
|
||||
writeFile(openStackFolder, "vendor_data.json", "{}");
|
||||
writeFile(openStackFolder, "network_data.json", "{}");
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create folder " + openStackFolder);
|
||||
}
|
||||
|
||||
JsonObject metaData = new JsonObject();
|
||||
for (String[] item : vmData) {
|
||||
String dataType = item[CONFIGDATA_DIR];
|
||||
String fileName = item[CONFIGDATA_FILE];
|
||||
String content = item[CONFIGDATA_CONTENT];
|
||||
LOG.debug(String.format("[createConfigDriveIsoForVM] dataType=%s, filename=%s, content=%s",
|
||||
dataType, fileName, (fileName.equals(PASSWORD_FILE)?"********":content)));
|
||||
writeVendorAndNetworkEmptyJsonFile(openStackFolder);
|
||||
writeVmMetadata(vmData, tempDirName, openStackFolder);
|
||||
|
||||
// create file with content in folder
|
||||
if (dataType != null && !dataType.isEmpty()) {
|
||||
//create folder
|
||||
File typeFolder = new File(tempDirName + ConfigDrive.cloudStackConfigDriveName + dataType);
|
||||
if (typeFolder.exists() || typeFolder.mkdirs()) {
|
||||
if (StringUtils.isNotEmpty(content)) {
|
||||
File file = new File(typeFolder, fileName + ".txt");
|
||||
try {
|
||||
if (fileName.equals(USERDATA_FILE)) {
|
||||
// User Data is passed as a base64 encoded string
|
||||
FileUtils.writeByteArrayToFile(file, Base64.decodeBase64(content));
|
||||
} else {
|
||||
FileUtils.write(file, content, com.cloud.utils.StringUtils.getPreferredCharset());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new CloudRuntimeException("Failed to create file ", ex);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create folder: " + typeFolder);
|
||||
}
|
||||
linkUserData(tempDirName);
|
||||
|
||||
//now write the file to the OpenStack directory
|
||||
metaData = buildOpenStackMetaData(metaData, dataType, fileName, content);
|
||||
}
|
||||
}
|
||||
writeFile(openStackFolder, "meta_data.json", metaData.toString());
|
||||
|
||||
String linkResult = linkUserData(tempDirName);
|
||||
if (linkResult != null) {
|
||||
String errMsg = "Unable to create user_data link due to " + linkResult;
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
File tmpIsoStore = new File(tempDirName, new File(isoFileName).getName());
|
||||
Script command = new Script("/usr/bin/genisoimage", Duration.standardSeconds(300), LOG);
|
||||
command.add("-o", tmpIsoStore.getAbsolutePath());
|
||||
command.add("-ldots");
|
||||
command.add("-allow-lowercase");
|
||||
command.add("-allow-multidot");
|
||||
command.add("-cache-inodes"); // Enable caching inode and device numbers to find hard links to files.
|
||||
command.add("-l");
|
||||
command.add("-quiet");
|
||||
command.add("-J");
|
||||
command.add("-r");
|
||||
command.add("-V", driveLabel);
|
||||
command.add(tempDirName);
|
||||
LOG.debug("Executing config drive creation command: " + command.toString());
|
||||
String result = command.execute();
|
||||
if (result != null) {
|
||||
String errMsg = "Unable to create iso file: " + isoFileName + " due to " + result;
|
||||
LOG.warn(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
File tmpIsoFile = new File(tmpIsoStore.getAbsolutePath());
|
||||
// Max allowed file size of config drive is 64MB: https://docs.openstack.org/project-install-guide/baremetal/draft/configdrive.html
|
||||
if (tmpIsoFile.length() > (64L * 1024L * 1024L)) {
|
||||
throw new CloudRuntimeException("Config drive file exceeds maximum allowed size of 64MB");
|
||||
}
|
||||
return fileToBase64String(tmpIsoFile);
|
||||
return generateAndRetrieveIsoAsBase64Iso(isoFileName, driveLabel, tempDirName);
|
||||
} catch (IOException e) {
|
||||
throw new CloudRuntimeException("Failed due to", e);
|
||||
} finally {
|
||||
try {
|
||||
FileUtils.deleteDirectory(tempDir.toFile());
|
||||
} catch (IOException ioe) {
|
||||
LOG.warn("Failed to delete ConfigDrive temporary directory: " + tempDirName, ioe);
|
||||
}
|
||||
deleteTempDir(tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
private static String linkUserData(String tempDirName) {
|
||||
//Hard link the user_data.txt file with the user_data file in the OpenStack directory.
|
||||
private static void deleteTempDir(Path tempDir) {
|
||||
try {
|
||||
if (tempDir != null) {
|
||||
FileUtils.deleteDirectory(tempDir.toFile());
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
LOG.warn("Failed to delete ConfigDrive temporary directory: " + tempDir.toString(), ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the ISO file that has the tempDir content.
|
||||
*
|
||||
* Max allowed file size of config drive is 64MB [1]. Therefore, if the ISO is bigger than that, we throw a {@link CloudRuntimeException}.
|
||||
* [1] https://docs.openstack.org/project-install-guide/baremetal/draft/configdrive.html
|
||||
*/
|
||||
static String generateAndRetrieveIsoAsBase64Iso(String isoFileName, String driveLabel, String tempDirName) throws IOException {
|
||||
File tmpIsoStore = new File(tempDirName, isoFileName);
|
||||
Script command = new Script(getProgramToGenerateIso(), Duration.standardSeconds(300), LOG);
|
||||
command.add("-o", tmpIsoStore.getAbsolutePath());
|
||||
command.add("-ldots");
|
||||
command.add("-allow-lowercase");
|
||||
command.add("-allow-multidot");
|
||||
command.add("-cache-inodes"); // Enable caching inode and device numbers to find hard links to files.
|
||||
command.add("-l");
|
||||
command.add("-quiet");
|
||||
command.add("-J");
|
||||
command.add("-r");
|
||||
command.add("-V", driveLabel);
|
||||
command.add(tempDirName);
|
||||
LOG.debug("Executing config drive creation command: " + command.toString());
|
||||
String result = command.execute();
|
||||
if (StringUtils.isNotBlank(result)) {
|
||||
String errMsg = "Unable to create iso file: " + isoFileName + " due to ge" + result;
|
||||
LOG.warn(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
File tmpIsoFile = new File(tmpIsoStore.getAbsolutePath());
|
||||
if (tmpIsoFile.length() > (64L * 1024L * 1024L)) {
|
||||
throw new CloudRuntimeException("Config drive file exceeds maximum allowed size of 64MB");
|
||||
}
|
||||
return fileToBase64String(tmpIsoFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the 'genisoimage' or 'mkisofs' is available and return the full qualified path for the program.
|
||||
* The path checked are the following:
|
||||
* <ul>
|
||||
* <li> /usr/bin/genisoimage
|
||||
* <li> /usr/bin/mkisofs
|
||||
* </ul> /usr/local/bin/mkisofs
|
||||
*/
|
||||
static String getProgramToGenerateIso() throws IOException {
|
||||
File isoCreator = new File("/usr/bin/genisoimage");
|
||||
if (!isoCreator.exists()) {
|
||||
isoCreator = new File("/usr/bin/mkisofs");
|
||||
if (!isoCreator.exists()) {
|
||||
isoCreator = new File("/usr/local/bin/mkisofs");
|
||||
}
|
||||
}
|
||||
if (!isoCreator.exists()) {
|
||||
throw new CloudRuntimeException("Cannot create iso for config drive using any know tool. Known paths [/usr/bin/genisoimage, /usr/bin/mkisofs, /usr/local/bin/mkisofs]");
|
||||
}
|
||||
if (!isoCreator.canExecute()) {
|
||||
throw new CloudRuntimeException("Cannot create iso for config drive using: " + isoCreator.getCanonicalPath());
|
||||
}
|
||||
return isoCreator.getCanonicalPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* First we generate a JSON object using {@link #createJsonObjectWithVmData(List, String)}, then we write it to a file called "meta_data.json".
|
||||
*/
|
||||
static void writeVmMetadata(List<String[]> vmData, String tempDirName, File openStackFolder) {
|
||||
JsonObject metaData = createJsonObjectWithVmData(vmData, tempDirName);
|
||||
writeFile(openStackFolder, "meta_data.json", metaData.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the following empty JSON files:
|
||||
* <ul>
|
||||
* <li> vendor_data.json
|
||||
* <li> network_data.json
|
||||
* </ul>
|
||||
*
|
||||
* If the folder does not exist and we cannot create it, we throw a {@link CloudRuntimeException}.
|
||||
*/
|
||||
static void writeVendorAndNetworkEmptyJsonFile(File openStackFolder) {
|
||||
if (openStackFolder.exists() || openStackFolder.mkdirs()) {
|
||||
writeFile(openStackFolder, "vendor_data.json", "{}");
|
||||
writeFile(openStackFolder, "network_data.json", "{}");
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create folder " + openStackFolder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@link JsonObject} with VM's metadata. The vmData is a list of arrays; we expect this list to have the following entries:
|
||||
* <ul>
|
||||
* <li> [0]: config data type
|
||||
* <li> [1]: config data file name
|
||||
* <li> [2]: config data file content
|
||||
* </ul>
|
||||
*/
|
||||
static JsonObject createJsonObjectWithVmData(List<String[]> vmData, String tempDirName) {
|
||||
JsonObject metaData = new JsonObject();
|
||||
for (String[] item : vmData) {
|
||||
String dataType = item[CONFIGDATA_DIR];
|
||||
String fileName = item[CONFIGDATA_FILE];
|
||||
String content = item[CONFIGDATA_CONTENT];
|
||||
LOG.debug(String.format("[createConfigDriveIsoForVM] dataType=%s, filename=%s, content=%s", dataType, fileName, (PASSWORD_FILE.equals(fileName) ? "********" : content)));
|
||||
|
||||
createFileInTempDirAnAppendOpenStackMetadataToJsonObject(tempDirName, metaData, dataType, fileName, content);
|
||||
}
|
||||
return metaData;
|
||||
}
|
||||
|
||||
static void createFileInTempDirAnAppendOpenStackMetadataToJsonObject(String tempDirName, JsonObject metaData, String dataType, String fileName, String content) {
|
||||
if (StringUtils.isBlank(dataType)) {
|
||||
return;
|
||||
}
|
||||
//create folder
|
||||
File typeFolder = new File(tempDirName + ConfigDrive.cloudStackConfigDriveName + dataType);
|
||||
if (!typeFolder.exists() && !typeFolder.mkdirs()) {
|
||||
throw new CloudRuntimeException("Failed to create folder: " + typeFolder);
|
||||
}
|
||||
if (StringUtils.isNotBlank(content)) {
|
||||
File file = new File(typeFolder, fileName + ".txt");
|
||||
try {
|
||||
if (fileName.equals(USERDATA_FILE)) {
|
||||
// User Data is passed as a base64 encoded string
|
||||
FileUtils.writeByteArrayToFile(file, Base64.decodeBase64(content));
|
||||
} else {
|
||||
FileUtils.write(file, content, com.cloud.utils.StringUtils.getPreferredCharset());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new CloudRuntimeException("Failed to create file ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
//now write the file to the OpenStack directory
|
||||
buildOpenStackMetaData(metaData, dataType, fileName, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hard link the user_data.txt file with the user_data file in the OpenStack directory.
|
||||
*/
|
||||
static void linkUserData(String tempDirName) {
|
||||
String userDataFilePath = tempDirName + ConfigDrive.cloudStackConfigDriveName + "userdata/user_data.txt";
|
||||
if ((new File(userDataFilePath).exists())) {
|
||||
File file = new File(userDataFilePath);
|
||||
if (file.exists()) {
|
||||
Script hardLink = new Script("ln", Duration.standardSeconds(300), LOG);
|
||||
hardLink.add(userDataFilePath);
|
||||
hardLink.add(tempDirName + ConfigDrive.openStackConfigDriveName + "user_data");
|
||||
LOG.debug("execute command: " + hardLink.toString());
|
||||
return hardLink.execute();
|
||||
|
||||
String executionResult = hardLink.execute();
|
||||
if (StringUtils.isNotBlank(executionResult)) {
|
||||
throw new CloudRuntimeException("Unable to create user_data link due to " + executionResult);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static JsonArray arrayOf(JsonElement... elements) {
|
||||
@ -193,30 +282,33 @@ public class ConfigDriveBuilder {
|
||||
return array;
|
||||
}
|
||||
|
||||
private static JsonObject buildOpenStackMetaData(JsonObject metaData, String dataType, String fileName, String content) {
|
||||
if (dataType.equals(NetworkModel.METATDATA_DIR) && StringUtils.isNotEmpty(content)) {
|
||||
//keys are a special case in OpenStack format
|
||||
if (NetworkModel.PUBLIC_KEYS_FILE.equals(fileName)) {
|
||||
String[] keyArray = content.replace("\\n", "").split(" ");
|
||||
String keyName = "key";
|
||||
if (keyArray.length > 3 && StringUtils.isNotEmpty(keyArray[2])){
|
||||
keyName = keyArray[2];
|
||||
}
|
||||
|
||||
JsonObject keyLegacy = new JsonObject();
|
||||
keyLegacy.addProperty("type", "ssh");
|
||||
keyLegacy.addProperty("data", content.replace("\\n", ""));
|
||||
keyLegacy.addProperty("name", keyName);
|
||||
metaData.add("keys", arrayOf(keyLegacy));
|
||||
|
||||
JsonObject key = new JsonObject();
|
||||
key.addProperty(keyName, content);
|
||||
metaData.add("public_keys", key);
|
||||
} else if (NetworkModel.openStackFileMapping.get(fileName) != null) {
|
||||
metaData.addProperty(NetworkModel.openStackFileMapping.get(fileName), content);
|
||||
}
|
||||
private static void buildOpenStackMetaData(JsonObject metaData, String dataType, String fileName, String content) {
|
||||
if (!NetworkModel.METATDATA_DIR.equals(dataType)) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isNotBlank(content)) {
|
||||
return;
|
||||
}
|
||||
//keys are a special case in OpenStack format
|
||||
if (NetworkModel.PUBLIC_KEYS_FILE.equals(fileName)) {
|
||||
String[] keyArray = content.replace("\\n", "").split(" ");
|
||||
String keyName = "key";
|
||||
if (keyArray.length > 3 && StringUtils.isNotEmpty(keyArray[2])) {
|
||||
keyName = keyArray[2];
|
||||
}
|
||||
|
||||
JsonObject keyLegacy = new JsonObject();
|
||||
keyLegacy.addProperty("type", "ssh");
|
||||
keyLegacy.addProperty("data", content.replace("\\n", ""));
|
||||
keyLegacy.addProperty("name", keyName);
|
||||
metaData.add("keys", arrayOf(keyLegacy));
|
||||
|
||||
JsonObject key = new JsonObject();
|
||||
key.addProperty(keyName, content);
|
||||
metaData.add("public_keys", key);
|
||||
} else if (NetworkModel.openStackFileMapping.get(fileName) != null) {
|
||||
metaData.addProperty(NetworkModel.openStackFileMapping.get(fileName), content);
|
||||
}
|
||||
return metaData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,49 +17,481 @@
|
||||
|
||||
package org.apache.cloudstack.storage.configdrive;
|
||||
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.reflections.ReflectionUtils;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({FileUtils.class})
|
||||
public class ConfigDriveBuilderTest {
|
||||
|
||||
@Test
|
||||
public void testConfigDriveIsoPath() throws IOException {
|
||||
Assert.assertEquals(ConfigDrive.createConfigDrivePath("i-x-y"), "configdrive/i-x-y/configdrive.iso");
|
||||
public void writeFileTest() throws Exception {
|
||||
PowerMockito.mockStatic(FileUtils.class);
|
||||
|
||||
ConfigDriveBuilder.writeFile(new File("folder"), "subfolder", "content");
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
FileUtils.write(Mockito.any(File.class), Mockito.anyString(), Mockito.any(Charset.class), Mockito.eq(false));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void writeFileTestwriteFileTestIOExceptionWhileWritingFile() throws Exception {
|
||||
PowerMockito.mockStatic(FileUtils.class);
|
||||
|
||||
//Does not look good, I know... but this is the price of static methods.
|
||||
Method method = ReflectionUtils.getMethods(FileUtils.class, ReflectionUtils.withParameters(File.class, CharSequence.class, Charset.class, Boolean.TYPE)).iterator().next();
|
||||
PowerMockito.when(FileUtils.class, method).withArguments(Mockito.any(File.class), Mockito.anyString(), Mockito.any(Charset.class), Mockito.anyBoolean()).thenThrow(IOException.class);
|
||||
|
||||
ConfigDriveBuilder.writeFile(new File("folder"), "subfolder", "content");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigDriveBuild() throws IOException {
|
||||
List<String[]> actualVmData = Arrays.asList(
|
||||
new String[]{"userdata", "user_data", "c29tZSB1c2VyIGRhdGE="},
|
||||
new String[]{"metadata", "service-offering", "offering"},
|
||||
new String[]{"metadata", "availability-zone", "zone1"},
|
||||
new String[]{"metadata", "local-hostname", "hostname"},
|
||||
new String[]{"metadata", "local-ipv4", "192.168.111.111"},
|
||||
new String[]{"metadata", "public-hostname", "7.7.7.7"},
|
||||
new String[]{"metadata", "public-ipv4", "7.7.7.7"},
|
||||
new String[]{"metadata", "vm-id", "uuid"},
|
||||
new String[]{"metadata", "instance-id", "i-x-y"},
|
||||
new String[]{"metadata", "public-keys", "ssh-rsa some-key"},
|
||||
new String[]{"metadata", "cloud-identifier", String.format("CloudStack-{%s}", "uuid")},
|
||||
new String[]{"password", "vm_password", "password123"}
|
||||
);
|
||||
public void fileToBase64StringTest() throws Exception {
|
||||
PowerMockito.mockStatic(FileUtils.class);
|
||||
|
||||
final Path tempDir = Files.createTempDirectory(ConfigDrive.CONFIGDRIVEDIR);
|
||||
final String isoData = ConfigDriveBuilder.buildConfigDrive(actualVmData, "i-x-y.iso", "config-2");
|
||||
final File isoFile = ConfigDriveBuilder.base64StringToFile(isoData, tempDir.toAbsolutePath().toString(), ConfigDrive.CONFIGDRIVEFILENAME);
|
||||
String fileContent = "content";
|
||||
Method method = getFileUtilsReadfileToByteArrayMethod();
|
||||
PowerMockito.when(FileUtils.class, method).withArguments(Mockito.any(File.class)).thenReturn(fileContent.getBytes());
|
||||
|
||||
Assert.assertTrue(isoFile.exists());
|
||||
Assert.assertTrue(isoFile.isFile());
|
||||
Assert.assertTrue(isoFile.length() > 0L);
|
||||
String returnedContentInBase64 = ConfigDriveBuilder.fileToBase64String(new File("file"));
|
||||
|
||||
FileUtils.deleteDirectory(tempDir.toFile());
|
||||
Assert.assertEquals("Y29udGVudA==", returnedContentInBase64);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = IOException.class)
|
||||
public void fileToBase64StringTestIOException() throws Exception {
|
||||
PowerMockito.mockStatic(FileUtils.class);
|
||||
|
||||
Method method = getFileUtilsReadfileToByteArrayMethod();
|
||||
PowerMockito.when(FileUtils.class, method).withArguments(Mockito.any(File.class)).thenThrow(IOException.class);
|
||||
|
||||
ConfigDriveBuilder.fileToBase64String(new File("file"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Method getFileUtilsReadfileToByteArrayMethod() {
|
||||
return ReflectionUtils.getMethods(FileUtils.class, ReflectionUtils.withName("readFileToByteArray")).iterator().next();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void base64StringToFileTest() throws Exception {
|
||||
String encodedIsoData = "Y29udGVudA==";
|
||||
|
||||
String parentFolder = "parentFolder";
|
||||
String fileName = "fileName";
|
||||
|
||||
File parentFolderFile = new File(parentFolder);
|
||||
parentFolderFile.mkdir();
|
||||
|
||||
ConfigDriveBuilder.base64StringToFile(encodedIsoData, parentFolder, fileName);
|
||||
|
||||
File file = new File(parentFolderFile, fileName);
|
||||
String contentOfFile = new String(FileUtils.readFileToByteArray(file), StandardCharsets.US_ASCII);
|
||||
|
||||
Assert.assertEquals("content", contentOfFile);
|
||||
|
||||
file.delete();
|
||||
parentFolderFile.delete();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void buildConfigDriveTestNoVmData() {
|
||||
ConfigDriveBuilder.buildConfigDrive(null, "teste", "C:");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void buildConfigDriveTestIoException() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("writeVendorAndNetworkEmptyJsonFile")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.any(File.class)).thenThrow(IOException.class);
|
||||
|
||||
//This is odd, but it was necessary to allow us to check if we catch the IOexception and re-throw as a CloudRuntimeException
|
||||
//We are mocking the class being tested; therefore, we needed to force the execution of the real method we want to test.
|
||||
PowerMockito.when(ConfigDriveBuilder.class, new ArrayList<>(), "teste", "C:").thenCallRealMethod();
|
||||
|
||||
ConfigDriveBuilder.buildConfigDrive(new ArrayList<>(), "teste", "C:");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void buildConfigDriveTest() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method writeVendorAndNetworkEmptyJsonFileMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("writeVendorAndNetworkEmptyJsonFile")).iterator().next();
|
||||
PowerMockito.doNothing().when(ConfigDriveBuilder.class, writeVendorAndNetworkEmptyJsonFileMethod).withArguments(Mockito.any(File.class));
|
||||
|
||||
Method writeVmMetadataMethod = getWriteVmMetadataMethod();
|
||||
PowerMockito.doNothing().when(ConfigDriveBuilder.class, writeVmMetadataMethod).withArguments(Mockito.anyListOf(String[].class), Mockito.anyString(), Mockito.any(File.class));
|
||||
|
||||
Method linkUserDataMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("linkUserData")).iterator().next();
|
||||
PowerMockito.doNothing().when(ConfigDriveBuilder.class, linkUserDataMethod).withArguments(Mockito.anyString());
|
||||
|
||||
Method generateAndRetrieveIsoAsBase64IsoMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("generateAndRetrieveIsoAsBase64Iso")).iterator().next();
|
||||
PowerMockito.doReturn("mockIsoDataBase64").when(ConfigDriveBuilder.class, generateAndRetrieveIsoAsBase64IsoMethod).withArguments(Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
|
||||
|
||||
//force execution of real method
|
||||
PowerMockito.when(ConfigDriveBuilder.class, new ArrayList<>(), "teste", "C:").thenCallRealMethod();
|
||||
|
||||
String returnedIsoData = ConfigDriveBuilder.buildConfigDrive(new ArrayList<>(), "teste", "C:");
|
||||
|
||||
Assert.assertEquals("mockIsoDataBase64", returnedIsoData);
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
ConfigDriveBuilder.writeVendorAndNetworkEmptyJsonFile(Mockito.any(File.class));
|
||||
ConfigDriveBuilder.writeVmMetadata(Mockito.anyListOf(String[].class), Mockito.anyString(), Mockito.any(File.class));
|
||||
ConfigDriveBuilder.linkUserData(Mockito.anyString());
|
||||
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso(Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Method getWriteVmMetadataMethod() {
|
||||
return ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("writeVmMetadata")).iterator().next();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void writeVendorAndNetworkEmptyJsonFileTestCannotCreateOpenStackFolder() {
|
||||
File folderFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(folderFileMock).mkdirs();
|
||||
|
||||
ConfigDriveBuilder.writeVendorAndNetworkEmptyJsonFile(folderFileMock);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void writeVendorAndNetworkEmptyJsonFileTest() {
|
||||
File folderFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(folderFileMock).mkdirs();
|
||||
|
||||
ConfigDriveBuilder.writeVendorAndNetworkEmptyJsonFile(folderFileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void writeVendorAndNetworkEmptyJsonFileTestCreatingFolder() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
File folderFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(folderFileMock).exists();
|
||||
Mockito.doReturn(true).when(folderFileMock).mkdirs();
|
||||
|
||||
//force execution of real method
|
||||
Method writeVendorAndNetworkEmptyJsonFileMethod = getWriteVendorAndNetworkEmptyJsonFileMethod();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, writeVendorAndNetworkEmptyJsonFileMethod).withArguments(folderFileMock).thenCallRealMethod();
|
||||
|
||||
ConfigDriveBuilder.writeVendorAndNetworkEmptyJsonFile(folderFileMock);
|
||||
|
||||
Mockito.verify(folderFileMock).exists();
|
||||
Mockito.verify(folderFileMock).mkdirs();
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
ConfigDriveBuilder.writeFile(Mockito.any(File.class), Mockito.eq("vendor_data.json"), Mockito.eq("{}"));
|
||||
ConfigDriveBuilder.writeFile(Mockito.any(File.class), Mockito.eq("network_data.json"), Mockito.eq("{}"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Method getWriteVendorAndNetworkEmptyJsonFileMethod() {
|
||||
return ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("writeVendorAndNetworkEmptyJsonFile")).iterator().next();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void writeVmMetadataTest() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method method = getWriteVmMetadataMethod();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(new ArrayList<>(), "metadataFile", new File("folder")).thenCallRealMethod();
|
||||
|
||||
Method createJsonObjectWithVmDataMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("createJsonObjectWithVmData")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, createJsonObjectWithVmDataMethod).withArguments(Mockito.anyListOf(String[].class), Mockito.any(File.class)).thenReturn(new JsonObject());
|
||||
|
||||
ConfigDriveBuilder.writeVmMetadata(new ArrayList<>(), "metadataFile", new File("folder"));
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
ConfigDriveBuilder.createJsonObjectWithVmData(Mockito.anyListOf(String[].class), Mockito.anyString());
|
||||
ConfigDriveBuilder.writeFile(Mockito.any(File.class), Mockito.eq("meta_data.json"), Mockito.eq("{}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void linkUserDataTestUserDataFilePathDoesNotExist() throws Exception {
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(fileMock).exists();
|
||||
|
||||
PowerMockito.mockStatic(File.class, Script.class);
|
||||
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
ConfigDriveBuilder.linkUserData("test");
|
||||
|
||||
Mockito.verify(scriptMock, times(0)).execute();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void linkUserDataTestUserDataFilePathExistAndExecutionPresentedSomeError() throws Exception {
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(fileMock).exists();
|
||||
|
||||
PowerMockito.mockStatic(File.class, Script.class);
|
||||
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.doReturn("message").when(scriptMock).execute();
|
||||
ConfigDriveBuilder.linkUserData("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void linkUserDataTest() throws Exception {
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(fileMock).exists();
|
||||
|
||||
PowerMockito.mockStatic(File.class, Script.class);
|
||||
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.doReturn(StringUtils.EMPTY).when(scriptMock).execute();
|
||||
String tempDirName = "test";
|
||||
ConfigDriveBuilder.linkUserData(tempDirName);
|
||||
|
||||
Mockito.verify(scriptMock).add(tempDirName + ConfigDrive.cloudStackConfigDriveName + "userdata/user_data.txt");
|
||||
Mockito.verify(scriptMock).add(tempDirName + ConfigDrive.openStackConfigDriveName + "user_data");
|
||||
Mockito.verify(scriptMock).execute();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@PrepareForTest({Script.class, ConfigDriveBuilder.class})
|
||||
public void generateAndRetrieveIsoAsBase64IsoTestGenIsoFailure() throws Exception {
|
||||
PowerMockito.mockStatic(Script.class, ConfigDriveBuilder.class);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.doReturn("scriptMessage").when(scriptMock).execute();
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("generateAndRetrieveIsoAsBase64Iso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.any(File.class), Mockito.any(File.class), Mockito.any(File.class)).thenCallRealMethod();
|
||||
|
||||
Method getProgramToGenerateIsoMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("getProgramToGenerateIso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, getProgramToGenerateIsoMethod).withNoArguments().thenReturn("/usr/bin/genisoimage");
|
||||
|
||||
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso("isoFileName", "driveLabel", "tempDirName");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void generateAndRetrieveIsoAsBase64IsoTestIsoTooBig() throws Exception {
|
||||
PowerMockito.mockStatic(File.class, Script.class, ConfigDriveBuilder.class);
|
||||
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
PowerMockito.whenNew(File.class).withAnyArguments().thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.doReturn(StringUtils.EMPTY).when(scriptMock).execute();
|
||||
Mockito.doReturn(64L * 1024L * 1024L + 1l).when(fileMock).length();
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("generateAndRetrieveIsoAsBase64Iso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.any(File.class), Mockito.any(File.class), Mockito.any(File.class)).thenCallRealMethod();
|
||||
|
||||
Method getProgramToGenerateIsoMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("getProgramToGenerateIso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, getProgramToGenerateIsoMethod).withNoArguments().thenReturn("/usr/bin/genisoimage");
|
||||
|
||||
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso("isoFileName", "driveLabel", "tempDirName");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void generateAndRetrieveIsoAsBase64IsoTest() throws Exception {
|
||||
PowerMockito.mockStatic(File.class, Script.class, ConfigDriveBuilder.class);
|
||||
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
PowerMockito.whenNew(File.class).withArguments("tempDirName", "isoFileName").thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.when(fileMock.getAbsolutePath()).thenReturn("absolutePath");
|
||||
Mockito.doReturn(StringUtils.EMPTY).when(scriptMock).execute();
|
||||
Mockito.doReturn(64L * 1024L * 1024L).when(fileMock).length();
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("generateAndRetrieveIsoAsBase64Iso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.any(File.class), Mockito.any(File.class), Mockito.any(File.class)).thenCallRealMethod();
|
||||
|
||||
Method getProgramToGenerateIsoMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("getProgramToGenerateIso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, getProgramToGenerateIsoMethod).withNoArguments().thenReturn("/usr/bin/genisoimage");
|
||||
|
||||
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso("isoFileName", "driveLabel", "tempDirName");
|
||||
|
||||
InOrder inOrder = Mockito.inOrder(scriptMock);
|
||||
inOrder.verify(scriptMock).add("-o", "absolutePath");
|
||||
inOrder.verify(scriptMock).add("-ldots");
|
||||
inOrder.verify(scriptMock).add("-allow-lowercase");
|
||||
inOrder.verify(scriptMock).add("-allow-multidot");
|
||||
inOrder.verify(scriptMock).add("-cache-inodes");
|
||||
inOrder.verify(scriptMock).add("-l");
|
||||
inOrder.verify(scriptMock).add("-quiet");
|
||||
inOrder.verify(scriptMock).add("-J");
|
||||
inOrder.verify(scriptMock).add("-r");
|
||||
inOrder.verify(scriptMock).add("-V", "driveLabel");
|
||||
inOrder.verify(scriptMock).add("tempDirName");
|
||||
inOrder.verify(scriptMock).execute();
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
ConfigDriveBuilder.fileToBase64String(Mockito.any(File.class));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void createJsonObjectWithVmDataTesT() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("createJsonObjectWithVmData")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.anyListOf(String[].class), Mockito.anyString()).thenCallRealMethod();
|
||||
|
||||
List<String[]> vmData = new ArrayList<>();
|
||||
vmData.add(new String[] {"dataType", "fileName", "content"});
|
||||
vmData.add(new String[] {"dataType2", "fileName2", "content2"});
|
||||
|
||||
ConfigDriveBuilder.createJsonObjectWithVmData(vmData, "tempDirName");
|
||||
|
||||
PowerMockito.verifyStatic(Mockito.times(1));
|
||||
ConfigDriveBuilder.createFileInTempDirAnAppendOpenStackMetadataToJsonObject(Mockito.eq("tempDirName"), Mockito.any(JsonObject.class), Mockito.eq("dataType"), Mockito.eq("fileName"),
|
||||
Mockito.eq("content"));
|
||||
ConfigDriveBuilder.createFileInTempDirAnAppendOpenStackMetadataToJsonObject(Mockito.eq("tempDirName"), Mockito.any(JsonObject.class), Mockito.eq("dataType2"), Mockito.eq("fileName2"),
|
||||
Mockito.eq("content2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, ConfigDriveBuilder.class})
|
||||
public void getProgramToGenerateIsoTestGenIsoExistsAndIsExecutable() throws Exception {
|
||||
PowerMockito.mockStatic(File.class);
|
||||
|
||||
File genIsoFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(genIsoFileMock).exists();
|
||||
Mockito.doReturn(true).when(genIsoFileMock).canExecute();
|
||||
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/genisoimage").thenReturn(genIsoFileMock);
|
||||
|
||||
ConfigDriveBuilder.getProgramToGenerateIso();
|
||||
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(2)).exists();
|
||||
Mockito.verify(genIsoFileMock).canExecute();
|
||||
Mockito.verify(genIsoFileMock).getCanonicalPath();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@PrepareForTest({File.class, ConfigDriveBuilder.class})
|
||||
public void getProgramToGenerateIsoTestGenIsoExistsbutNotExecutable() throws Exception {
|
||||
PowerMockito.mockStatic(File.class);
|
||||
|
||||
File genIsoFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(genIsoFileMock).exists();
|
||||
Mockito.doReturn(false).when(genIsoFileMock).canExecute();
|
||||
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/genisoimage").thenReturn(genIsoFileMock);
|
||||
|
||||
ConfigDriveBuilder.getProgramToGenerateIso();
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, ConfigDriveBuilder.class})
|
||||
public void getProgramToGenerateIsoTestNotGenIsoMkIsoInLinux() throws Exception {
|
||||
PowerMockito.mockStatic(File.class);
|
||||
|
||||
File genIsoFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(genIsoFileMock).exists();
|
||||
|
||||
File mkIsoProgramInLinuxFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(mkIsoProgramInLinuxFileMock).exists();
|
||||
Mockito.doReturn(true).when(mkIsoProgramInLinuxFileMock).canExecute();
|
||||
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/genisoimage").thenReturn(genIsoFileMock);
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/mkisofs").thenReturn(mkIsoProgramInLinuxFileMock);
|
||||
|
||||
ConfigDriveBuilder.getProgramToGenerateIso();
|
||||
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(1)).exists();
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(0)).canExecute();
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(0)).getCanonicalPath();
|
||||
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(2)).exists();
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(1)).canExecute();
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(1)).getCanonicalPath();
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, ConfigDriveBuilder.class})
|
||||
public void getProgramToGenerateIsoTestMkIsoMac() throws Exception {
|
||||
PowerMockito.mockStatic(File.class);
|
||||
|
||||
File genIsoFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(genIsoFileMock).exists();
|
||||
|
||||
File mkIsoProgramInLinuxFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(mkIsoProgramInLinuxFileMock).exists();
|
||||
|
||||
File mkIsoProgramInMacOsFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(mkIsoProgramInMacOsFileMock).exists();
|
||||
Mockito.doReturn(true).when(mkIsoProgramInMacOsFileMock).canExecute();
|
||||
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/genisoimage").thenReturn(genIsoFileMock);
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/mkisofs").thenReturn(mkIsoProgramInLinuxFileMock);
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/local/bin/mkisofs").thenReturn(mkIsoProgramInMacOsFileMock);
|
||||
|
||||
ConfigDriveBuilder.getProgramToGenerateIso();
|
||||
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(1)).exists();
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(0)).canExecute();
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(0)).getCanonicalPath();
|
||||
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(1)).exists();
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(0)).canExecute();
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(0)).getCanonicalPath();
|
||||
|
||||
Mockito.verify(mkIsoProgramInMacOsFileMock, Mockito.times(1)).exists();
|
||||
Mockito.verify(mkIsoProgramInMacOsFileMock, Mockito.times(1)).canExecute();
|
||||
Mockito.verify(mkIsoProgramInMacOsFileMock, Mockito.times(1)).getCanonicalPath();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
// 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.storage.configdrive;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ConfigDriveTest {
|
||||
|
||||
@Test
|
||||
public void testConfigDriveIsoPath() throws IOException {
|
||||
Assert.assertEquals(ConfigDrive.createConfigDrivePath("i-x-y"), "configdrive/i-x-y/configdrive.iso");
|
||||
}
|
||||
|
||||
}
|
||||
@ -1375,7 +1375,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
|
||||
|
||||
if (!result.first()) {
|
||||
s_logger.error("Unable to copy haproxy configuration file");
|
||||
return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to uanble to copy haproxy configuration file");
|
||||
return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to unable to copy haproxy configuration file");
|
||||
}
|
||||
|
||||
final String command = String.format("%s%s %s", "/root/", VRScripts.LB, args);
|
||||
|
||||
@ -54,6 +54,7 @@ import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupVspCommand;
|
||||
import com.cloud.agent.api.element.ApplyAclRuleVspCommand;
|
||||
@ -289,14 +290,41 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering);
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
|
||||
ImplementVspCommand cmd = new ImplementVspCommand(vspNetwork, ingressFirewallRules, egressFirewallRules, floatingIpUuids, vspDhcpOptions);
|
||||
send(cmd, network);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void send(Command cmd, Network network)
|
||||
throws ResourceUnavailableException {
|
||||
send(cmd, network.getPhysicalNetworkId(), Network.class, network);
|
||||
}
|
||||
|
||||
private void send(Command cmd, Vpc vpc)
|
||||
throws ResourceUnavailableException {
|
||||
send(cmd, getPhysicalNetworkId(vpc.getZoneId()), Vpc.class, vpc);
|
||||
}
|
||||
|
||||
|
||||
private <R extends InternalIdentity> void send(Command cmd, long physicalNetworkId, Class<R> resourceClass,
|
||||
R resource)
|
||||
throws ResourceUnavailableException {
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("ImplementVspCommand for network " + network.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
throw new ResourceUnavailableException(answer.getDetails(), Network.class, network.getId());
|
||||
if (isFailure(answer)) {
|
||||
s_logger.error(cmd.getClass().getName() + " for " + resourceClass.getName() + " " + resource.getId() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
|
||||
if (hasFailureDetails(answer)) {
|
||||
throw new ResourceUnavailableException(answer.getDetails(), resourceClass, resource.getId());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasFailureDetails(Answer answer) {
|
||||
return (null != answer) && (null != answer.getDetails());
|
||||
}
|
||||
|
||||
private boolean isFailure(Answer answer) {
|
||||
return answer == null || !answer.getResult();
|
||||
}
|
||||
|
||||
private boolean applyACLRulesForVpc(Network network, NetworkOffering offering) throws ResourceUnavailableException {
|
||||
@ -358,15 +386,9 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
NetworkOfferingVO networkOfferingVO = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
|
||||
VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, networkOfferingVO);
|
||||
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
|
||||
|
||||
ShutDownVspCommand cmd = new ShutDownVspCommand(vspNetwork, vspDhcpOptions);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("ShutDownVspCommand for network " + network.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
throw new ResourceUnavailableException(answer.getDetails(), Network.class, network.getId());
|
||||
}
|
||||
}
|
||||
send(cmd, network);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -501,14 +523,17 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
|
||||
@Override
|
||||
public boolean setExtraDhcpOptions(Network network, long nicId, Map<Integer, String> dhcpOptions) {
|
||||
if (network.isRollingRestart()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
|
||||
NicVO nic = _nicDao.findById(nicId);
|
||||
|
||||
ExtraDhcpOptionsVspCommand extraDhcpOptionsVspCommand = new ExtraDhcpOptionsVspCommand(vspNetwork, nic.getUuid(), dhcpOptions);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), extraDhcpOptionsVspCommand);
|
||||
|
||||
if (answer == null || !answer.getResult()) {
|
||||
if (isFailure(answer)) {
|
||||
s_logger.error("[setExtraDhcpOptions] setting extra DHCP options for nic " + nic.getUuid() + " failed.");
|
||||
return false;
|
||||
}
|
||||
@ -539,15 +564,9 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
}
|
||||
|
||||
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(config);
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(config.getPhysicalNetworkId());
|
||||
ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(vspNetwork, vspStaticNatDetails);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("ApplyStaticNatNuageVspCommand for network " + config.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
throw new ResourceUnavailableException(answer.getDetails(), Network.class, config.getId());
|
||||
}
|
||||
}
|
||||
send(cmd,
|
||||
config);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -611,16 +630,10 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
}
|
||||
});
|
||||
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
|
||||
VspAclRule.ACLType vspAclType = isNetworkAcl ? VspAclRule.ACLType.NetworkACL : VspAclRule.ACLType.Firewall;
|
||||
ApplyAclRuleVspCommand cmd = new ApplyAclRuleVspCommand(vspAclType, vspNetwork, vspAclRules, networkReset);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("ApplyAclRuleNuageVspCommand for network " + network.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
throw new ResourceUnavailableException(answer.getDetails(), Network.class, network.getId());
|
||||
}
|
||||
}
|
||||
send(cmd,
|
||||
network);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -686,7 +699,6 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
});
|
||||
|
||||
Domain vpcDomain = _domainDao.findById(vpc.getDomainId());
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(getPhysicalNetworkId(vpc.getZoneId()));
|
||||
|
||||
String preConfiguredDomainTemplateName;
|
||||
VpcDetailVO domainTemplateNameDetail = _vpcDetailsDao.findDetail(vpc.getId(), NuageVspManager.nuageDomainTemplateDetailName);
|
||||
@ -710,14 +722,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
}
|
||||
|
||||
ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand(vpcDomain.getUuid(), vpc.getUuid(), preConfiguredDomainTemplateName, domainRouterUuids, vpcDetails);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("ShutDownVpcVspCommand for VPC " + vpc.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
throw new ResourceUnavailableException(answer.getDetails(), Vpc.class, vpc.getId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
send(cmd, vpc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -82,6 +82,7 @@ import com.cloud.network.dao.NetworkDetailsDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.manager.NuageVspManager;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
||||
@ -94,6 +95,7 @@ import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.Ip;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicVO;
|
||||
@ -101,6 +103,7 @@ import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public class NuageVspGuestNetworkGuru extends GuestNetworkGuru implements NetworkGuruAdditionalFunctions {
|
||||
@ -134,6 +137,8 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru implements Networ
|
||||
DataCenterDetailsDao _dcDetailsDao;
|
||||
@Inject
|
||||
VlanDetailsDao _vlanDetailsDao;
|
||||
@Inject
|
||||
private DomainRouterDao _routerDao;
|
||||
|
||||
public NuageVspGuestNetworkGuru() {
|
||||
super();
|
||||
@ -528,29 +533,34 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru implements Networ
|
||||
nic.setBroadcastUri(network.getBroadcastUri());
|
||||
nic.setIsolationUri(network.getBroadcastUri());
|
||||
|
||||
//NicProfile does not contain the NIC UUID. We need this information to set it in the VMInterface and VPort
|
||||
//that we create in VSP
|
||||
NicVO nicFromDb = _nicDao.findById(nic.getId());
|
||||
IPAddressVO staticNatIp = _ipAddressDao.findByVmIdAndNetworkId(network.getId(), vm.getId());
|
||||
VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(vm.getVirtualMachine(), network);
|
||||
VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic);
|
||||
VspStaticNat vspStaticNat = null;
|
||||
if (staticNatIp != null) {
|
||||
VlanVO staticNatVlan = _vlanDao.findById(staticNatIp.getVlanId());
|
||||
vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(null, staticNatIp, staticNatVlan, vspNic);
|
||||
}
|
||||
|
||||
boolean defaultHasDns = getDefaultHasDns(networkHasDnsCache, nicFromDb);
|
||||
VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(nicFromDb, defaultHasDns, networkHasDns);
|
||||
ReserveVmInterfaceVspCommand cmd = new ReserveVmInterfaceVspCommand(vspNetwork, vspVm, vspNic, vspStaticNat, dhcpOption);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("ReserveVmInterfaceNuageVspCommand failed for NIC " + nic.getId() + " attached to VM " + vm.getId() + " in network " + network.getId());
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
s_logger.error(answer.getDetails());
|
||||
if (vm.isRollingRestart()) {
|
||||
((NetworkVO)network).setRollingRestart(true);
|
||||
} else {
|
||||
//NicProfile does not contain the NIC UUID. We need this information to set it in the VMInterface and VPort
|
||||
//that we create in VSP
|
||||
NicVO nicFromDb = _nicDao.findById(nic.getId());
|
||||
IPAddressVO staticNatIp = _ipAddressDao.findByVmIdAndNetworkId(network.getId(), vm.getId());
|
||||
VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic);
|
||||
VspStaticNat vspStaticNat = null;
|
||||
if (staticNatIp != null) {
|
||||
VlanVO staticNatVlan = _vlanDao.findById(staticNatIp.getVlanId());
|
||||
vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(null, staticNatIp, staticNatVlan, vspNic);
|
||||
}
|
||||
|
||||
boolean defaultHasDns = getDefaultHasDns(networkHasDnsCache, nicFromDb);
|
||||
VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(nicFromDb, defaultHasDns, networkHasDns);
|
||||
ReserveVmInterfaceVspCommand cmd = new ReserveVmInterfaceVspCommand(vspNetwork, vspVm, vspNic, vspStaticNat, dhcpOption);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("ReserveVmInterfaceNuageVspCommand failed for NIC " + nic.getId() + " attached to VM " + vm.getId() + " in network " + network.getId());
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
s_logger.error(answer.getDetails());
|
||||
}
|
||||
throw new InsufficientVirtualNetworkCapacityException("Failed to reserve VM in Nuage VSP.", Network.class, network.getId());
|
||||
}
|
||||
throw new InsufficientVirtualNetworkCapacityException("Failed to reserve VM in Nuage VSP.", Network.class, network.getId());
|
||||
}
|
||||
|
||||
if (vspVm.getDomainRouter() == Boolean.TRUE) {
|
||||
@ -695,15 +705,18 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru implements Networ
|
||||
}
|
||||
|
||||
try {
|
||||
final VirtualMachine virtualMachine = vm.getVirtualMachine();
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Handling deallocate() call back, which is called when a VM is destroyed or interface is removed, " + "to delete VM Interface with IP "
|
||||
+ nic.getIPv4Address() + " from a VM " + vm.getInstanceName() + " with state " + vm.getVirtualMachine().getState());
|
||||
+ nic.getIPv4Address() + " from a VM " + vm.getInstanceName() + " with state " + virtualMachine
|
||||
.getState());
|
||||
}
|
||||
|
||||
NicVO nicFromDb = _nicDao.findById(nic.getId());
|
||||
|
||||
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network);
|
||||
VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(vm.getVirtualMachine(), network);
|
||||
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(virtualMachine
|
||||
.getDomainId(), network);
|
||||
VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(virtualMachine, network);
|
||||
VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic);
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
|
||||
|
||||
@ -723,6 +736,32 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru implements Networ
|
||||
} else {
|
||||
super.deallocate(network, nic, vm);
|
||||
}
|
||||
|
||||
if (virtualMachine.getType() == VirtualMachine.Type.DomainRouter) {
|
||||
final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
|
||||
final DomainRouterVO otherRouter = routers.stream()
|
||||
.filter(r -> r.getId() != vm.getId())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (otherRouter != null) {
|
||||
nicFromDb = _nicDao.findByNtwkIdAndInstanceId(network.getId(), otherRouter.getId());
|
||||
vspVm = _nuageVspEntityBuilder.buildVspVm(otherRouter, network);
|
||||
vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb);
|
||||
|
||||
VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(nicFromDb, false, false);
|
||||
ReserveVmInterfaceVspCommand reserveCmd = new ReserveVmInterfaceVspCommand(vspNetwork, vspVm, vspNic, null, dhcpOption);
|
||||
|
||||
answer = _agentMgr.easySend(nuageVspHost.getId(), reserveCmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("DeallocateVmNuageVspCommand for VM " + vm.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
s_logger.error(answer.getDetails());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} finally {
|
||||
if (network != null && lockedNetwork) {
|
||||
_networkDao.releaseFromLockTable(network.getId());
|
||||
|
||||
@ -19,15 +19,34 @@
|
||||
|
||||
package com.cloud.network.guru;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.internal.util.collections.Sets;
|
||||
@ -39,10 +58,11 @@ import com.cloud.NuageTest;
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.guru.DeallocateVmVspCommand;
|
||||
import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
|
||||
import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand;
|
||||
import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
@ -71,6 +91,7 @@ import com.cloud.network.dao.NuageVspDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.manager.NuageVspManager;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
@ -78,26 +99,34 @@ import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class NuageVspGuestNetworkGuruTest extends NuageTest {
|
||||
private static final long DATACENTER_ID = 100L;
|
||||
private static final long HOST_ID = 101L;
|
||||
private static final long DOMAIN_ID = 1L;
|
||||
private static final long ACCOUNT_ID = 2L;
|
||||
private static final long OFFERING_ID = 40L;
|
||||
private static final long NETWORK_ID = 42L;
|
||||
private static final long VM_ID = 242L;
|
||||
private static final long NIC_ID = 342L;
|
||||
|
||||
private static final String DATACENTER_UUID = "uuid-datacenter-100";
|
||||
private static final String HOST_UUID = "uuid-host-101";
|
||||
private static final String DOMAIN_UUID = "uuid-domain-001";
|
||||
private static final String ACCOUNT_UUID = "uuid-account-002";
|
||||
private static final String OFFERING_UUID = "uuid-offering-040";
|
||||
private static final String NETWORK_UUID = "uuid-network-000-42";
|
||||
private static final String VM_UUID = "uuid-vm-002-42";
|
||||
private static final String NIC_UUID = "uuid-nic-003-42";
|
||||
|
||||
@Mock private PhysicalNetworkDao _physicalNetworkDao;
|
||||
@Mock private DataCenterDao _dataCenterDao;
|
||||
@Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
|
||||
@ -115,39 +144,42 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
|
||||
@Mock private DataCenterDetailsDao _dcDetailsDao;
|
||||
@Mock private NetworkDetailsDao _networkDetailsDao;
|
||||
@Mock private PhysicalNetworkVO physnet;
|
||||
@Mock private DomainRouterDao _routerDao;
|
||||
|
||||
private Account _account;
|
||||
private Domain _domain;
|
||||
private DataCenterVO _dc;
|
||||
private ReservationContext _reservationContext;
|
||||
|
||||
@InjectMocks
|
||||
private NuageVspGuestNetworkGuru _nuageVspGuestNetworkGuru;
|
||||
private NuageVspGuestNetworkGuru _nuageVspGuestNetworkGuru = new NuageVspGuestNetworkGuru();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
_nuageVspGuestNetworkGuru = new NuageVspGuestNetworkGuru();
|
||||
|
||||
super.setUp();
|
||||
|
||||
_nuageVspGuestNetworkGuru._nuageVspEntityBuilder = _nuageVspEntityBuilder;
|
||||
|
||||
final DataCenterVO dc = mock(DataCenterVO.class);
|
||||
when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
|
||||
when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24");
|
||||
|
||||
when(_dataCenterDao.findById((Long)any())).thenReturn(dc);
|
||||
_account = getMockAccount();
|
||||
_domain = getMockDomain();
|
||||
_dc = mockDataCenter();
|
||||
_reservationContext = getMockReservationContext(_account, _domain);
|
||||
|
||||
when(_physicalNetworkDao.findById(any(Long.class))).thenReturn(physnet);
|
||||
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList("VSP"));
|
||||
when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VSP"));
|
||||
when(physnet.getId()).thenReturn(NETWORK_ID);
|
||||
|
||||
final HostVO host = mock(HostVO.class);
|
||||
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
|
||||
when(host.getId()).thenReturn(NETWORK_ID);
|
||||
when(_agentManager.easySend(eq(NETWORK_ID), any(Command.class))).thenReturn(new Answer(null));
|
||||
when(_agentManager.easySend(eq(NETWORK_ID), any(ImplementNetworkVspCommand.class))).thenAnswer(this::mockImplement);
|
||||
when(host.getId()).thenReturn(HOST_ID);
|
||||
when(host.getUuid()).thenReturn(HOST_UUID);
|
||||
when(_hostDao.findById(HOST_ID)).thenReturn(host);
|
||||
|
||||
when(_agentManager.easySend(eq(HOST_ID), any(Command.class))).thenReturn(new Answer(null));
|
||||
when(_agentManager.easySend(eq(HOST_ID), any(ImplementNetworkVspCommand.class))).thenAnswer(this::mockImplement);
|
||||
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
|
||||
|
||||
final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class);
|
||||
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(device));
|
||||
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections.singletonList(device));
|
||||
when(device.getId()).thenReturn(1L);
|
||||
when(device.getHostId()).thenReturn(NETWORK_ID);
|
||||
when(device.getHostId()).thenReturn(HOST_ID);
|
||||
}
|
||||
|
||||
Answer mockImplement(InvocationOnMock invocation) {
|
||||
@ -161,18 +193,7 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
|
||||
|
||||
@Test
|
||||
public void testCanHandle() {
|
||||
final NetworkOffering offering = mock(NetworkOffering.class);
|
||||
when(offering.getId()).thenReturn(NETWORK_ID);
|
||||
when(offering.getIsPersistent()).thenReturn(false);
|
||||
when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(false);
|
||||
|
||||
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true);
|
||||
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true);
|
||||
|
||||
when(_networkModel.getNetworkOfferingServiceProvidersMap(NETWORK_ID)).thenReturn(ImmutableMap.of(
|
||||
Service.Connectivity, Sets.newSet(Network.Provider.NuageVsp),
|
||||
Service.SourceNat, Sets.newSet(Network.Provider.NuageVsp)
|
||||
));
|
||||
final NetworkOffering offering = mockNetworkOffering(false);
|
||||
|
||||
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
|
||||
@ -191,8 +212,8 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
|
||||
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
|
||||
assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Basic, physnet), is(false));
|
||||
|
||||
// Not supported: IsolationMethod != STT
|
||||
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList("VLAN"));
|
||||
// Not supported: IsolationMethod != VSP
|
||||
when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VLAN"));
|
||||
assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Basic, physnet), is(false));
|
||||
|
||||
// Not supported: Non-persistent VPC tier
|
||||
@ -202,272 +223,289 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
|
||||
|
||||
@Test
|
||||
public void testDesign() {
|
||||
final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class);
|
||||
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(device));
|
||||
when(device.getId()).thenReturn(1L);
|
||||
|
||||
final NetworkOffering offering = mock(NetworkOffering.class);
|
||||
when(offering.getId()).thenReturn(NETWORK_ID);
|
||||
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
|
||||
final NetworkOffering offering = mockNetworkOffering(false);
|
||||
when(offering.getIsPersistent()).thenReturn(false);
|
||||
when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(false);
|
||||
|
||||
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true);
|
||||
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true);
|
||||
|
||||
when(_networkModel.getNetworkOfferingServiceProvidersMap(NETWORK_ID)).thenReturn(ImmutableMap.of(
|
||||
Service.Connectivity, Sets.newSet(Network.Provider.NuageVsp),
|
||||
Service.SourceNat, Sets.newSet(Network.Provider.NuageVsp)
|
||||
));
|
||||
|
||||
final DeploymentPlan plan = mock(DeploymentPlan.class);
|
||||
final DeploymentPlan plan = mockDeploymentPlan();
|
||||
final Network network = mock(Network.class);
|
||||
final Account account = mock(Account.class);
|
||||
|
||||
final Network designednetwork = _nuageVspGuestNetworkGuru.design(offering, plan, network, account);
|
||||
final Network designednetwork = _nuageVspGuestNetworkGuru.design(offering, plan, network, _account);
|
||||
assertThat(designednetwork, notNullValue(Network.class));
|
||||
assertThat(designednetwork.getBroadcastDomainType(), is(BroadcastDomainType.Vsp));
|
||||
|
||||
// Can't design non-persistent VPC tier
|
||||
when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(true);
|
||||
assertThat(_nuageVspGuestNetworkGuru.design(offering, plan, network, account), nullValue(Network.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDesignNoElementOnPhysicalNetwork() {
|
||||
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList("STT"));
|
||||
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections.<NuageVspDeviceVO>emptyList());
|
||||
|
||||
final NetworkOffering offering = mock(NetworkOffering.class);
|
||||
when(offering.getId()).thenReturn(NETWORK_ID);
|
||||
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
|
||||
|
||||
final DeploymentPlan plan = mock(DeploymentPlan.class);
|
||||
final Network network = mock(Network.class);
|
||||
final Account account = mock(Account.class);
|
||||
|
||||
final Network designednetwork = _nuageVspGuestNetworkGuru.design(offering, plan, network, account);
|
||||
assertTrue(designednetwork == null);
|
||||
assertThat(_nuageVspGuestNetworkGuru.design(offering, plan, network, _account), nullValue(Network.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDesignNoIsolationMethodVSP() {
|
||||
when(physnet.getIsolationMethods()).thenReturn(Arrays.asList("VLAN"));
|
||||
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections.<NuageVspDeviceVO>emptyList());
|
||||
when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VLAN"));
|
||||
|
||||
final NetworkOffering offering = mock(NetworkOffering.class);
|
||||
when(offering.getId()).thenReturn(NETWORK_ID);
|
||||
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
|
||||
final NetworkOffering offering = mockNetworkOffering(false);
|
||||
|
||||
final DeploymentPlan plan = mock(DeploymentPlan.class);
|
||||
final DeploymentPlan plan = mockDeploymentPlan();
|
||||
final Network network = mock(Network.class);
|
||||
final Account account = mock(Account.class);
|
||||
|
||||
final Network designednetwork = _nuageVspGuestNetworkGuru.design(offering, plan, network, account);
|
||||
assertTrue(designednetwork == null);
|
||||
assertThat(_nuageVspGuestNetworkGuru.design(offering, plan, network, _account), nullValue(Network.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReserve() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
|
||||
final NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(network.getUuid()).thenReturn("aaaaaa");
|
||||
when(network.getDataCenterId()).thenReturn(NETWORK_ID);
|
||||
when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
|
||||
when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(network.getDomainId()).thenReturn(NETWORK_ID);
|
||||
when(network.getAccountId()).thenReturn(NETWORK_ID);
|
||||
when(network.getVpcId()).thenReturn(null);
|
||||
when(network.getBroadcastUri()).thenReturn(new URI("vsp://aaaaaa-aavvv/10.1.1.1"));
|
||||
|
||||
final DataCenterVO dataCenter = mock(DataCenterVO.class);
|
||||
when(_dataCenterDao.findById(NETWORK_ID)).thenReturn(dataCenter);
|
||||
final AccountVO networksAccount = mock(AccountVO.class);
|
||||
when(networksAccount.getId()).thenReturn(NETWORK_ID);
|
||||
when(networksAccount.getUuid()).thenReturn("aaaa-abbbb");
|
||||
when(networksAccount.getType()).thenReturn(Account.ACCOUNT_TYPE_NORMAL);
|
||||
when(_accountDao.findById(NETWORK_ID)).thenReturn(networksAccount);
|
||||
final DomainVO networksDomain = mock(DomainVO.class);
|
||||
when(networksDomain.getId()).thenReturn(NETWORK_ID);
|
||||
when(networksDomain.getUuid()).thenReturn("aaaaa-bbbbb");
|
||||
when(_domainDao.findById(NETWORK_ID)).thenReturn(networksDomain);
|
||||
|
||||
final NicVO nicvo = mock(NicVO.class);
|
||||
when(nicvo.getId()).thenReturn(NETWORK_ID);
|
||||
when(nicvo.getMacAddress()).thenReturn("aa-aa-aa-aa-aa-aa");
|
||||
when(nicvo.getUuid()).thenReturn("aaaa-fffff");
|
||||
when(nicvo.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(nicvo.getInstanceId()).thenReturn(NETWORK_ID);
|
||||
when(_nicDao.findById(NETWORK_ID)).thenReturn(nicvo);
|
||||
when(_nicDao.findDefaultNicForVM(NETWORK_ID)).thenReturn(nicvo);
|
||||
|
||||
final VirtualMachine vm = mock(VirtualMachine.class);
|
||||
when(vm.getId()).thenReturn(NETWORK_ID);
|
||||
when(vm.getType()).thenReturn(VirtualMachine.Type.User);
|
||||
|
||||
final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class);
|
||||
when(vmProfile.getType()).thenReturn(VirtualMachine.Type.User);
|
||||
when(vmProfile.getInstanceName()).thenReturn("");
|
||||
when(vmProfile.getUuid()).thenReturn("aaaa-bbbbb");
|
||||
when(vmProfile.getVirtualMachine()).thenReturn(vm);
|
||||
|
||||
NicProfile nicProfile = mock(NicProfile.class);
|
||||
when(nicProfile.getUuid()).thenReturn("aaa-bbbb");
|
||||
when(nicProfile.getId()).thenReturn(NETWORK_ID);
|
||||
when(nicProfile.getMacAddress()).thenReturn("aa-aa-aa-aa-aa-aa");
|
||||
|
||||
final NetworkOfferingVO ntwkoffering = mock(NetworkOfferingVO.class);
|
||||
when(ntwkoffering.getId()).thenReturn(NETWORK_ID);
|
||||
when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffering);
|
||||
|
||||
when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
|
||||
when(_ipAddressDao.findByVmIdAndNetworkId(NETWORK_ID, NETWORK_ID)).thenReturn(null);
|
||||
when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
|
||||
|
||||
final Answer answer = mock(Answer.class);
|
||||
when(answer.getResult()).thenReturn(true);
|
||||
when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
|
||||
|
||||
final ReservationContext reservationContext = mock(ReservationContext.class);
|
||||
when(reservationContext.getAccount()).thenReturn(networksAccount);
|
||||
when(reservationContext.getDomain()).thenReturn(networksDomain);
|
||||
final NetworkVO network = mockNetwork();
|
||||
final NicProfile nicProfile = mockNicProfile();
|
||||
final VirtualMachineProfile vmProfile = mockVirtualMachineProfile(VirtualMachine.State.Starting);
|
||||
|
||||
when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
|
||||
_nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), reservationContext);
|
||||
_nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), _reservationContext);
|
||||
|
||||
verify(_agentManager).easySend(anyLong(), any(Command.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReserveVRRollingRestart() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
|
||||
final NetworkVO network = mockNetwork();
|
||||
final NicProfile nicProfile = mockNicProfile();
|
||||
final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Starting);
|
||||
|
||||
when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
|
||||
_nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), _reservationContext);
|
||||
|
||||
verifyZeroInteractions(_agentManager);
|
||||
verify(network).setRollingRestart(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImplementNetwork() throws URISyntaxException, InsufficientVirtualNetworkCapacityException {
|
||||
final NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(network.getUuid()).thenReturn("aaaaaa");
|
||||
when(network.getDataCenterId()).thenReturn(NETWORK_ID);
|
||||
when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
|
||||
when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(network.getDomainId()).thenReturn(NETWORK_ID);
|
||||
when(network.getAccountId()).thenReturn(NETWORK_ID);
|
||||
when(network.getVpcId()).thenReturn(null);
|
||||
final NetworkVO network = mockNetwork();
|
||||
|
||||
when(network.getState()).thenReturn(com.cloud.network.Network.State.Implementing);
|
||||
when(network.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(network.getMode()).thenReturn(Mode.Static);
|
||||
when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
|
||||
when(network.getBroadcastUri()).thenReturn(new URI("vsp://aaaaaa-aavvv/10.1.1.1"));
|
||||
when(network.getGateway()).thenReturn("10.1.1.1");
|
||||
when(network.getCidr()).thenReturn("10.1.1.0/24");
|
||||
when(network.getName()).thenReturn("iso");
|
||||
|
||||
final NetworkOffering offering = mock(NetworkOffering.class);
|
||||
when(offering.getId()).thenReturn(NETWORK_ID);
|
||||
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(offering.getTags()).thenReturn("aaaa");
|
||||
when(offering.getEgressDefaultPolicy()).thenReturn(true);
|
||||
final NetworkOffering offering = mockNetworkOffering(false);
|
||||
|
||||
when(_networkModel.findPhysicalNetworkId(NETWORK_ID, "aaa", TrafficType.Guest)).thenReturn(NETWORK_ID);
|
||||
|
||||
final ReservationContext reserveContext = mock(ReservationContext.class);
|
||||
final Domain domain = mock(Domain.class);
|
||||
when(domain.getId()).thenReturn(NETWORK_ID);
|
||||
when(reserveContext.getDomain()).thenReturn(domain);
|
||||
when(domain.getName()).thenReturn("aaaaa");
|
||||
final Account account = mock(Account.class);
|
||||
when(account.getId()).thenReturn(NETWORK_ID);
|
||||
when(account.getAccountId()).thenReturn(NETWORK_ID);
|
||||
when(reserveContext.getAccount()).thenReturn(account);
|
||||
final DomainVO domainVo = mock(DomainVO.class);
|
||||
when(_domainDao.findById(NETWORK_ID)).thenReturn(domainVo);
|
||||
final AccountVO accountVo = mock(AccountVO.class);
|
||||
when(_accountDao.findById(NETWORK_ID)).thenReturn(accountVo);
|
||||
|
||||
when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
|
||||
when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList<String>());
|
||||
when(_nuageVspManager.getGatewaySystemIds()).thenReturn(new ArrayList<String>());
|
||||
|
||||
final DataCenter dc = mock(DataCenter.class);
|
||||
when(dc.getId()).thenReturn(NETWORK_ID);
|
||||
final DeployDestination deployDest = mock(DeployDestination.class);
|
||||
when(deployDest.getDataCenter()).thenReturn(dc);
|
||||
_nuageVspGuestNetworkGuru.implement(network, offering, deployDest, reserveContext);
|
||||
when(deployDest.getDataCenter()).thenReturn(_dc);
|
||||
_nuageVspGuestNetworkGuru.implement(network, offering, deployDest, _reservationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeallocate() throws Exception {
|
||||
final NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(network.getUuid()).thenReturn("aaaaaa");
|
||||
when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
|
||||
when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(network.getVpcId()).thenReturn(null);
|
||||
when(network.getDomainId()).thenReturn(NETWORK_ID);
|
||||
when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
|
||||
|
||||
final NetworkOfferingVO offering = mock(NetworkOfferingVO.class);
|
||||
when(offering.getId()).thenReturn(NETWORK_ID);
|
||||
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(offering);
|
||||
|
||||
final DomainVO domain = mock(DomainVO.class);
|
||||
when(domain.getUuid()).thenReturn("aaaaaa");
|
||||
when(_domainDao.findById(NETWORK_ID)).thenReturn(domain);
|
||||
|
||||
final NicVO nic = mock(NicVO.class);
|
||||
when(nic.getId()).thenReturn(NETWORK_ID);
|
||||
when(nic.getIPv4Address()).thenReturn("10.10.10.10");
|
||||
when(nic.getMacAddress()).thenReturn("c8:60:00:56:e5:58");
|
||||
when(_nicDao.findById(NETWORK_ID)).thenReturn(nic);
|
||||
|
||||
final NicProfile nicProfile = mock(NicProfile.class);
|
||||
when(nicProfile.getId()).thenReturn(NETWORK_ID);
|
||||
when(nicProfile.getIPv4Address()).thenReturn("10.10.10.10");
|
||||
when(nicProfile.getMacAddress()).thenReturn("c8:60:00:56:e5:58");
|
||||
|
||||
final VirtualMachine vm = mock(VirtualMachine.class);
|
||||
when(vm.getType()).thenReturn(VirtualMachine.Type.User);
|
||||
when(vm.getState()).thenReturn(VirtualMachine.State.Expunging);
|
||||
|
||||
final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class);
|
||||
when(vmProfile.getUuid()).thenReturn("aaaaaa");
|
||||
when(vmProfile.getInstanceName()).thenReturn("Test-VM");
|
||||
when(vmProfile.getVirtualMachine()).thenReturn(vm);
|
||||
final NetworkVO network = mockNetwork();
|
||||
final NicProfile nicProfile = mockNicProfile();
|
||||
final VirtualMachineProfile vmProfile = mockVirtualMachineProfile(VirtualMachine.State.Expunging);
|
||||
|
||||
_nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeallocateVR() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
|
||||
final NetworkVO network = mockNetwork();
|
||||
final NicProfile nicProfile = mockNicProfile();
|
||||
final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Expunging);
|
||||
|
||||
when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
|
||||
_nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeallocateVRRollingRestart() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
|
||||
final NetworkVO network = mockNetwork();
|
||||
final NicProfile nicProfile = mockNicProfile();
|
||||
final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Expunging);
|
||||
|
||||
DomainRouterVO newVR = mock(DomainRouterVO.class);
|
||||
|
||||
when(_routerDao.listByNetworkAndRole(NETWORK_ID, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(Collections.singletonList(newVR));
|
||||
when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
|
||||
_nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
|
||||
|
||||
ArgumentCaptor<Command> argumentCaptor = ArgumentCaptor.forClass(Command.class);
|
||||
verify(_agentManager, times(2)).easySend(eq(HOST_ID), argumentCaptor.capture());
|
||||
final List<Command> commands = argumentCaptor.getAllValues();
|
||||
assertThat(commands.get(0) instanceof DeallocateVmVspCommand, is(true));
|
||||
assertThat(commands.get(1) instanceof ReserveVmInterfaceVspCommand, is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrash() throws Exception {
|
||||
final NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(network.getUuid()).thenReturn("aaaaaa");
|
||||
when(network.getUuid()).thenReturn(NETWORK_UUID);
|
||||
when(network.getName()).thenReturn("trash");
|
||||
when(network.getDomainId()).thenReturn(NETWORK_ID);
|
||||
when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
|
||||
when(network.getDomainId()).thenReturn(DOMAIN_ID);
|
||||
when(network.getNetworkOfferingId()).thenReturn(OFFERING_ID);
|
||||
when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(network.getDataCenterId()).thenReturn(NETWORK_ID);
|
||||
when(network.getDataCenterId()).thenReturn(DATACENTER_ID);
|
||||
when(network.getVpcId()).thenReturn(null);
|
||||
when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
|
||||
|
||||
final NetworkOfferingVO offering = mock(NetworkOfferingVO.class);
|
||||
when(offering.getId()).thenReturn(NETWORK_ID);
|
||||
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(offering);
|
||||
final NetworkOffering offering = mockNetworkOffering(false);
|
||||
|
||||
final DomainVO domain = mock(DomainVO.class);
|
||||
when(domain.getUuid()).thenReturn("aaaaaa");
|
||||
when(_domainDao.findById(NETWORK_ID)).thenReturn(domain);
|
||||
|
||||
final HostVO host = mock(HostVO.class);
|
||||
when(host.getId()).thenReturn(NETWORK_ID);
|
||||
final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
|
||||
when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
|
||||
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
|
||||
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
|
||||
when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList<String>());
|
||||
when(_nuageVspManager.getGatewaySystemIds()).thenReturn(new ArrayList<String>());
|
||||
when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList<>());
|
||||
when(_nuageVspManager.getGatewaySystemIds()).thenReturn(new ArrayList<>());
|
||||
|
||||
assertTrue(_nuageVspGuestNetworkGuru.trash(network, offering));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private NetworkVO mockNetwork() throws URISyntaxException {
|
||||
final NetworkVO network = mock(NetworkVO.class);
|
||||
when(network.getId()).thenReturn(NETWORK_ID);
|
||||
when(network.getUuid()).thenReturn(NETWORK_UUID);
|
||||
when(network.getDataCenterId()).thenReturn(DATACENTER_ID);
|
||||
when(network.getNetworkOfferingId()).thenReturn(OFFERING_ID);
|
||||
when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(network.getDomainId()).thenReturn(DOMAIN_ID);
|
||||
when(network.getAccountId()).thenReturn(ACCOUNT_ID);
|
||||
when(network.getVpcId()).thenReturn(null);
|
||||
when(network.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(network.getMode()).thenReturn(Mode.Dhcp);
|
||||
when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
|
||||
when(network.getBroadcastUri()).thenReturn(new URI("vsp://" + NETWORK_UUID + "/10.1.1.1"));
|
||||
when(network.getGateway()).thenReturn("10.1.1.1");
|
||||
when(network.getCidr()).thenReturn("10.1.1.0/24");
|
||||
when(network.getName()).thenReturn("iso");
|
||||
|
||||
when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
|
||||
when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
|
||||
|
||||
return network;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private NetworkOffering mockNetworkOffering(boolean forVpc) {
|
||||
final NetworkOfferingVO offering = mock(NetworkOfferingVO.class);
|
||||
when(offering.getId()).thenReturn(OFFERING_ID);
|
||||
when(offering.getUuid()).thenReturn(OFFERING_UUID);
|
||||
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
|
||||
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
|
||||
when(offering.getForVpc()).thenReturn(forVpc);
|
||||
when(offering.getIsPersistent()).thenReturn(false);
|
||||
when(offering.getTags()).thenReturn("aaaa");
|
||||
when(offering.getEgressDefaultPolicy()).thenReturn(true);
|
||||
|
||||
when(_networkOfferingDao.findById(OFFERING_ID)).thenReturn(offering);
|
||||
|
||||
when(_configurationManager.isOfferingForVpc(offering)).thenReturn(forVpc);
|
||||
|
||||
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(OFFERING_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true);
|
||||
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(OFFERING_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true);
|
||||
|
||||
when(_networkModel.getNetworkOfferingServiceProvidersMap(OFFERING_ID)).thenReturn(ImmutableMap.of(
|
||||
Service.Connectivity, Sets.newSet(Network.Provider.NuageVsp),
|
||||
Service.SourceNat, Sets.newSet(Network.Provider.NuageVsp)
|
||||
));
|
||||
|
||||
return offering;
|
||||
}
|
||||
|
||||
private DeploymentPlan mockDeploymentPlan() {
|
||||
final DeploymentPlan deploymentPlan = mock(DeploymentPlan.class);
|
||||
when(deploymentPlan.getDataCenterId()).thenReturn(DATACENTER_ID);
|
||||
return deploymentPlan;
|
||||
}
|
||||
|
||||
private DataCenterVO mockDataCenter() {
|
||||
DataCenterVO dc = mock(DataCenterVO.class);
|
||||
when(dc.getId()).thenReturn(DATACENTER_ID);
|
||||
when(dc.getUuid()).thenReturn(DATACENTER_UUID);
|
||||
when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
|
||||
when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24");
|
||||
when(_dataCenterDao.findById(DATACENTER_ID)).thenReturn(dc);
|
||||
|
||||
return dc;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Account getMockAccount() {
|
||||
final AccountVO account = mock(AccountVO.class);
|
||||
when(account.getId()).thenReturn(ACCOUNT_ID);
|
||||
when(account.getAccountId()).thenReturn(ACCOUNT_ID);
|
||||
when(account.getUuid()).thenReturn(ACCOUNT_UUID);
|
||||
when(account.getDomainId()).thenReturn(DOMAIN_ID);
|
||||
when(account.getType()).thenReturn(Account.ACCOUNT_TYPE_NORMAL);
|
||||
|
||||
when(_accountDao.findById(ACCOUNT_ID)).thenReturn(account);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Domain getMockDomain() {
|
||||
final DomainVO domain = mock(DomainVO.class);
|
||||
when(domain.getId()).thenReturn(DOMAIN_ID);
|
||||
when(domain.getUuid()).thenReturn(DOMAIN_UUID);
|
||||
when(domain.getName()).thenReturn("aaaaa");
|
||||
|
||||
when(_domainDao.findById(DOMAIN_ID)).thenReturn(domain);
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private VirtualMachineProfile mockVirtualMachineProfile(VirtualMachine.State state) {
|
||||
final VirtualMachine vm = mock(VirtualMachine.class);
|
||||
when(vm.getId()).thenReturn(VM_ID);
|
||||
when(vm.getType()).thenReturn(VirtualMachine.Type.User);
|
||||
when(vm.getState()).thenReturn(state);
|
||||
|
||||
final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class);
|
||||
when(vmProfile.getType()).thenReturn(VirtualMachine.Type.User);
|
||||
when(vmProfile.getInstanceName()).thenReturn("Test-VM");
|
||||
when(vmProfile.getUuid()).thenReturn(VM_UUID);
|
||||
when(vmProfile.getVirtualMachine()).thenReturn(vm);
|
||||
return vmProfile;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private VirtualMachineProfile mockVRProfile(VirtualMachine.State state) {
|
||||
final VirtualMachine vm = mock(VirtualMachine.class);
|
||||
when(vm.getId()).thenReturn(VM_ID);
|
||||
when(vm.getUuid()).thenReturn(VM_UUID);
|
||||
when(vm.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
|
||||
when(vm.getState()).thenReturn(state);
|
||||
|
||||
|
||||
final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class);
|
||||
when(vmProfile.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
|
||||
when(vmProfile.getInstanceName()).thenReturn("Test-VR");
|
||||
when(vmProfile.getId()).thenReturn(VM_ID);
|
||||
when(vmProfile.getUuid()).thenReturn(VM_UUID);
|
||||
when(vmProfile.getVirtualMachine()).thenReturn(vm);
|
||||
when(vmProfile.isRollingRestart()).thenReturn(true);
|
||||
return vmProfile;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private NicProfile mockNicProfile() {
|
||||
final NicVO nicvo = mock(NicVO.class);
|
||||
when(nicvo.getId()).thenReturn(NIC_ID);
|
||||
when(nicvo.getMacAddress()).thenReturn("c8:60:00:56:e5:58");
|
||||
when(nicvo.getIPv4Address()).thenReturn("10.10.10.10");
|
||||
when(nicvo.getUuid()).thenReturn("aaaa-fffff");
|
||||
when(nicvo.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(nicvo.getInstanceId()).thenReturn(VM_ID);
|
||||
when(_nicDao.findById(NIC_ID)).thenReturn(nicvo);
|
||||
when(_nicDao.findDefaultNicForVM(VM_ID)).thenReturn(nicvo);
|
||||
|
||||
NicProfile nicProfile = mock(NicProfile.class);
|
||||
when(nicProfile.getUuid()).thenReturn("aaa-bbbb");
|
||||
when(nicProfile.getId()).thenReturn(NIC_ID);
|
||||
when(nicProfile.getMacAddress()).thenReturn("c8:60:00:56:e5:58");
|
||||
when(nicProfile.getIPv4Address()).thenReturn("10.10.10.10");
|
||||
return nicProfile;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private static ReservationContext getMockReservationContext(Account networksAccount, Domain networksDomain) {
|
||||
final ReservationContext reservationContext = mock(ReservationContext.class);
|
||||
when(reservationContext.getAccount()).thenReturn(networksAccount);
|
||||
when(reservationContext.getDomain()).thenReturn(networksDomain);
|
||||
return reservationContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -216,6 +216,10 @@ NetworkMigrationResponder, AggregatedCommandExecutor, RedundantResource, DnsServ
|
||||
final Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
|
||||
params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
|
||||
|
||||
if (network.isRollingRestart()) {
|
||||
params.put(VirtualMachineProfile.Param.RollingRestart, true);
|
||||
}
|
||||
|
||||
final RouterDeploymentDefinition routerDeploymentDefinition =
|
||||
routerDeploymentDefinitionBuilder.create()
|
||||
.setGuestNetwork(network)
|
||||
|
||||
@ -153,6 +153,10 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
|
||||
final Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
|
||||
params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
|
||||
|
||||
if (vpc.isRollingRestart()) {
|
||||
params.put(VirtualMachineProfile.Param.RollingRestart, true);
|
||||
}
|
||||
|
||||
final RouterDeploymentDefinition routerDeploymentDefinition = routerDeploymentDefinitionBuilder.create().setVpc(vpc).setDeployDestination(dest)
|
||||
.setAccountOwner(_accountMgr.getAccount(vpc.getAccountId())).setParams(params).build();
|
||||
|
||||
@ -194,6 +198,10 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
|
||||
final Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
|
||||
params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
|
||||
|
||||
if (network.isRollingRestart()) {
|
||||
params.put(VirtualMachineProfile.Param.RollingRestart, true);
|
||||
}
|
||||
|
||||
final RouterDeploymentDefinition routerDeploymentDefinition = routerDeploymentDefinitionBuilder.create()
|
||||
.setGuestNetwork(network)
|
||||
.setVpc(vpc)
|
||||
|
||||
@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -41,12 +42,20 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.storage.configdrive.ConfigDrive;
|
||||
import org.apache.cloudstack.storage.configdrive.ConfigDriveBuilder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.reflections.ReflectionUtils;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
@ -90,6 +99,7 @@ import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
public class ConfigDriveNetworkElementTest {
|
||||
|
||||
public static final String CLOUD_ID = "xx";
|
||||
@ -140,7 +150,7 @@ public class ConfigDriveNetworkElementTest {
|
||||
@InjectMocks private final ConfigDriveNetworkElement _configDrivesNetworkElement = new ConfigDriveNetworkElement();
|
||||
@InjectMocks @Spy private NetworkModelImpl _networkModel = new NetworkModelImpl();
|
||||
|
||||
@org.junit.Before
|
||||
@Before
|
||||
public void setUp() throws NoSuchFieldException, IllegalAccessException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
@ -243,7 +253,14 @@ public class ConfigDriveNetworkElementTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void testAddPasswordAndUserData() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("buildConfigDrive")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.anyListOf(String[].class), Mockito.anyString(), Mockito.anyString()).thenReturn("content");
|
||||
|
||||
final Answer answer = mock(Answer.class);
|
||||
final UserVmDetailVO userVmDetailVO = mock(UserVmDetailVO.class);
|
||||
when(agentManager.easySend(anyLong(), any(HandleConfigDriveIsoCommand.class))).thenReturn(answer);
|
||||
|
||||
@ -29,10 +29,9 @@ import javax.net.SocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import streamer.debug.MockServer;
|
||||
import streamer.debug.MockServer.Packet;
|
||||
|
||||
@ -93,7 +92,6 @@ public class MockServerTest extends TestCase {
|
||||
|
||||
@Test
|
||||
public void testIsMockServerCanUpgradeConnectionToSsl() throws Exception {
|
||||
|
||||
final byte[] mockClientData1 = new byte[] {0x01, 0x02, 0x03};
|
||||
final byte[] mockServerData1 = new byte[] {0x03, 0x02, 0x01};
|
||||
|
||||
@ -161,8 +159,7 @@ public class MockServerTest extends TestCase {
|
||||
|
||||
final SSLSocketFactory sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
|
||||
SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, address.getHostName(), address.getPort(), true);
|
||||
//sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
|
||||
sslSocket.setEnabledCipherSuites(new String[] { "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA" });
|
||||
sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
|
||||
sslSocket.startHandshake();
|
||||
|
||||
InputStream is = sslSocket.getInputStream();
|
||||
|
||||
@ -584,16 +584,19 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(secStorageMountPoint);
|
||||
if (!secStorageMountPoint.endsWith("/"))
|
||||
if (!secStorageMountPoint.endsWith("/")) {
|
||||
sb.append("/");
|
||||
}
|
||||
|
||||
sb.append(templateRelativeFolderPath);
|
||||
if (!secStorageMountPoint.endsWith("/"))
|
||||
if (!secStorageMountPoint.endsWith("/")) {
|
||||
sb.append("/");
|
||||
}
|
||||
|
||||
sb.append(templateName);
|
||||
if (!fileExtension.startsWith("."))
|
||||
if (!fileExtension.startsWith(".")) {
|
||||
sb.append(".");
|
||||
}
|
||||
sb.append(fileExtension);
|
||||
|
||||
return sb.toString();
|
||||
@ -904,7 +907,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
try {
|
||||
_storage.create(destFile.getAbsolutePath(), _tmpltpp);
|
||||
try ( // generate template.properties file
|
||||
FileWriter writer = new FileWriter(metaFile); BufferedWriter bufferWriter = new BufferedWriter(writer);) {
|
||||
FileWriter writer = new FileWriter(metaFile); BufferedWriter bufferWriter = new BufferedWriter(writer);) {
|
||||
// KVM didn't change template unique name, just used the template name passed from orchestration layer, so no need
|
||||
// to send template name back.
|
||||
bufferWriter.write("uniquename=" + destData.getName());
|
||||
@ -1450,7 +1453,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
Script command = new Script("/bin/bash", s_logger);
|
||||
command.add("-c");
|
||||
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
|
||||
+ " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
|
||||
+ " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
if (result != null) {
|
||||
@ -1554,7 +1557,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
Script command = new Script("/bin/bash", s_logger);
|
||||
command.add("-c");
|
||||
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
|
||||
+ " -K " + swift.getKey() + " list " + container + " " + rFilename);
|
||||
+ " -K " + swift.getKey() + " list " + container + " " + rFilename);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
if (result == null && parser.getLines() != null) {
|
||||
@ -1576,7 +1579,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
Script command = new Script("/bin/bash", s_logger);
|
||||
command.add("-c");
|
||||
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
|
||||
+ " -K " + swift.getKey() + " delete " + container + " " + object);
|
||||
+ " -K " + swift.getKey() + " delete " + container + " " + object);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
if (result != null) {
|
||||
@ -3316,7 +3319,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
||||
for (Processor processor : processors.values()) {
|
||||
FormatInfo info = null;
|
||||
try {
|
||||
info = processor.process(resourcePath, null, templateName, processTimeout * 1000);
|
||||
info = processor.process(resourcePath, null, templateName, processTimeout * 1000);
|
||||
} catch (InternalErrorException e) {
|
||||
s_logger.error("Template process exception ", e);
|
||||
return e.toString();
|
||||
|
||||
@ -42,7 +42,8 @@ from marvin.lib.base import (Account,
|
||||
StaticNATRule,
|
||||
VirtualMachine,
|
||||
VPC,
|
||||
VpcOffering)
|
||||
VpcOffering,
|
||||
Hypervisor)
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_template,
|
||||
get_zone,
|
||||
@ -145,6 +146,27 @@ class Services:
|
||||
"Dns": 'VirtualRouter'
|
||||
}
|
||||
},
|
||||
"shared_network_config_drive_offering": {
|
||||
"name": 'shared_network_config_drive_offering',
|
||||
"displaytext": 'shared_network_config_drive_offering',
|
||||
"guestiptype": 'shared',
|
||||
"supportedservices": 'Dhcp,UserData',
|
||||
"traffictype": 'GUEST',
|
||||
"specifyVlan": "True",
|
||||
"specifyIpRanges": "True",
|
||||
"availability": 'Optional',
|
||||
"serviceProviderList": {
|
||||
"Dhcp": "VirtualRouter",
|
||||
"UserData": 'ConfigDrive'
|
||||
}
|
||||
},
|
||||
"publiciprange2": {
|
||||
"gateway": "10.219.1.1",
|
||||
"netmask": "255.255.255.0",
|
||||
"startip": "10.219.1.2",
|
||||
"endip": "10.219.1.5",
|
||||
"forvirtualnetwork": "false"
|
||||
},
|
||||
"acl": {
|
||||
"network_all_1": {
|
||||
"name": "SharedNetwork-All-1",
|
||||
@ -513,10 +535,7 @@ class ConfigDriveUtils:
|
||||
:rtype: str
|
||||
"""
|
||||
self.debug("Updating Service Provider ConfigDrive to %s" % new_state)
|
||||
configdriveprovider = NetworkServiceProvider.list(
|
||||
self.api_client,
|
||||
name="ConfigDrive",
|
||||
physicalnetworkid=self.vsp_physical_network.id)[0]
|
||||
configdriveprovider = self.get_configdrive_provider()
|
||||
orig_state = configdriveprovider.state
|
||||
NetworkServiceProvider.update(self.api_client,
|
||||
configdriveprovider.id,
|
||||
@ -524,6 +543,14 @@ class ConfigDriveUtils:
|
||||
self.validate_NetworkServiceProvider("ConfigDrive", state=new_state)
|
||||
return orig_state
|
||||
|
||||
def _get_test_data(self, key):
|
||||
return self.test_data[key]
|
||||
|
||||
def get_configdrive_provider(self):
|
||||
return NetworkServiceProvider.list(
|
||||
self.api_client,
|
||||
name="ConfigDrive")[0]
|
||||
|
||||
def verify_network_creation(self, offering=None,
|
||||
offering_name=None,
|
||||
gateway=None,
|
||||
@ -549,7 +576,7 @@ class ConfigDriveUtils:
|
||||
if offering is None:
|
||||
self.debug("Creating Nuage VSP network offering...")
|
||||
offering = self.create_NetworkOffering(
|
||||
self.test_data["nuagevsp"][offering_name])
|
||||
self._get_test_data(offering_name))
|
||||
self.validate_NetworkOffering(offering, state="Enabled")
|
||||
try:
|
||||
network = self.create_Network(offering,
|
||||
@ -576,7 +603,7 @@ class ConfigDriveUtils:
|
||||
if offering is None:
|
||||
self.debug("Creating Nuage VSP VPC offering...")
|
||||
offering = self.create_VpcOffering(
|
||||
self.test_data["nuagevsp"][offering_name])
|
||||
self._get_test_data(offering_name))
|
||||
self.validate_VpcOffering(offering, state="Enabled")
|
||||
try:
|
||||
vpc = self.create_Vpc(offering, cidr='10.1.0.0/16')
|
||||
@ -627,7 +654,7 @@ class ConfigDriveUtils:
|
||||
|
||||
self.debug("SSHing into the VM %s" % vm.name)
|
||||
if ssh_client is None:
|
||||
ssh = self.ssh_into_VM(vm, public_ip, keypair=ssh_key)
|
||||
ssh = self.ssh_into_VM(vm, public_ip)
|
||||
else:
|
||||
ssh = ssh_client
|
||||
d = {x.name: x for x in ssh.logger.handlers}
|
||||
@ -674,7 +701,10 @@ class ConfigDriveUtils:
|
||||
keypair=keypair)
|
||||
# Check VM
|
||||
self.check_VM_state(vm, state="Running")
|
||||
self.verify_vsd_vm(vm)
|
||||
|
||||
if keypair:
|
||||
self.decrypt_password(vm)
|
||||
|
||||
# Check networks
|
||||
network_list = []
|
||||
if isinstance(networks, list):
|
||||
@ -685,10 +715,9 @@ class ConfigDriveUtils:
|
||||
|
||||
for network in network_list:
|
||||
self.validate_Network(network, state="Implemented")
|
||||
self.verify_vsd_network(self.domain.id, network, vpc=vpc)
|
||||
|
||||
if acl_item is not None:
|
||||
self.verify_vsd_firewall_rule(acl_item)
|
||||
self.validate_firewall_rule(acl_item)
|
||||
return vm
|
||||
|
||||
# nic_operation_VM - Performs NIC operations such as add, remove, and
|
||||
@ -754,12 +783,21 @@ class ConfigDriveUtils:
|
||||
self.debug("Sshkey reset to - %s" % self.keypair.name)
|
||||
vm.start(self.api_client)
|
||||
|
||||
# reset SSH key also resets the password.
|
||||
# the new password is available in VM detail,
|
||||
# named "Encrypted.Password".
|
||||
# It is encrypted using the SSH Public Key,
|
||||
# and thus can be decrypted using the SSH Private Key
|
||||
vm.details = vm_new_ssh.details
|
||||
|
||||
# reset SSH key also resets the password.
|
||||
self.decrypt_password(vm)
|
||||
|
||||
def decrypt_password(self, vm):
|
||||
"""Decrypt VM password
|
||||
|
||||
the new password is available in VM detail,
|
||||
named "Encrypted.Password".
|
||||
It is encrypted using the SSH Public Key,
|
||||
and thus can be decrypted using the SSH Private Key
|
||||
|
||||
:type vm: VirtualMachine
|
||||
"""
|
||||
try:
|
||||
from base64 import b64decode
|
||||
from Crypto.PublicKey import RSA
|
||||
@ -768,7 +806,7 @@ class ConfigDriveUtils:
|
||||
key = RSA.importKey(pkfile.read())
|
||||
cipher = PKCS1_v1_5.new(key)
|
||||
new_password = cipher.decrypt(
|
||||
b64decode(vm_new_ssh.details['Encrypted.Password']), None)
|
||||
b64decode(vm.details['Encrypted.Password']), None)
|
||||
if new_password:
|
||||
vm.password = new_password
|
||||
else:
|
||||
@ -776,7 +814,6 @@ class ConfigDriveUtils:
|
||||
except:
|
||||
self.debug("Failed to decrypt new password")
|
||||
|
||||
|
||||
def add_subnet_verify(self, network, services):
|
||||
"""verify required nic is present in the VM"""
|
||||
|
||||
@ -806,6 +843,9 @@ class ConfigDriveUtils:
|
||||
)
|
||||
return addedsubnet
|
||||
|
||||
def ssh_into_VM(self, vm, public_ip, keypair):
|
||||
pass
|
||||
|
||||
|
||||
class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
"""Test user data and password reset functionality
|
||||
@ -838,6 +878,9 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
cls.api_client,
|
||||
cls.test_data["service_offering"])
|
||||
cls._cleanup = [cls.service_offering]
|
||||
|
||||
hypervisors = Hypervisor.list(cls.api_client, zoneid=cls.zone.id)
|
||||
cls.isSimulator = any(h.name == "Simulator" for h in hypervisors)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
@ -948,6 +991,39 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
self.debug("Successfully validated the creation and state of Network "
|
||||
"Service Provider - %s" % provider_name)
|
||||
|
||||
# validate_PublicIPAddress - Validates if the given public IP address is in
|
||||
# the expected state form the list of fetched public IP addresses
|
||||
def validate_PublicIPAddress(self, public_ip, network, static_nat=False,
|
||||
vm=None):
|
||||
"""Validates the Public IP Address"""
|
||||
self.debug("Validating the assignment and state of public IP address "
|
||||
"- %s" % public_ip.ipaddress.ipaddress)
|
||||
public_ips = PublicIPAddress.list(self.api_client,
|
||||
id=public_ip.ipaddress.id,
|
||||
networkid=network.id,
|
||||
isstaticnat=static_nat,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(isinstance(public_ips, list), True,
|
||||
"List public IP for network should return a "
|
||||
"valid list"
|
||||
)
|
||||
self.assertEqual(public_ips[0].ipaddress,
|
||||
public_ip.ipaddress.ipaddress,
|
||||
"List public IP for network should list the assigned "
|
||||
"public IP address"
|
||||
)
|
||||
self.assertEqual(public_ips[0].state, "Allocated",
|
||||
"Assigned public IP is not in the allocated state"
|
||||
)
|
||||
if static_nat and vm:
|
||||
self.assertEqual(public_ips[0].virtualmachineid, vm.id,
|
||||
"Static NAT rule is not enabled for the VM on "
|
||||
"the assigned public IP"
|
||||
)
|
||||
self.debug("Successfully validated the assignment and state of public "
|
||||
"IP address - %s" % public_ip.ipaddress.ipaddress)
|
||||
|
||||
# create_NetworkOffering - Creates Network offering
|
||||
def create_NetworkOffering(self, net_offering, suffix=None,
|
||||
conserve_mode=False):
|
||||
@ -1095,7 +1171,8 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
% vpc.name)
|
||||
|
||||
# ssh_into_VM - Gets into the shell of the given VM using its public IP
|
||||
def ssh_into_VM(self, vm, public_ip, reconnect=True, negative_test=False):
|
||||
def ssh_into_VM(self, vm, public_ip, reconnect=True,
|
||||
negative_test=False, keypair=None):
|
||||
self.debug("SSH into VM with ID - %s on public IP address - %s" %
|
||||
(vm.id, public_ip.ipaddress.ipaddress))
|
||||
tries = 1 if negative_test else 3
|
||||
@ -1782,22 +1859,18 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
metadata=True,
|
||||
userdata=expected_user_data,
|
||||
ssh_key=self.keypair)
|
||||
vpc_public_ip_2 = \
|
||||
self.acquire_PublicIPAddress(create_tiernetwork2.network,
|
||||
create_vpc.vpc)
|
||||
self.create_StaticNatRule_For_VM(vm, vpc_public_ip_2,
|
||||
create_tiernetwork2.network)
|
||||
|
||||
vm.password = vm.resetPassword(self.api_client)
|
||||
self.debug("Password reset to - %s" % vm.password)
|
||||
self.debug("VM - %s password - %s !" %
|
||||
(vm.name, vm.password))
|
||||
self.verify_config_drive_content(vm, vpc_public_ip_2,
|
||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||
self.PasswordTest(vm.password),
|
||||
metadata=True,
|
||||
userdata=expected_user_data,
|
||||
ssh_key=self.keypair)
|
||||
expected_user_data1 = self.update_userdata(vm, "hellomultinicvm1")
|
||||
self.verify_config_drive_content(vm, vpc_public_ip_2,
|
||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||
self.PasswordTest(vm.password),
|
||||
userdata=expected_user_data1,
|
||||
ssh_key=self.keypair)
|
||||
@ -1807,6 +1880,14 @@ class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
|
||||
self.nic_operation_VM(vm,
|
||||
create_tiernetwork2.network,
|
||||
operation="update")
|
||||
vm.stop(self.api_client)
|
||||
vm.start(self.api_client)
|
||||
vpc_public_ip_2 = \
|
||||
self.acquire_PublicIPAddress(create_tiernetwork2.network,
|
||||
create_vpc.vpc)
|
||||
self.create_StaticNatRule_For_VM(vm, vpc_public_ip_2,
|
||||
create_tiernetwork2.network)
|
||||
|
||||
self.verify_config_drive_content(vm, vpc_public_ip_2,
|
||||
self.PasswordTest(vm.password),
|
||||
metadata=True,
|
||||
|
||||
@ -204,6 +204,15 @@ class TestNuageConfigDrive(nuageTestCase, ConfigDriveUtils):
|
||||
def validate_StaticNat_rule_For_VM(self, public_ip, network, vm):
|
||||
self.verify_vsd_floating_ip(network, vm, public_ip.ipaddress)
|
||||
|
||||
def _get_test_data(self, key):
|
||||
return self.test_data["nuagevsp"][key]
|
||||
|
||||
def get_configdrive_provider(self):
|
||||
return NetworkServiceProvider.list(
|
||||
self.api_client,
|
||||
name="ConfigDrive",
|
||||
physicalnetworkid=self.vsp_physical_network.id)[0]
|
||||
|
||||
def create_guest_vm(self, networks, acl_item=None,
|
||||
vpc=None, keypair=None):
|
||||
vm = self.create_VM(
|
||||
|
||||
@ -20,7 +20,7 @@ Nuage VSP SDN plugin
|
||||
"""
|
||||
# Import Local Modules
|
||||
from nuageTestCase import nuageTestCase
|
||||
from marvin.lib.base import Account
|
||||
from marvin.lib.base import Account, VPC
|
||||
# Import System Modules
|
||||
from nose.plugins.attrib import attr
|
||||
|
||||
@ -118,6 +118,12 @@ class TestNuageVpcNetwork(nuageTestCase):
|
||||
# VSD verification for ACL item
|
||||
self.verify_vsd_firewall_rule(acl_item)
|
||||
|
||||
self.restart_Vpc(vpc, cleanup=True)
|
||||
|
||||
self.validate_Network(vpc_network, state="Implemented")
|
||||
vr = self.get_Router(vpc_network)
|
||||
self.verify_vsd_router(vr)
|
||||
|
||||
@attr(
|
||||
tags=["advanced", "nuagevsp", "multizone"], required_hardware="false")
|
||||
def test_nuage_vpc_network_multizone(self):
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
"""
|
||||
# Import Local Modules
|
||||
from nuageTestCase import nuageTestCase
|
||||
from marvin.lib.base import Account, Nuage
|
||||
from marvin.lib.base import Account, Nuage, Network
|
||||
from marvin.cloudstackAPI import deleteNuageVspDevice
|
||||
# Import System Modules
|
||||
from nose.plugins.attrib import attr
|
||||
@ -158,7 +158,7 @@ class TestNuageVsp(nuageTestCase):
|
||||
"Physical Network...")
|
||||
self.validate_NuageVspDevice()
|
||||
|
||||
@attr(tags=["advanced", "nuagevsp"], required_hardware="false")
|
||||
@attr(tags=["advanced", "nuagevsp", "isolated"], required_hardware="false")
|
||||
def test_nuage_vsp(self):
|
||||
""" Test Nuage VSP SDN plugin with basic Isolated Network functionality
|
||||
"""
|
||||
@ -223,6 +223,12 @@ class TestNuageVsp(nuageTestCase):
|
||||
# VSD verification
|
||||
self.verify_vsd_vm(vm_2)
|
||||
|
||||
Network.restart(network, self.api_client, cleanup=True)
|
||||
|
||||
self.validate_Network(network, state="Implemented")
|
||||
vr = self.get_Router(network)
|
||||
self.verify_vsd_router(vr)
|
||||
|
||||
# Deleting the network
|
||||
self.debug("Deleting the Isolated Network with Nuage VSP Isolated "
|
||||
"Network offering...")
|
||||
|
||||
@ -992,7 +992,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
||||
|
||||
if (s_logger.isTraceEnabled())
|
||||
s_logger.trace("vCenter API trace - getHyperHostNetworkSummary() done(failed)");
|
||||
throw new Exception("Uanble to find management port group " + managementPortGroup);
|
||||
throw new Exception("Unable to find management port group " + managementPortGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user