mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Forward merge branch '4.11' to master
ConfigDrive fixes: CLOUDSTACK-10288, CLOUDSTACK-10289 (#2566) CLOUDSTACK-9677: Adding storage policy support for swift as secondary storage (#2412)
This commit is contained in:
commit
b3c22df71d
@ -26,17 +26,19 @@ public class SwiftTO implements DataStoreTO, SwiftUtil.SwiftClientCfg {
|
|||||||
|
|
||||||
String userName;
|
String userName;
|
||||||
String key;
|
String key;
|
||||||
|
String storagePolicy;
|
||||||
private static final String pathSeparator = "/";
|
private static final String pathSeparator = "/";
|
||||||
|
|
||||||
public SwiftTO() {
|
public SwiftTO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SwiftTO(Long id, String url, String account, String userName, String key) {
|
public SwiftTO(Long id, String url, String account, String userName, String key, String storagePolicy) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
this.storagePolicy = storagePolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@ -63,6 +65,11 @@ public class SwiftTO implements DataStoreTO, SwiftUtil.SwiftClientCfg {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStoragePolicy() {
|
||||||
|
return this.storagePolicy;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataStoreRole getRole() {
|
public DataStoreRole getRole() {
|
||||||
return DataStoreRole.Image;
|
return DataStoreRole.Image;
|
||||||
|
|||||||
@ -59,6 +59,9 @@ public interface NetworkModel {
|
|||||||
String SERVICE_OFFERING_FILE = "service-offering";
|
String SERVICE_OFFERING_FILE = "service-offering";
|
||||||
String AVAILABILITY_ZONE_FILE = "availability-zone";
|
String AVAILABILITY_ZONE_FILE = "availability-zone";
|
||||||
String LOCAL_HOSTNAME_FILE = "local-hostname";
|
String LOCAL_HOSTNAME_FILE = "local-hostname";
|
||||||
|
String LOCAL_IPV4_FILE = "local-ipv4";
|
||||||
|
String PUBLIC_HOSTNAME_FILE = "public-hostname";
|
||||||
|
String PUBLIC_IPV4_FILE = "public-ipv4";
|
||||||
String INSTANCE_ID_FILE = "instance-id";
|
String INSTANCE_ID_FILE = "instance-id";
|
||||||
String VM_ID_FILE = "vm-id";
|
String VM_ID_FILE = "vm-id";
|
||||||
String PUBLIC_KEYS_FILE = "public-keys";
|
String PUBLIC_KEYS_FILE = "public-keys";
|
||||||
@ -309,8 +312,8 @@ public interface NetworkModel {
|
|||||||
|
|
||||||
boolean getNetworkEgressDefaultPolicy(Long networkId);
|
boolean getNetworkEgressDefaultPolicy(Long networkId);
|
||||||
|
|
||||||
List<String[]> generateVmData(String userData, String serviceOffering, String zoneName,
|
List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId,
|
||||||
String vmName, long vmId, String publicKey, String password, Boolean isWindows);
|
String vmName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows);
|
||||||
|
|
||||||
String getValidNetworkCidr(Network guestNetwork);
|
String getValidNetworkCidr(Network guestNetwork);
|
||||||
|
|
||||||
|
|||||||
@ -289,6 +289,7 @@ public class ApiConstants {
|
|||||||
public static final String STATE = "state";
|
public static final String STATE = "state";
|
||||||
public static final String STATUS = "status";
|
public static final String STATUS = "status";
|
||||||
public static final String STORAGE_TYPE = "storagetype";
|
public static final String STORAGE_TYPE = "storagetype";
|
||||||
|
public static final String STORAGE_POLICY = "storagepolicy";
|
||||||
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
||||||
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
|
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
|
||||||
public static final String SYSTEM_VM_TYPE = "systemvmtype";
|
public static final String SYSTEM_VM_TYPE = "systemvmtype";
|
||||||
|
|||||||
@ -2542,16 +2542,15 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
if (defaultNic != null) {
|
if (defaultNic != null) {
|
||||||
UserVmVO userVm = _userVmDao.findById(vm.getId());
|
UserVmVO userVm = _userVmDao.findById(vm.getId());
|
||||||
Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
|
Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
|
||||||
vm.setDetails(details);
|
userVm.setDetails(details);
|
||||||
|
|
||||||
Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
|
Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
|
||||||
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
||||||
final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
|
final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
|
||||||
final String zoneName = _dcDao.findById(vm.getDataCenterId()).getName();
|
|
||||||
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
||||||
|
|
||||||
vmData = _networkModel.generateVmData(userVm.getUserData(), serviceOffering, zoneName, vm.getInstanceName(), vm.getId(),
|
vmData = _networkModel.generateVmData(userVm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getId(),
|
||||||
(String) profile.getParameter(VirtualMachineProfile.Param.VmSshPubKey), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
|
vm.getUuid(), defaultNic.getMacAddress(), userVm.getDetail("SSH.PublicKey"), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
|
||||||
String vmName = vm.getInstanceName();
|
String vmName = vm.getInstanceName();
|
||||||
String configDriveIsoRootFolder = "/tmp";
|
String configDriveIsoRootFolder = "/tmp";
|
||||||
String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
|
String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
|
||||||
|
|||||||
@ -18,23 +18,24 @@
|
|||||||
*/
|
*/
|
||||||
package com.cloud.hypervisor.xenserver.resource;
|
package com.cloud.hypervisor.xenserver.resource;
|
||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
import static com.cloud.utils.ReflectUtil.flattenProperties;
|
||||||
import com.cloud.agent.api.to.DataObjectType;
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
import com.cloud.agent.api.to.DataStoreTO;
|
|
||||||
import com.cloud.agent.api.to.DataTO;
|
import java.io.File;
|
||||||
import com.cloud.agent.api.to.DiskTO;
|
import java.net.URI;
|
||||||
import com.cloud.agent.api.to.NfsTO;
|
import java.util.ArrayList;
|
||||||
import com.cloud.agent.api.to.S3TO;
|
import java.util.Arrays;
|
||||||
import com.cloud.agent.api.to.SwiftTO;
|
import java.util.HashMap;
|
||||||
import com.cloud.exception.InternalErrorException;
|
import java.util.List;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import java.util.Map;
|
||||||
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.SRType;
|
import java.util.Set;
|
||||||
import com.cloud.storage.DataStoreRole;
|
import java.util.UUID;
|
||||||
import com.cloud.storage.Storage;
|
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import com.cloud.storage.resource.StorageProcessor;
|
import org.apache.log4j.Logger;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import org.apache.xmlrpc.XmlRpcException;
|
||||||
import com.cloud.utils.storage.S3.ClientOptions;
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.xensource.xenapi.Connection;
|
import com.xensource.xenapi.Connection;
|
||||||
import com.xensource.xenapi.SR;
|
import com.xensource.xenapi.SR;
|
||||||
import com.xensource.xenapi.Types;
|
import com.xensource.xenapi.Types;
|
||||||
@ -44,6 +45,7 @@ import com.xensource.xenapi.Types.XenAPIException;
|
|||||||
import com.xensource.xenapi.VBD;
|
import com.xensource.xenapi.VBD;
|
||||||
import com.xensource.xenapi.VDI;
|
import com.xensource.xenapi.VDI;
|
||||||
import com.xensource.xenapi.VM;
|
import com.xensource.xenapi.VM;
|
||||||
|
|
||||||
import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
|
import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
|
||||||
import org.apache.cloudstack.storage.command.AttachAnswer;
|
import org.apache.cloudstack.storage.command.AttachAnswer;
|
||||||
import org.apache.cloudstack.storage.command.AttachCommand;
|
import org.apache.cloudstack.storage.command.AttachCommand;
|
||||||
@ -65,20 +67,24 @@ import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
|
|||||||
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
||||||
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
||||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.apache.xmlrpc.XmlRpcException;
|
|
||||||
|
|
||||||
import java.io.File;
|
import com.cloud.agent.api.Answer;
|
||||||
import java.net.URI;
|
import com.cloud.agent.api.to.DataObjectType;
|
||||||
import java.util.Arrays;
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
import java.util.HashMap;
|
import com.cloud.agent.api.to.DataTO;
|
||||||
import java.util.List;
|
import com.cloud.agent.api.to.DiskTO;
|
||||||
import java.util.Map;
|
import com.cloud.agent.api.to.NfsTO;
|
||||||
import java.util.Set;
|
import com.cloud.agent.api.to.S3TO;
|
||||||
import java.util.UUID;
|
import com.cloud.agent.api.to.SwiftTO;
|
||||||
|
import com.cloud.exception.InternalErrorException;
|
||||||
import static com.cloud.utils.ReflectUtil.flattenProperties;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import static com.google.common.collect.Lists.newArrayList;
|
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.SRType;
|
||||||
|
import com.cloud.storage.DataStoreRole;
|
||||||
|
import com.cloud.storage.Storage;
|
||||||
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
|
import com.cloud.storage.resource.StorageProcessor;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.utils.storage.S3.ClientOptions;
|
||||||
|
|
||||||
public class XenServerStorageProcessor implements StorageProcessor {
|
public class XenServerStorageProcessor implements StorageProcessor {
|
||||||
private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
|
private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
|
||||||
@ -914,20 +920,55 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
private boolean swiftUpload(final Connection conn, final SwiftTO swift, final String container, final String ldir, final String lfilename, final Boolean isISCSI,
|
private boolean swiftUpload(final Connection conn, final SwiftTO swift, final String container, final String ldir, final String lfilename, final Boolean isISCSI,
|
||||||
final int wait) {
|
final int wait) {
|
||||||
String result = null;
|
|
||||||
|
List<String> params = getSwiftParams(swift, container, ldir, lfilename, isISCSI);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result =
|
String result = hypervisorResource.callHostPluginAsync(conn, "swiftxenserver", "swift", wait, params.toArray(new String[params.size()]));
|
||||||
hypervisorResource.callHostPluginAsync(conn, "swiftxenserver", "swift", wait, "op", "upload", "url", swift.getUrl(), "account", swift.getAccount(), "username",
|
return BooleanUtils.toBoolean(result);
|
||||||
swift.getUserName(), "key", swift.getKey(), "container", container, "ldir", ldir, "lfilename", lfilename, "isISCSI", isISCSI.toString());
|
|
||||||
if (result != null && result.equals("true")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
s_logger.warn("swift upload failed due to " + e.toString(), e);
|
s_logger.warn("swift upload failed due to " + e.toString(), e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
List<String> getSwiftParams(SwiftTO swift, String container, String ldir, String lfilename, Boolean isISCSI) {
|
||||||
|
// ORDER IS IMPORTANT
|
||||||
|
List<String> params = new ArrayList<>();
|
||||||
|
|
||||||
|
//operation
|
||||||
|
params.add("op");
|
||||||
|
params.add("upload");
|
||||||
|
|
||||||
|
//auth
|
||||||
|
params.add("url");
|
||||||
|
params.add(swift.getUrl());
|
||||||
|
params.add("account");
|
||||||
|
params.add(swift.getAccount());
|
||||||
|
params.add("username");
|
||||||
|
params.add(swift.getUserName());
|
||||||
|
params.add("key");
|
||||||
|
params.add(swift.getKey());
|
||||||
|
|
||||||
|
// object info
|
||||||
|
params.add("container");
|
||||||
|
params.add(container);
|
||||||
|
params.add("ldir");
|
||||||
|
params.add(ldir);
|
||||||
|
params.add("lfilename");
|
||||||
|
params.add(lfilename);
|
||||||
|
params.add("isISCSI");
|
||||||
|
params.add(isISCSI.toString());
|
||||||
|
|
||||||
|
if (swift.getStoragePolicy() != null) {
|
||||||
|
params.add("storagepolicy");
|
||||||
|
params.add(swift.getStoragePolicy());
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
protected String deleteSnapshotBackup(final Connection conn, final String localMountPoint, final String path, final String secondaryStorageMountPath, final String backupUUID) {
|
protected String deleteSnapshotBackup(final Connection conn, final String localMountPoint, final String path, final String secondaryStorageMountPath, final String backupUUID) {
|
||||||
|
|
||||||
// If anybody modifies the formatting below again, I'll skin them
|
// If anybody modifies the formatting below again, I'll skin them
|
||||||
|
|||||||
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.cloud.hypervisor.xenserver.resource;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.to.SwiftTO;
|
||||||
|
|
||||||
|
public class XenServerStorageProcessorTest {
|
||||||
|
@Test
|
||||||
|
public void testOrderOfSwiftUplodScriptParamsWithoutStoragePolicy() {
|
||||||
|
CitrixResourceBase resource = Mockito.mock(CitrixResourceBase.class);
|
||||||
|
XenServerStorageProcessor mock = new XenServerStorageProcessor(resource);
|
||||||
|
|
||||||
|
SwiftTO swift = Mockito.mock(SwiftTO.class);
|
||||||
|
when(swift.getStoragePolicy()).thenReturn(null);
|
||||||
|
|
||||||
|
String container = "sample-container-name";
|
||||||
|
String ldir = "sample-ldir";
|
||||||
|
String lfilename = "sample-lfilename";
|
||||||
|
Boolean isISCSI = true;
|
||||||
|
|
||||||
|
List<String> params = mock.getSwiftParams(swift, container, ldir, lfilename, isISCSI);
|
||||||
|
|
||||||
|
// make sure the params not null and has correct number of items in it
|
||||||
|
Assert.assertNotNull("params is null", params);
|
||||||
|
Assert.assertTrue("Expected param list size is 18 but it was" + params.size(), params.size() == 18);
|
||||||
|
|
||||||
|
// check the order of params
|
||||||
|
Assert.assertEquals("unexpected param.", "op", params.get(0));
|
||||||
|
Assert.assertEquals("unexpected param.", "upload", params.get(1));
|
||||||
|
Assert.assertEquals("unexpected param.", "url", params.get(2));
|
||||||
|
Assert.assertEquals("unexpected param.", swift.getUrl(), params.get(3));
|
||||||
|
Assert.assertEquals("unexpected param.", "account", params.get(4));
|
||||||
|
Assert.assertEquals("unexpected param.", swift.getAccount(), params.get(5));
|
||||||
|
Assert.assertEquals("unexpected param.", "username", params.get(6));
|
||||||
|
Assert.assertEquals("unexpected param.", swift.getUserName(), params.get(7));
|
||||||
|
Assert.assertEquals("unexpected param.", "key", params.get(8));
|
||||||
|
Assert.assertEquals("unexpected param.", swift.getKey(), params.get(9));
|
||||||
|
Assert.assertEquals("unexpected param.", "container", params.get(10));
|
||||||
|
Assert.assertEquals("unexpected param.", container, params.get(11));
|
||||||
|
Assert.assertEquals("unexpected param.", "ldir", params.get(12));
|
||||||
|
Assert.assertEquals("unexpected param.", ldir, params.get(13));
|
||||||
|
Assert.assertEquals("unexpected param.", "lfilename", params.get(14));
|
||||||
|
Assert.assertEquals("unexpected param.", lfilename, params.get(15));
|
||||||
|
Assert.assertEquals("unexpected param.", "isISCSI", params.get(16));
|
||||||
|
Assert.assertEquals("unexpected param.", isISCSI.toString(), params.get(17));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOrderOfSwiftUplodScriptParamsWithStoragePolicy() {
|
||||||
|
CitrixResourceBase resource = Mockito.mock(CitrixResourceBase.class);
|
||||||
|
XenServerStorageProcessor mock = new XenServerStorageProcessor(resource);
|
||||||
|
|
||||||
|
SwiftTO swift = Mockito.mock(SwiftTO.class);
|
||||||
|
when(swift.getStoragePolicy()).thenReturn("sample-storagepolicy");
|
||||||
|
|
||||||
|
String container = "sample-container-name";
|
||||||
|
String ldir = "sample-ldir";
|
||||||
|
String lfilename = "sample-lfilename";
|
||||||
|
Boolean isISCSI = true;
|
||||||
|
|
||||||
|
List<String> params = mock.getSwiftParams(swift, container, ldir, lfilename, isISCSI);
|
||||||
|
|
||||||
|
// make sure the params not null and has correct number of items in it
|
||||||
|
Assert.assertNotNull("params is null", params);
|
||||||
|
Assert.assertTrue("Expected param list size is 20 but it was" + params.size(), params.size() == 20);
|
||||||
|
|
||||||
|
// check the order of params
|
||||||
|
Assert.assertEquals("unexpected param.", "op", params.get(0));
|
||||||
|
Assert.assertEquals("unexpected param.", "upload", params.get(1));
|
||||||
|
Assert.assertEquals("unexpected param.", "url", params.get(2));
|
||||||
|
Assert.assertEquals("unexpected param.", swift.getUrl(), params.get(3));
|
||||||
|
Assert.assertEquals("unexpected param.", "account", params.get(4));
|
||||||
|
Assert.assertEquals("unexpected param.", swift.getAccount(), params.get(5));
|
||||||
|
Assert.assertEquals("unexpected param.", "username", params.get(6));
|
||||||
|
Assert.assertEquals("unexpected param.", swift.getUserName(), params.get(7));
|
||||||
|
Assert.assertEquals("unexpected param.", "key", params.get(8));
|
||||||
|
Assert.assertEquals("unexpected param.", swift.getKey(), params.get(9));
|
||||||
|
Assert.assertEquals("unexpected param.", "container", params.get(10));
|
||||||
|
Assert.assertEquals("unexpected param.", container, params.get(11));
|
||||||
|
Assert.assertEquals("unexpected param.", "ldir", params.get(12));
|
||||||
|
Assert.assertEquals("unexpected param.", ldir, params.get(13));
|
||||||
|
Assert.assertEquals("unexpected param.", "lfilename", params.get(14));
|
||||||
|
Assert.assertEquals("unexpected param.", lfilename, params.get(15));
|
||||||
|
Assert.assertEquals("unexpected param.", "isISCSI", params.get(16));
|
||||||
|
Assert.assertEquals("unexpected param.", isISCSI.toString(), params.get(17));
|
||||||
|
Assert.assertEquals("unexpected param.", "storagepolicy", params.get(18));
|
||||||
|
Assert.assertEquals("unexpected param.", "sample-storagepolicy", params.get(19));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -68,7 +68,7 @@ public class SwiftImageStoreDriverImpl extends BaseImageStoreDriverImpl {
|
|||||||
public DataStoreTO getStoreTO(DataStore store) {
|
public DataStoreTO getStoreTO(DataStore store) {
|
||||||
ImageStoreImpl imgStore = (ImageStoreImpl)store;
|
ImageStoreImpl imgStore = (ImageStoreImpl)store;
|
||||||
Map<String, String> details = _imageStoreDetailsDao.getDetails(imgStore.getId());
|
Map<String, String> details = _imageStoreDetailsDao.getDetails(imgStore.getId());
|
||||||
return new SwiftTO(imgStore.getId(), imgStore.getUri(), details.get(ApiConstants.ACCOUNT), details.get(ApiConstants.USERNAME), details.get(ApiConstants.KEY));
|
return new SwiftTO(imgStore.getId(), imgStore.getUri(), details.get(ApiConstants.ACCOUNT), details.get(ApiConstants.USERNAME), details.get(ApiConstants.KEY), details.get(ApiConstants.STORAGE_POLICY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -1473,8 +1473,9 @@ post [options] [container] [object]
|
|||||||
Updates meta information for the account, container, or object depending on
|
Updates meta information for the account, container, or object depending on
|
||||||
the args given. If the container is not found, it will be created
|
the args given. If the container is not found, it will be created
|
||||||
automatically; but this is not true for accounts and objects. Containers
|
automatically; but this is not true for accounts and objects. Containers
|
||||||
also allow the -r (or --read-acl) and -w (or --write-acl) options. The -m
|
also allow the -r (or --read-acl) and -w (or --write-acl) options.
|
||||||
or --meta option is allowed on all and used to define the user meta data
|
The --storage-policy will set a storage policy to the container if the container does not exist.
|
||||||
|
The -m or --meta option is allowed on all and used to define the user meta data
|
||||||
items to set in the form Name:Value. This option can be repeated. Example:
|
items to set in the form Name:Value. This option can be repeated. Example:
|
||||||
post -m Color:Blue -m Size:Large'''.strip('\n')
|
post -m Color:Blue -m Size:Large'''.strip('\n')
|
||||||
|
|
||||||
@ -1493,6 +1494,8 @@ def st_post(options, args, print_queue, error_queue):
|
|||||||
parser.add_option('-m', '--meta', action='append', dest='meta', default=[],
|
parser.add_option('-m', '--meta', action='append', dest='meta', default=[],
|
||||||
help='Sets a meta data item with the syntax name:value. This option '
|
help='Sets a meta data item with the syntax name:value. This option '
|
||||||
'may be repeated. Example: -m Color:Blue -m Size:Large')
|
'may be repeated. Example: -m Color:Blue -m Size:Large')
|
||||||
|
parser.add_option('', '--storage-policy', action='store', dest='storage_policy',
|
||||||
|
help='Sets a storage policy to the container if the container does not exist')
|
||||||
(options, args) = parse_args(parser, args)
|
(options, args) = parse_args(parser, args)
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
if (options.read_acl or options.write_acl or options.sync_to or
|
if (options.read_acl or options.write_acl or options.sync_to or
|
||||||
@ -1529,6 +1532,8 @@ def st_post(options, args, print_queue, error_queue):
|
|||||||
headers['X-Container-Sync-To'] = options.sync_to
|
headers['X-Container-Sync-To'] = options.sync_to
|
||||||
if options.sync_key is not None:
|
if options.sync_key is not None:
|
||||||
headers['X-Container-Sync-Key'] = options.sync_key
|
headers['X-Container-Sync-Key'] = options.sync_key
|
||||||
|
if options.storage_policy is not None:
|
||||||
|
headers['X-Storage-Policy'] = options.storage_policy
|
||||||
try:
|
try:
|
||||||
conn.post_container(args[0], headers=headers)
|
conn.post_container(args[0], headers=headers)
|
||||||
except ClientException, err:
|
except ClientException, err:
|
||||||
@ -1558,7 +1563,8 @@ upload [options] container file_or_directory [file_or_directory] [...]
|
|||||||
Uploads to the given container the files and directories specified by the
|
Uploads to the given container the files and directories specified by the
|
||||||
remaining args. -c or --changed is an option that will only upload files
|
remaining args. -c or --changed is an option that will only upload files
|
||||||
that have changed since the last upload. -S <size> or --segment-size <size>
|
that have changed since the last upload. -S <size> or --segment-size <size>
|
||||||
and --leave-segments are options as well (see --help for more).
|
and --leave-segments are options as well (see --help for more). --storage-policy
|
||||||
|
Sets a storage policy to the container if the container does not exist.
|
||||||
'''.strip('\n')
|
'''.strip('\n')
|
||||||
|
|
||||||
|
|
||||||
@ -1576,6 +1582,8 @@ def st_upload(options, args, print_queue, error_queue):
|
|||||||
dest='leave_segments', default=False, help='Indicates that you want '
|
dest='leave_segments', default=False, help='Indicates that you want '
|
||||||
'the older segments of manifest objects left alone (in the case of '
|
'the older segments of manifest objects left alone (in the case of '
|
||||||
'overwrites)')
|
'overwrites)')
|
||||||
|
parser.add_option('', '--storage-policy', action='store', dest='storage_policy',
|
||||||
|
help='Sets a storage policy to the container if the container does not exist')
|
||||||
(options, args) = parse_args(parser, args)
|
(options, args) = parse_args(parser, args)
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
if len(args) < 2:
|
if len(args) < 2:
|
||||||
@ -1749,9 +1757,12 @@ def st_upload(options, args, print_queue, error_queue):
|
|||||||
# permissions, so we'll ignore any error. If there's really a problem,
|
# permissions, so we'll ignore any error. If there's really a problem,
|
||||||
# it'll surface on the first object PUT.
|
# it'll surface on the first object PUT.
|
||||||
try:
|
try:
|
||||||
conn.put_container(args[0])
|
container_headers = {}
|
||||||
|
if options.storage_policy is not None:
|
||||||
|
container_headers['X-Storage-Policy'] = options.storage_policy
|
||||||
|
conn.put_container(args[0],headers=container_headers)
|
||||||
if options.segment_size is not None:
|
if options.segment_size is not None:
|
||||||
conn.put_container(args[0] + '_segments')
|
conn.put_container(args[0] + '_segments',headers=container_headers)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -1475,8 +1475,9 @@ post [options] [container] [object]
|
|||||||
Updates meta information for the account, container, or object depending on
|
Updates meta information for the account, container, or object depending on
|
||||||
the args given. If the container is not found, it will be created
|
the args given. If the container is not found, it will be created
|
||||||
automatically; but this is not true for accounts and objects. Containers
|
automatically; but this is not true for accounts and objects. Containers
|
||||||
also allow the -r (or --read-acl) and -w (or --write-acl) options. The -m
|
also allow the -r (or --read-acl) and -w (or --write-acl) options.
|
||||||
or --meta option is allowed on all and used to define the user meta data
|
The --storage-policy will set a storage policy to the container if the container does not exist.
|
||||||
|
The -m or --meta option is allowed on all and used to define the user meta data
|
||||||
items to set in the form Name:Value. This option can be repeated. Example:
|
items to set in the form Name:Value. This option can be repeated. Example:
|
||||||
post -m Color:Blue -m Size:Large'''.strip('\n')
|
post -m Color:Blue -m Size:Large'''.strip('\n')
|
||||||
|
|
||||||
@ -1495,6 +1496,8 @@ def st_post(options, args, print_queue, error_queue):
|
|||||||
parser.add_option('-m', '--meta', action='append', dest='meta', default=[],
|
parser.add_option('-m', '--meta', action='append', dest='meta', default=[],
|
||||||
help='Sets a meta data item with the syntax name:value. This option '
|
help='Sets a meta data item with the syntax name:value. This option '
|
||||||
'may be repeated. Example: -m Color:Blue -m Size:Large')
|
'may be repeated. Example: -m Color:Blue -m Size:Large')
|
||||||
|
parser.add_option('', '--storage-policy', action='store', dest='storage_policy',
|
||||||
|
help='Sets a storage policy to the container if the container does not exist')
|
||||||
(options, args) = parse_args(parser, args)
|
(options, args) = parse_args(parser, args)
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
if (options.read_acl or options.write_acl or options.sync_to or
|
if (options.read_acl or options.write_acl or options.sync_to or
|
||||||
@ -1531,6 +1534,8 @@ def st_post(options, args, print_queue, error_queue):
|
|||||||
headers['X-Container-Sync-To'] = options.sync_to
|
headers['X-Container-Sync-To'] = options.sync_to
|
||||||
if options.sync_key is not None:
|
if options.sync_key is not None:
|
||||||
headers['X-Container-Sync-Key'] = options.sync_key
|
headers['X-Container-Sync-Key'] = options.sync_key
|
||||||
|
if options.storage_policy is not None:
|
||||||
|
headers['X-Storage-Policy'] = options.storage_policy
|
||||||
try:
|
try:
|
||||||
conn.post_container(args[0], headers=headers)
|
conn.post_container(args[0], headers=headers)
|
||||||
except ClientException, err:
|
except ClientException, err:
|
||||||
@ -1560,7 +1565,8 @@ upload [options] container file_or_directory [file_or_directory] [...]
|
|||||||
Uploads to the given container the files and directories specified by the
|
Uploads to the given container the files and directories specified by the
|
||||||
remaining args. -c or --changed is an option that will only upload files
|
remaining args. -c or --changed is an option that will only upload files
|
||||||
that have changed since the last upload. -S <size> or --segment-size <size>
|
that have changed since the last upload. -S <size> or --segment-size <size>
|
||||||
and --leave-segments are options as well (see --help for more).
|
and --leave-segments are options as well (see --help for more). --storage-policy
|
||||||
|
Sets a storage policy to the container if the container does not exist.
|
||||||
'''.strip('\n')
|
'''.strip('\n')
|
||||||
|
|
||||||
|
|
||||||
@ -1578,6 +1584,8 @@ def st_upload(options, args, print_queue, error_queue):
|
|||||||
dest='leave_segments', default=False, help='Indicates that you want '
|
dest='leave_segments', default=False, help='Indicates that you want '
|
||||||
'the older segments of manifest objects left alone (in the case of '
|
'the older segments of manifest objects left alone (in the case of '
|
||||||
'overwrites)')
|
'overwrites)')
|
||||||
|
parser.add_option('', '--storage-policy', action='store', dest='storage_policy',
|
||||||
|
help='Sets a storage policy to the container if the container does not exist')
|
||||||
(options, args) = parse_args(parser, args)
|
(options, args) = parse_args(parser, args)
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
if len(args) < 2:
|
if len(args) < 2:
|
||||||
@ -1751,9 +1759,12 @@ def st_upload(options, args, print_queue, error_queue):
|
|||||||
# permissions, so we'll ignore any error. If there's really a problem,
|
# permissions, so we'll ignore any error. If there's really a problem,
|
||||||
# it'll surface on the first object PUT.
|
# it'll surface on the first object PUT.
|
||||||
try:
|
try:
|
||||||
conn.put_container(args[0])
|
container_headers = {}
|
||||||
|
if options.storage_policy is not None:
|
||||||
|
container_headers['X-Storage-Policy'] = options.storage_policy
|
||||||
|
conn.put_container(args[0],headers=container_headers)
|
||||||
if options.segment_size is not None:
|
if options.segment_size is not None:
|
||||||
conn.put_container(args[0] + '_segments')
|
conn.put_container(args[0] + '_segments',headers=container_headers)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import java.security.InvalidParameterException;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -29,24 +30,24 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.Collections;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
import org.apache.cloudstack.framework.config.Configurable;
|
import org.apache.cloudstack.framework.config.Configurable;
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
|
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
|
||||||
|
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
import com.cloud.configuration.Config;
|
import com.cloud.configuration.Config;
|
||||||
import com.cloud.configuration.ConfigurationManager;
|
import com.cloud.configuration.ConfigurationManager;
|
||||||
import com.cloud.dc.DataCenter;
|
import com.cloud.dc.DataCenter;
|
||||||
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.dc.PodVlanMapVO;
|
import com.cloud.dc.PodVlanMapVO;
|
||||||
import com.cloud.dc.Vlan;
|
import com.cloud.dc.Vlan;
|
||||||
import com.cloud.dc.Vlan.VlanType;
|
import com.cloud.dc.Vlan.VlanType;
|
||||||
@ -2344,18 +2345,47 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String[]> generateVmData(String userData, String serviceOffering, String zoneName,
|
public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId,
|
||||||
String vmName, long vmId, String publicKey, String password, Boolean isWindows) {
|
String vmName, long vmId, String vmUuid,
|
||||||
|
String guestIpAddress, String publicKey, String password, Boolean isWindows) {
|
||||||
|
|
||||||
|
DataCenterVO dcVo = _dcDao.findById(datacenterId);
|
||||||
|
final String zoneName = dcVo.getName();
|
||||||
|
|
||||||
|
IPAddressVO publicIp = _ipAddressDao.findByAssociatedVmId(vmId);
|
||||||
|
|
||||||
final List<String[]> vmData = new ArrayList<String[]>();
|
final List<String[]> vmData = new ArrayList<String[]>();
|
||||||
|
|
||||||
if (userData != null) {
|
if (userData != null) {
|
||||||
vmData.add(new String[]{USERDATA_DIR, USERDATA_FILE, new String(Base64.decodeBase64(userData),StringUtils.getPreferredCharset())});
|
vmData.add(new String[]{USERDATA_DIR, USERDATA_FILE, userData});
|
||||||
}
|
}
|
||||||
vmData.add(new String[]{METATDATA_DIR, SERVICE_OFFERING_FILE, StringUtils.unicodeEscape(serviceOffering)});
|
vmData.add(new String[]{METATDATA_DIR, SERVICE_OFFERING_FILE, StringUtils.unicodeEscape(serviceOffering)});
|
||||||
vmData.add(new String[]{METATDATA_DIR, AVAILABILITY_ZONE_FILE, StringUtils.unicodeEscape(zoneName)});
|
vmData.add(new String[]{METATDATA_DIR, AVAILABILITY_ZONE_FILE, StringUtils.unicodeEscape(zoneName)});
|
||||||
vmData.add(new String[]{METATDATA_DIR, LOCAL_HOSTNAME_FILE, StringUtils.unicodeEscape(vmName)});
|
vmData.add(new String[]{METATDATA_DIR, LOCAL_HOSTNAME_FILE, StringUtils.unicodeEscape(vmName)});
|
||||||
|
vmData.add(new String[]{METATDATA_DIR, LOCAL_IPV4_FILE, guestIpAddress});
|
||||||
|
|
||||||
|
String publicIpAddress = guestIpAddress;
|
||||||
|
String publicHostName = StringUtils.unicodeEscape(vmName);
|
||||||
|
|
||||||
|
if (dcVo.getNetworkType() != DataCenter.NetworkType.Basic) {
|
||||||
|
if (publicIp != null) {
|
||||||
|
publicIpAddress = publicIp.getAddress().addr();
|
||||||
|
publicHostName = publicIp.getAddress().addr();
|
||||||
|
} else {
|
||||||
|
publicHostName = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vmData.add(new String[]{METATDATA_DIR, PUBLIC_IPV4_FILE, publicIpAddress});
|
||||||
|
vmData.add(new String[]{METATDATA_DIR, PUBLIC_HOSTNAME_FILE, publicHostName});
|
||||||
|
|
||||||
|
if (vmUuid == null) {
|
||||||
vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmName});
|
vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmName});
|
||||||
vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, String.valueOf(vmId)});
|
vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, String.valueOf(vmId)});
|
||||||
|
} else {
|
||||||
|
vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmUuid});
|
||||||
|
vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, vmUuid});
|
||||||
|
}
|
||||||
|
|
||||||
vmData.add(new String[]{METATDATA_DIR, PUBLIC_KEYS_FILE, publicKey});
|
vmData.add(new String[]{METATDATA_DIR, PUBLIC_KEYS_FILE, publicKey});
|
||||||
|
|
||||||
String cloudIdentifier = _configDao.getValue("cloud.identifier");
|
String cloudIdentifier = _configDao.getValue("cloud.identifier");
|
||||||
|
|||||||
@ -206,30 +206,37 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getSshKey(VirtualMachineProfile profile) {
|
||||||
|
UserVmDetailVO vmDetailSshKey = _userVmDetailsDao.findDetail(profile.getId(), "SSH.PublicKey");
|
||||||
|
return (vmDetailSshKey!=null ? vmDetailSshKey.getValue() : null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context)
|
public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context)
|
||||||
throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
|
throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
|
||||||
UserVmDetailVO vmDetailSshKey = _userVmDetailsDao.findDetail(profile.getId(), "SSH.PublicKey");
|
String sshPublicKey = getSshKey(profile);
|
||||||
return (canHandle(network.getTrafficType()) && updateConfigDrive(profile,
|
return (canHandle(network.getTrafficType())
|
||||||
(vmDetailSshKey!=null?vmDetailSshKey.getValue():null)))
|
&& updateConfigDrive(profile, sshPublicKey, nic))
|
||||||
&& updateConfigDriveIso(network, profile, dest.getHost(), false);
|
&& updateConfigDriveIso(network, profile, dest.getHost(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile profile) throws ResourceUnavailableException {
|
public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile profile) throws ResourceUnavailableException {
|
||||||
if (!(canHandle(network.getTrafficType()) && updateConfigDrive(profile, (String) profile.getParameter(VirtualMachineProfile.Param.VmSshPubKey)))) return false;
|
String sshPublicKey = getSshKey(profile);
|
||||||
|
if (!(canHandle(network.getTrafficType()) && updateConfigDrive(profile, sshPublicKey, nic))) return false;
|
||||||
return updateConfigDriveIso(network, profile, true);
|
return updateConfigDriveIso(network, profile, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean saveSSHKey(Network network, NicProfile nic, VirtualMachineProfile vm, String sshPublicKey) throws ResourceUnavailableException {
|
public boolean saveSSHKey(Network network, NicProfile nic, VirtualMachineProfile vm, String sshPublicKey) throws ResourceUnavailableException {
|
||||||
if (!(canHandle(network.getTrafficType()) && updateConfigDrive(vm, sshPublicKey))) return false;
|
if (!(canHandle(network.getTrafficType()) && updateConfigDrive(vm, sshPublicKey, nic))) return false;
|
||||||
return updateConfigDriveIso(network, vm, true);
|
return updateConfigDriveIso(network, vm, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean saveUserData(Network network, NicProfile nic, VirtualMachineProfile profile) throws ResourceUnavailableException {
|
public boolean saveUserData(Network network, NicProfile nic, VirtualMachineProfile profile) throws ResourceUnavailableException {
|
||||||
if (!(canHandle(network.getTrafficType()) && updateConfigDrive(profile, (String) profile.getParameter(VirtualMachineProfile.Param.VmSshPubKey)))) return false;
|
String sshPublicKey = getSshKey(profile);
|
||||||
|
if (!(canHandle(network.getTrafficType()) && updateConfigDrive(profile, sshPublicKey, nic))) return false;
|
||||||
return updateConfigDriveIso(network, profile, true);
|
return updateConfigDriveIso(network, profile, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +337,7 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
|
|||||||
Answer createIsoAnswer = endpoint.sendMessage(configDriveIsoCommand);
|
Answer createIsoAnswer = endpoint.sendMessage(configDriveIsoCommand);
|
||||||
if (!createIsoAnswer.getResult()) {
|
if (!createIsoAnswer.getResult()) {
|
||||||
throw new ResourceUnavailableException(String.format("%s ISO failed, details: %s",
|
throw new ResourceUnavailableException(String.format("%s ISO failed, details: %s",
|
||||||
(update?"Update":"Create"), createIsoAnswer.getDetails()),ConfigDriveNetworkElement.class,0L);
|
(update?"Update":"Create"), createIsoAnswer.getDetails()), ConfigDriveNetworkElement.class, 0L);
|
||||||
}
|
}
|
||||||
configureConfigDriveDisk(profile, secondaryStore);
|
configureConfigDriveDisk(profile, secondaryStore);
|
||||||
|
|
||||||
@ -363,7 +370,7 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updateConfigDrive(VirtualMachineProfile profile, String publicKey) {
|
private boolean updateConfigDrive(VirtualMachineProfile profile, String publicKey, NicProfile nic) {
|
||||||
UserVmVO vm = _userVmDao.findById(profile.getId());
|
UserVmVO vm = _userVmDao.findById(profile.getId());
|
||||||
if (vm.getType() != VirtualMachine.Type.User) {
|
if (vm.getType() != VirtualMachine.Type.User) {
|
||||||
return false;
|
return false;
|
||||||
@ -372,11 +379,10 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
|
|||||||
Nic defaultNic = _networkModel.getDefaultNic(vm.getId());
|
Nic defaultNic = _networkModel.getDefaultNic(vm.getId());
|
||||||
if (defaultNic != null) {
|
if (defaultNic != null) {
|
||||||
final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
|
final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
|
||||||
final String zoneName = _dcDao.findById(vm.getDataCenterId()).getName();
|
|
||||||
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
||||||
|
|
||||||
List<String[]> vmData = _networkModel.generateVmData(vm.getUserData(), serviceOffering, zoneName, vm.getInstanceName(), vm.getId(),
|
List<String[]> vmData = _networkModel.generateVmData(vm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getId(),
|
||||||
publicKey, (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
|
vm.getUuid(), nic.getIPv4Address(), publicKey, (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
|
||||||
profile.setVmData(vmData);
|
profile.setVmData(vmData);
|
||||||
profile.setConfigDriveLabel(VirtualMachineManager.VmConfigDriveLabel.value());
|
profile.setConfigDriveLabel(VirtualMachineManager.VmConfigDriveLabel.value());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4085,11 +4085,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
|
Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
|
||||||
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
||||||
final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
|
final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
|
||||||
final String zoneName = _dcDao.findById(vm.getDataCenterId()).getName();
|
|
||||||
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
|
||||||
|
|
||||||
List<String[]> vmData = _networkModel.generateVmData(vm.getUserData(), serviceOffering, zoneName, vm.getInstanceName(), vm.getId(),
|
List<String[]> vmData = _networkModel.generateVmData(vm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getId(),
|
||||||
(String) profile.getParameter(VirtualMachineProfile.Param.VmSshPubKey), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
|
vm.getUuid(), defaultNic.getIPv4Address(), vm.getDetail("SSH.PublicKey"), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
|
||||||
String vmName = vm.getInstanceName();
|
String vmName = vm.getInstanceName();
|
||||||
String configDriveIsoRootFolder = "/tmp";
|
String configDriveIsoRootFolder = "/tmp";
|
||||||
String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
|
String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
|
||||||
|
|||||||
@ -898,7 +898,7 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String[]> generateVmData(String userData, String serviceOffering, String zoneName, String vmName, long vmId, String publicKey, String password, Boolean isWindows) {
|
public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId, String vmName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,6 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.xerces.impl.dv.util.Base64;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
@ -64,6 +63,8 @@ import com.cloud.host.dao.HostDao;
|
|||||||
import com.cloud.network.Network;
|
import com.cloud.network.Network;
|
||||||
import com.cloud.network.NetworkModelImpl;
|
import com.cloud.network.NetworkModelImpl;
|
||||||
import com.cloud.network.Networks;
|
import com.cloud.network.Networks;
|
||||||
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
|
import com.cloud.network.dao.IPAddressVO;
|
||||||
import com.cloud.network.dao.NetworkDao;
|
import com.cloud.network.dao.NetworkDao;
|
||||||
import com.cloud.network.dao.NetworkServiceMapDao;
|
import com.cloud.network.dao.NetworkServiceMapDao;
|
||||||
import com.cloud.network.dao.NetworkVO;
|
import com.cloud.network.dao.NetworkVO;
|
||||||
@ -77,6 +78,7 @@ import com.cloud.storage.dao.GuestOSDao;
|
|||||||
import com.cloud.utils.fsm.NoTransitionException;
|
import com.cloud.utils.fsm.NoTransitionException;
|
||||||
import com.cloud.utils.fsm.StateListener;
|
import com.cloud.utils.fsm.StateListener;
|
||||||
import com.cloud.utils.fsm.StateMachine2;
|
import com.cloud.utils.fsm.StateMachine2;
|
||||||
|
import com.cloud.utils.net.Ip;
|
||||||
import com.cloud.vm.Nic;
|
import com.cloud.vm.Nic;
|
||||||
import com.cloud.vm.NicProfile;
|
import com.cloud.vm.NicProfile;
|
||||||
import com.cloud.vm.UserVmDetailVO;
|
import com.cloud.vm.UserVmDetailVO;
|
||||||
@ -99,7 +101,7 @@ public class ConfigDriveNetworkElementTest {
|
|||||||
private final String VMINSTANCENAME = "vm_name";
|
private final String VMINSTANCENAME = "vm_name";
|
||||||
private final String VMOFFERING = "custom_instance";
|
private final String VMOFFERING = "custom_instance";
|
||||||
private final long VMID = 30L;
|
private final long VMID = 30L;
|
||||||
private final String VMUSERDATA = "userdata";
|
private final String VMUSERDATA = "H4sIABCvw1oAAystTi1KSSxJ5AIAUPllwQkAAAA=";
|
||||||
private final long SOID = 31L;
|
private final long SOID = 31L;
|
||||||
private final long HOSTID = NETWORK_ID;
|
private final long HOSTID = NETWORK_ID;
|
||||||
private final String HOSTNAME = "host1";
|
private final String HOSTNAME = "host1";
|
||||||
@ -116,6 +118,7 @@ public class ConfigDriveNetworkElementTest {
|
|||||||
@Mock private UserVmDetailsDao _userVmDetailsDao;
|
@Mock private UserVmDetailsDao _userVmDetailsDao;
|
||||||
@Mock private NetworkDao _networkDao;
|
@Mock private NetworkDao _networkDao;
|
||||||
@Mock private NetworkServiceMapDao _ntwkSrvcDao;
|
@Mock private NetworkServiceMapDao _ntwkSrvcDao;
|
||||||
|
@Mock private IPAddressDao _ipAddressDao;
|
||||||
|
|
||||||
@Mock private DataCenterVO dataCenterVO;
|
@Mock private DataCenterVO dataCenterVO;
|
||||||
@Mock private DataStore dataStore;
|
@Mock private DataStore dataStore;
|
||||||
@ -130,6 +133,7 @@ public class ConfigDriveNetworkElementTest {
|
|||||||
@Mock private NicProfile nicp;
|
@Mock private NicProfile nicp;
|
||||||
@Mock private ServiceOfferingVO serviceOfferingVO;
|
@Mock private ServiceOfferingVO serviceOfferingVO;
|
||||||
@Mock private UserVmVO virtualMachine;
|
@Mock private UserVmVO virtualMachine;
|
||||||
|
@Mock private IPAddressVO publicIp;
|
||||||
|
|
||||||
@InjectMocks private final ConfigDriveNetworkElement _configDrivesNetworkElement = new ConfigDriveNetworkElement();
|
@InjectMocks private final ConfigDriveNetworkElement _configDrivesNetworkElement = new ConfigDriveNetworkElement();
|
||||||
@InjectMocks @Spy private NetworkModelImpl _networkModel = new NetworkModelImpl();
|
@InjectMocks @Spy private NetworkModelImpl _networkModel = new NetworkModelImpl();
|
||||||
@ -161,7 +165,7 @@ public class ConfigDriveNetworkElementTest {
|
|||||||
when(virtualMachine.getServiceOfferingId()).thenReturn(SOID);
|
when(virtualMachine.getServiceOfferingId()).thenReturn(SOID);
|
||||||
when(virtualMachine.getDataCenterId()).thenReturn(DATACENTERID);
|
when(virtualMachine.getDataCenterId()).thenReturn(DATACENTERID);
|
||||||
when(virtualMachine.getInstanceName()).thenReturn(VMINSTANCENAME);
|
when(virtualMachine.getInstanceName()).thenReturn(VMINSTANCENAME);
|
||||||
when(virtualMachine.getUserData()).thenReturn(Base64.encode(VMUSERDATA.getBytes()));
|
when(virtualMachine.getUserData()).thenReturn(VMUSERDATA);
|
||||||
when(deployDestination.getHost()).thenReturn(hostVO);
|
when(deployDestination.getHost()).thenReturn(hostVO);
|
||||||
when(hostVO.getId()).thenReturn(HOSTID);
|
when(hostVO.getId()).thenReturn(HOSTID);
|
||||||
when(nic.isDefaultNic()).thenReturn(true);
|
when(nic.isDefaultNic()).thenReturn(true);
|
||||||
@ -236,6 +240,71 @@ public class ConfigDriveNetworkElementTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddPasswordAndUserdata() throws InsufficientCapacityException, ResourceUnavailableException {
|
public void testAddPasswordAndUserdata() throws InsufficientCapacityException, ResourceUnavailableException {
|
||||||
|
List<String[]> actualVmData = getVmData();
|
||||||
|
|
||||||
|
assertThat(actualVmData, containsInAnyOrder(
|
||||||
|
new String[]{"userdata", "user_data", VMUSERDATA},
|
||||||
|
new String[]{"metadata", "service-offering", VMOFFERING},
|
||||||
|
new String[]{"metadata", "availability-zone", ZONENAME},
|
||||||
|
new String[]{"metadata", "local-hostname", VMINSTANCENAME},
|
||||||
|
new String[]{"metadata", "local-ipv4", "192.168.111.111"},
|
||||||
|
new String[]{"metadata", "public-hostname", null},
|
||||||
|
new String[]{"metadata", "public-ipv4", "192.168.111.111"},
|
||||||
|
new String[]{"metadata", "vm-id", String.valueOf(VMID)},
|
||||||
|
new String[]{"metadata", "instance-id", VMINSTANCENAME},
|
||||||
|
new String[]{"metadata", "public-keys", PUBLIC_KEY},
|
||||||
|
new String[]{"metadata", "cloud-identifier", String.format("CloudStack-{%s}", CLOUD_ID)},
|
||||||
|
new String[]{PASSWORD, "vm_password", PASSWORD}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddPasswordAndUserdataStaticNat() throws InsufficientCapacityException, ResourceUnavailableException {
|
||||||
|
when(_ipAddressDao.findByAssociatedVmId(VMID)).thenReturn(publicIp);
|
||||||
|
when(publicIp.getAddress()).thenReturn(new Ip("7.7.7.7"));
|
||||||
|
|
||||||
|
List<String[]> actualVmData = getVmData();
|
||||||
|
|
||||||
|
assertThat(actualVmData, containsInAnyOrder(
|
||||||
|
new String[]{"userdata", "user_data", VMUSERDATA},
|
||||||
|
new String[]{"metadata", "service-offering", VMOFFERING},
|
||||||
|
new String[]{"metadata", "availability-zone", ZONENAME},
|
||||||
|
new String[]{"metadata", "local-hostname", VMINSTANCENAME},
|
||||||
|
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", String.valueOf(VMID)},
|
||||||
|
new String[]{"metadata", "instance-id", VMINSTANCENAME},
|
||||||
|
new String[]{"metadata", "public-keys", PUBLIC_KEY},
|
||||||
|
new String[]{"metadata", "cloud-identifier", String.format("CloudStack-{%s}", CLOUD_ID)},
|
||||||
|
new String[]{PASSWORD, "vm_password", PASSWORD}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddPasswordAndUserdataUuid() throws InsufficientCapacityException, ResourceUnavailableException {
|
||||||
|
when(virtualMachine.getUuid()).thenReturn("vm-uuid");
|
||||||
|
|
||||||
|
List<String[]> actualVmData = getVmData();
|
||||||
|
|
||||||
|
assertThat(actualVmData, containsInAnyOrder(
|
||||||
|
new String[]{"userdata", "user_data", VMUSERDATA},
|
||||||
|
new String[]{"metadata", "service-offering", VMOFFERING},
|
||||||
|
new String[]{"metadata", "availability-zone", ZONENAME},
|
||||||
|
new String[]{"metadata", "local-hostname", VMINSTANCENAME},
|
||||||
|
new String[]{"metadata", "local-ipv4", "192.168.111.111"},
|
||||||
|
new String[]{"metadata", "public-hostname", null},
|
||||||
|
new String[]{"metadata", "public-ipv4", "192.168.111.111"},
|
||||||
|
new String[]{"metadata", "vm-id", "vm-uuid"},
|
||||||
|
new String[]{"metadata", "instance-id", "vm-uuid"},
|
||||||
|
new String[]{"metadata", "public-keys", PUBLIC_KEY},
|
||||||
|
new String[]{"metadata", "cloud-identifier", String.format("CloudStack-{%s}", CLOUD_ID)},
|
||||||
|
new String[]{PASSWORD, "vm_password", PASSWORD}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String[]> getVmData() throws InsufficientCapacityException, ResourceUnavailableException {
|
||||||
final Answer answer = mock(Answer.class);
|
final Answer answer = mock(Answer.class);
|
||||||
final UserVmDetailVO userVmDetailVO = mock(UserVmDetailVO.class);
|
final UserVmDetailVO userVmDetailVO = mock(UserVmDetailVO.class);
|
||||||
when(endpoint.sendMessage(any(HandleConfigDriveIsoCommand.class))).thenReturn(answer);
|
when(endpoint.sendMessage(any(HandleConfigDriveIsoCommand.class))).thenReturn(answer);
|
||||||
@ -243,6 +312,7 @@ public class ConfigDriveNetworkElementTest {
|
|||||||
when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
|
when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
|
||||||
when(virtualMachine.getState()).thenReturn(VirtualMachine.State.Stopped);
|
when(virtualMachine.getState()).thenReturn(VirtualMachine.State.Stopped);
|
||||||
when(userVmDetailVO.getValue()).thenReturn(PUBLIC_KEY);
|
when(userVmDetailVO.getValue()).thenReturn(PUBLIC_KEY);
|
||||||
|
when(nicp.getIPv4Address()).thenReturn("192.168.111.111");
|
||||||
when(_userVmDetailsDao.findDetail(anyLong(), anyString())).thenReturn(userVmDetailVO);
|
when(_userVmDetailsDao.findDetail(anyLong(), anyString())).thenReturn(userVmDetailVO);
|
||||||
Map<VirtualMachineProfile.Param, Object> parms = Maps.newHashMap();
|
Map<VirtualMachineProfile.Param, Object> parms = Maps.newHashMap();
|
||||||
parms.put(VirtualMachineProfile.Param.VmPassword, PASSWORD);
|
parms.put(VirtualMachineProfile.Param.VmPassword, PASSWORD);
|
||||||
@ -254,19 +324,6 @@ public class ConfigDriveNetworkElementTest {
|
|||||||
ArgumentCaptor<HandleConfigDriveIsoCommand> commandCaptor = ArgumentCaptor.forClass(HandleConfigDriveIsoCommand.class);
|
ArgumentCaptor<HandleConfigDriveIsoCommand> commandCaptor = ArgumentCaptor.forClass(HandleConfigDriveIsoCommand.class);
|
||||||
verify(endpoint, times(1)).sendMessage(commandCaptor.capture());
|
verify(endpoint, times(1)).sendMessage(commandCaptor.capture());
|
||||||
HandleConfigDriveIsoCommand result = commandCaptor.getValue();
|
HandleConfigDriveIsoCommand result = commandCaptor.getValue();
|
||||||
List<String[]> actualVmData = result.getVmData();
|
return result.getVmData();
|
||||||
|
|
||||||
assertThat(actualVmData, containsInAnyOrder(
|
|
||||||
new String[]{"userdata", "user_data", VMUSERDATA},
|
|
||||||
new String[]{"metadata", "service-offering", VMOFFERING},
|
|
||||||
new String[]{"metadata", "availability-zone", ZONENAME},
|
|
||||||
new String[]{"metadata", "local-hostname", VMINSTANCENAME},
|
|
||||||
new String[]{"metadata", "vm-id", String.valueOf(VMID)},
|
|
||||||
new String[]{"metadata", "instance-id", String.valueOf(VMINSTANCENAME)},
|
|
||||||
new String[]{"metadata", "public-keys", PUBLIC_KEY},
|
|
||||||
new String[]{"metadata", "cloud-identifier", String.format("CloudStack-{%s}", CLOUD_ID)},
|
|
||||||
new String[]{PASSWORD, "vm_password", PASSWORD}
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -913,7 +913,7 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String[]> generateVmData(String userData, String serviceOffering, String zoneName, String vmName, long vmId, String publicKey, String password, Boolean isWindows) {
|
public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId, String vmName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import java.io.FileReader;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -52,6 +53,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
@ -68,6 +70,7 @@ import io.netty.handler.codec.http.HttpResponseEncoder;
|
|||||||
import io.netty.handler.logging.LogLevel;
|
import io.netty.handler.logging.LogLevel;
|
||||||
import io.netty.handler.logging.LoggingHandler;
|
import io.netty.handler.logging.LoggingHandler;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
@ -155,11 +158,11 @@ import com.cloud.agent.api.to.DatadiskTO;
|
|||||||
import com.cloud.agent.api.to.NfsTO;
|
import com.cloud.agent.api.to.NfsTO;
|
||||||
import com.cloud.agent.api.to.S3TO;
|
import com.cloud.agent.api.to.S3TO;
|
||||||
import com.cloud.agent.api.to.SwiftTO;
|
import com.cloud.agent.api.to.SwiftTO;
|
||||||
|
import com.cloud.configuration.Resource;
|
||||||
import com.cloud.exception.InternalErrorException;
|
import com.cloud.exception.InternalErrorException;
|
||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.host.Host.Type;
|
import com.cloud.host.Host.Type;
|
||||||
import com.cloud.configuration.Resource;
|
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.network.NetworkModel;
|
import com.cloud.network.NetworkModel;
|
||||||
import com.cloud.resource.ServerResourceBase;
|
import com.cloud.resource.ServerResourceBase;
|
||||||
@ -190,9 +193,6 @@ import com.cloud.utils.script.Script;
|
|||||||
import com.cloud.utils.storage.S3.S3Utils;
|
import com.cloud.utils.storage.S3.S3Utils;
|
||||||
import com.cloud.vm.SecondaryStorageVm;
|
import com.cloud.vm.SecondaryStorageVm;
|
||||||
|
|
||||||
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
|
|
||||||
public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
|
public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
|
||||||
|
|
||||||
public static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
|
public static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
|
||||||
@ -492,8 +492,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||||||
if (typeFolder.exists() || typeFolder.mkdirs()) {
|
if (typeFolder.exists() || typeFolder.mkdirs()) {
|
||||||
if (StringUtils.isNotEmpty(content)) {
|
if (StringUtils.isNotEmpty(content)) {
|
||||||
File file = new File(typeFolder, fileName + ".txt");
|
File file = new File(typeFolder, fileName + ".txt");
|
||||||
try (FileWriter fw = new FileWriter(file); BufferedWriter bw = new BufferedWriter(fw)) {
|
try {
|
||||||
bw.write(content);
|
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) {
|
} catch (IOException ex) {
|
||||||
s_logger.error("Failed to create file ", ex);
|
s_logger.error("Failed to create file ", ex);
|
||||||
return new Answer(cmd, ex);
|
return new Answer(cmd, ex);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -733,8 +733,12 @@ class nuageTestCase(cloudstackTestCase):
|
|||||||
traffictype=traffic_type
|
traffictype=traffic_type
|
||||||
)
|
)
|
||||||
|
|
||||||
# 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, keypair=None):
|
||||||
def ssh_into_VM(self, vm, public_ip, reconnect=True, negative_test=False):
|
"""Creates a SSH connection to the VM
|
||||||
|
|
||||||
|
:returns: the SSH connection
|
||||||
|
:rtype: marvin.sshClient.SshClient
|
||||||
|
"""
|
||||||
if self.isSimulator:
|
if self.isSimulator:
|
||||||
self.debug("Simulator Environment: Skipping ssh into VM")
|
self.debug("Simulator Environment: Skipping ssh into VM")
|
||||||
return
|
return
|
||||||
@ -748,7 +752,8 @@ class nuageTestCase(cloudstackTestCase):
|
|||||||
ssh_client = vm.get_ssh_client(
|
ssh_client = vm.get_ssh_client(
|
||||||
ipaddress=public_ip.ipaddress.ipaddress,
|
ipaddress=public_ip.ipaddress.ipaddress,
|
||||||
reconnect=reconnect,
|
reconnect=reconnect,
|
||||||
retries=3 if negative_test else 30
|
retries=3 if negative_test else 30,
|
||||||
|
keyPairFileLocation=keypair.private_key_file if keypair else None
|
||||||
)
|
)
|
||||||
self.debug("Successful to SSH into VM with ID - %s on "
|
self.debug("Successful to SSH into VM with ID - %s on "
|
||||||
"public IP address - %s" %
|
"public IP address - %s" %
|
||||||
|
|||||||
47
test/integration/plugins/nuagevsp/nuage_lib.py
Normal file
47
test/integration/plugins/nuagevsp/nuage_lib.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
from marvin.cloudstackAPI import createSSHKeyPair, deleteSSHKeyPair
|
||||||
|
|
||||||
|
|
||||||
|
class MySSHKeyPair:
|
||||||
|
"""Manage SSH Key pairs"""
|
||||||
|
|
||||||
|
def __init__(self, items):
|
||||||
|
self.__dict__.update(items)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls, apiclient, name=None, account=None,
|
||||||
|
domainid=None, projectid=None):
|
||||||
|
"""Creates SSH keypair"""
|
||||||
|
cmd = createSSHKeyPair.createSSHKeyPairCmd()
|
||||||
|
cmd.name = name
|
||||||
|
if account is not None:
|
||||||
|
cmd.account = account
|
||||||
|
if domainid is not None:
|
||||||
|
cmd.domainid = domainid
|
||||||
|
if projectid is not None:
|
||||||
|
cmd.projectid = projectid
|
||||||
|
return MySSHKeyPair(apiclient.createSSHKeyPair(cmd).__dict__)
|
||||||
|
|
||||||
|
def delete(self, apiclient):
|
||||||
|
"""Delete SSH key pair"""
|
||||||
|
cmd = deleteSSHKeyPair.deleteSSHKeyPairCmd()
|
||||||
|
cmd.name = self.name
|
||||||
|
cmd.account = self.account
|
||||||
|
cmd.domainid = self.domainid
|
||||||
|
apiclient.deleteSSHKeyPair(cmd)
|
||||||
@ -19,8 +19,15 @@
|
|||||||
and password reset functionality with
|
and password reset functionality with
|
||||||
ConfigDrive and Nuage VSP SDN plugin
|
ConfigDrive and Nuage VSP SDN plugin
|
||||||
"""
|
"""
|
||||||
# Import Local Modules
|
import base64
|
||||||
from nuageTestCase import nuageTestCase
|
import copy
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import threading
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
from marvin.cloudstackAPI import updateTemplate, resetSSHKeyForVirtualMachine
|
from marvin.cloudstackAPI import updateTemplate, resetSSHKeyForVirtualMachine
|
||||||
from marvin.lib.base import (Account,
|
from marvin.lib.base import (Account,
|
||||||
createVlanIpRange,
|
createVlanIpRange,
|
||||||
@ -28,80 +35,24 @@ from marvin.lib.base import (Account,
|
|||||||
NetworkServiceProvider,
|
NetworkServiceProvider,
|
||||||
PublicIpRange,
|
PublicIpRange,
|
||||||
PublicIPAddress,
|
PublicIPAddress,
|
||||||
createSSHKeyPair,
|
|
||||||
deleteSSHKeyPair,
|
|
||||||
VirtualMachine)
|
VirtualMachine)
|
||||||
|
|
||||||
from marvin.lib.common import list_templates
|
from marvin.lib.common import list_templates
|
||||||
from marvin.lib.utils import random_gen
|
from marvin.lib.utils import random_gen
|
||||||
# Import System Modules
|
# Import System Modules
|
||||||
from nose.plugins.attrib import attr
|
from nose.plugins.attrib import attr
|
||||||
from datetime import datetime
|
|
||||||
import threading
|
# Import Local Modules
|
||||||
import tempfile
|
from component.test_configdrive import MySSHKeyPair, ConfigDriveUtils
|
||||||
import base64
|
from nuageTestCase import nuageTestCase, needscleanup
|
||||||
import sys
|
|
||||||
import time
|
NO_SUCH_FILE = "No such file or directory"
|
||||||
import os
|
|
||||||
import copy
|
|
||||||
import json
|
|
||||||
|
|
||||||
|
|
||||||
class MySSHKeyPair:
|
class TestNuageConfigDrive(nuageTestCase, ConfigDriveUtils):
|
||||||
"""Manage SSH Key pairs"""
|
|
||||||
|
|
||||||
def __init__(self, items):
|
|
||||||
self.__dict__.update(items)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def create(cls, apiclient, name=None, account=None,
|
|
||||||
domainid=None, projectid=None):
|
|
||||||
"""Creates SSH keypair"""
|
|
||||||
cmd = createSSHKeyPair.createSSHKeyPairCmd()
|
|
||||||
cmd.name = name
|
|
||||||
if account is not None:
|
|
||||||
cmd.account = account
|
|
||||||
if domainid is not None:
|
|
||||||
cmd.domainid = domainid
|
|
||||||
if projectid is not None:
|
|
||||||
cmd.projectid = projectid
|
|
||||||
return MySSHKeyPair(apiclient.createSSHKeyPair(cmd).__dict__)
|
|
||||||
|
|
||||||
def delete(self, apiclient):
|
|
||||||
"""Delete SSH key pair"""
|
|
||||||
cmd = deleteSSHKeyPair.deleteSSHKeyPairCmd()
|
|
||||||
cmd.name = self.name
|
|
||||||
cmd.account = self.account
|
|
||||||
cmd.domainid = self.domainid
|
|
||||||
apiclient.deleteSSHKeyPair(cmd)
|
|
||||||
|
|
||||||
|
|
||||||
class TestNuageConfigDrive(nuageTestCase):
|
|
||||||
"""Test user data and password reset functionality
|
"""Test user data and password reset functionality
|
||||||
using configDrive with Nuage VSP SDN plugin
|
using configDrive with Nuage VSP SDN plugin
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class CreateResult:
|
|
||||||
def __init__(self, success, offering=None, network=None, vpc=None):
|
|
||||||
self.success = success
|
|
||||||
self.network = network
|
|
||||||
self.offering = offering
|
|
||||||
self.vpc = vpc
|
|
||||||
|
|
||||||
class PasswordTest:
|
|
||||||
def __init__(self, password):
|
|
||||||
self.test_presence = False
|
|
||||||
self.presence = None
|
|
||||||
self.password = None
|
|
||||||
if type(password) is bool:
|
|
||||||
self.test_presence = True
|
|
||||||
self.presence = password
|
|
||||||
self.password = None
|
|
||||||
elif type(password) is unicode or type(password) is str:
|
|
||||||
self.test_presence = True
|
|
||||||
self.password = password
|
|
||||||
self.presence = True
|
|
||||||
|
|
||||||
class StartVM(threading.Thread):
|
class StartVM(threading.Thread):
|
||||||
|
|
||||||
def __init__(self, nuagetestcase, network, index):
|
def __init__(self, nuagetestcase, network, index):
|
||||||
@ -247,312 +198,11 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.updateTemplate(False)
|
self.updateTemplate(False)
|
||||||
return
|
return
|
||||||
|
|
||||||
# updateTemplate - Updates value of the guest VM template's password
|
def validate_firewall_rule(self, fw_rule):
|
||||||
# enabled setting
|
|
||||||
def updateTemplate(self, value):
|
|
||||||
self.debug("Updating value of guest VM template's password enabled "
|
|
||||||
"setting")
|
|
||||||
cmd = updateTemplate.updateTemplateCmd()
|
|
||||||
cmd.id = self.template.id
|
|
||||||
cmd.passwordenabled = value
|
|
||||||
self.api_client.updateTemplate(cmd)
|
|
||||||
list_template_response = list_templates(self.api_client,
|
|
||||||
templatefilter="all",
|
|
||||||
id=self.template.id
|
|
||||||
)
|
|
||||||
self.template = list_template_response[0]
|
|
||||||
self.debug("Updated guest VM template")
|
|
||||||
|
|
||||||
# get_userdata_url - Returns user data URL for the given VM object
|
|
||||||
def get_userdata_url(self, vm):
|
|
||||||
self.debug("Getting user data url")
|
|
||||||
nic = vm.nic[0]
|
|
||||||
gateway = str(nic.gateway)
|
|
||||||
self.debug("Gateway: " + gateway)
|
|
||||||
user_data_url = 'curl "http://' + gateway + ':80/latest/user-data"'
|
|
||||||
return user_data_url
|
|
||||||
|
|
||||||
# create_and_verify_fw - Creates and verifies (Ingress) firewall rule
|
|
||||||
# with a Static NAT rule enabled public IP
|
|
||||||
def create_and_verify_fip_and_fw(self, vm, public_ip, network):
|
|
||||||
self.debug("Creating and verifying firewall rule")
|
|
||||||
self.create_StaticNatRule_For_VM(vm, public_ip, network)
|
|
||||||
|
|
||||||
# VSD verification
|
|
||||||
self.verify_vsd_floating_ip(network, vm, public_ip.ipaddress)
|
|
||||||
|
|
||||||
fw_rule = self.create_FirewallRule(
|
|
||||||
public_ip, self.test_data["ingress_rule"])
|
|
||||||
|
|
||||||
# VSD verification
|
|
||||||
self.verify_vsd_firewall_rule(fw_rule)
|
self.verify_vsd_firewall_rule(fw_rule)
|
||||||
self.debug("Successfully created and verified firewall rule")
|
|
||||||
|
|
||||||
def getConfigDriveContent(self, ssh):
|
def validate_StaticNat_rule_For_VM(self, public_ip, network, vm):
|
||||||
"""
|
self.verify_vsd_floating_ip(network, vm, public_ip.ipaddress)
|
||||||
This method is to verify whether configdrive iso
|
|
||||||
is attached to vm or not
|
|
||||||
Returns mount path if config drive is attached else False
|
|
||||||
"""
|
|
||||||
mountdir = "/root/iso"
|
|
||||||
cmd = "blkid -t LABEL='config-2' /dev/sr? /dev/hd? /dev/sd? /dev/xvd? -o device"
|
|
||||||
tmp_cmd = [
|
|
||||||
'bash -c "if [ ! -d /root/iso ] ; then mkdir /root/iso ; fi"',
|
|
||||||
"umount /root/iso"]
|
|
||||||
for tcmd in tmp_cmd:
|
|
||||||
ssh.execute(tcmd)
|
|
||||||
configDrive = ssh.execute(cmd)
|
|
||||||
res = ssh.execute("mount {} {}".format(str(configDrive[0]), mountdir))
|
|
||||||
if str(res).lower().find("mounting read-only") > -1:
|
|
||||||
self.debug("configDrive iso is mounted at location %s" % mountdir)
|
|
||||||
return mountdir
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def verifyUserData(self, ssh, iso_path, userdata):
|
|
||||||
"""
|
|
||||||
verify Userdata
|
|
||||||
"""
|
|
||||||
userdata_path = iso_path+"/cloudstack/userdata/user_data.txt"
|
|
||||||
cmd = "cat %s" % userdata_path
|
|
||||||
res = ssh.execute(cmd)
|
|
||||||
vmuserdata = str(res[0])
|
|
||||||
self.debug("Expected userdata is %s" % userdata)
|
|
||||||
self.debug("ConfigDrive userdata acsformat is %s" % vmuserdata)
|
|
||||||
self.assertEqual(vmuserdata, userdata,
|
|
||||||
'Userdata found: %s is not equal to expected: %s'
|
|
||||||
% (vmuserdata, userdata))
|
|
||||||
|
|
||||||
def verifyOpenStackUserData(self, ssh, iso_path, userdata):
|
|
||||||
"""
|
|
||||||
verify Userdata in Openstack format
|
|
||||||
"""
|
|
||||||
userdata_path = iso_path+"/openstack/latest/user_data"
|
|
||||||
cmd = "cat %s" % userdata_path
|
|
||||||
res = ssh.execute(cmd)
|
|
||||||
vmuserdata = str(res[0])
|
|
||||||
self.debug("Expected userdata is %s" % userdata)
|
|
||||||
self.debug("ConfigDrive userdata openstackformat is %s" % vmuserdata)
|
|
||||||
self.assertEqual(vmuserdata, userdata,
|
|
||||||
'Userdata found: %s is not equal to expected: %s'
|
|
||||||
% (vmuserdata, userdata))
|
|
||||||
|
|
||||||
def verifyPassword(self, ssh, iso_path, password):
|
|
||||||
self.debug("Expected VM password is %s " % password.password)
|
|
||||||
password_file = iso_path+"/cloudstack/password/vm_password.txt"
|
|
||||||
cmd = "cat %s" % password_file
|
|
||||||
res = ssh.execute(cmd)
|
|
||||||
vmpassword = str(res[0])
|
|
||||||
self.debug("ConfigDrive password is %s " % vmpassword)
|
|
||||||
nosuchfile = "No such file or directory"
|
|
||||||
if nosuchfile in vmpassword:
|
|
||||||
self.debug("Password file is not found")
|
|
||||||
return False, False
|
|
||||||
elif (password.password is not None) \
|
|
||||||
and (password.password in vmpassword):
|
|
||||||
self.debug("Expected Password is found in configDriveIso")
|
|
||||||
return True, True
|
|
||||||
else:
|
|
||||||
self.debug("Expected password is not found in configDriveIso")
|
|
||||||
return True, False
|
|
||||||
|
|
||||||
def verifySshKey(self, ssh, iso_path, sshkey):
|
|
||||||
self.debug("Expected VM sshkey is %s " % sshkey)
|
|
||||||
publicKey_file = iso_path+"/cloudstack/metadata/public-keys.txt"
|
|
||||||
cmd = "cat %s" % publicKey_file
|
|
||||||
res = ssh.execute(cmd)
|
|
||||||
vmsshkey = str(res[0])
|
|
||||||
self.debug("ConfigDrive ssh key is %s " % vmsshkey)
|
|
||||||
|
|
||||||
def verifyMetaData(self, vm, ssh, iso_path):
|
|
||||||
|
|
||||||
metadata_dir = iso_path+"/cloudstack/metadata/"
|
|
||||||
metadata = {}
|
|
||||||
vm_files = ["availability-zone.txt",
|
|
||||||
"instance-id.txt",
|
|
||||||
"service-offering.txt",
|
|
||||||
"vm-id.txt"]
|
|
||||||
for file in vm_files:
|
|
||||||
cmd = "cat %s" % metadata_dir+file
|
|
||||||
res = ssh.execute(cmd)
|
|
||||||
metadata[file] = res
|
|
||||||
|
|
||||||
for mfile in vm_files:
|
|
||||||
if mfile not in metadata:
|
|
||||||
self.fail("{} file is not found in vm metadata".format(mfile))
|
|
||||||
self.assertEqual(
|
|
||||||
str(metadata["availability-zone.txt"][0]),
|
|
||||||
self.zone.name,
|
|
||||||
"Zone name inside metadata does not match with the zone"
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
str(metadata["instance-id.txt"][0]),
|
|
||||||
vm.instancename,
|
|
||||||
"vm name inside metadata does not match with the "
|
|
||||||
"instance name"
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
str(metadata["service-offering.txt"][0]),
|
|
||||||
vm.serviceofferingname,
|
|
||||||
"Service offering inside metadata does not match "
|
|
||||||
"with the instance offering"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
def verifyOpenStackData(self, ssh, iso_path):
|
|
||||||
|
|
||||||
openstackdata_dir = iso_path+"/openstack/latest/"
|
|
||||||
openstackdata = {}
|
|
||||||
openstackdata_files = ["user_data",
|
|
||||||
"meta_data.json",
|
|
||||||
"vendor_data.json",
|
|
||||||
"network_data.json"]
|
|
||||||
for file in openstackdata_files:
|
|
||||||
cmd = "cat %s" % openstackdata_dir+file
|
|
||||||
res = ssh.execute(cmd)
|
|
||||||
openstackdata[file] = res
|
|
||||||
if file not in openstackdata:
|
|
||||||
self.fail("{} file not found in vm openstack".format(file))
|
|
||||||
return
|
|
||||||
|
|
||||||
def generate_ssh_keys(self):
|
|
||||||
"""
|
|
||||||
This method generates ssh key pair and writes the private key
|
|
||||||
into a temp file and returns the file name
|
|
||||||
"""
|
|
||||||
self.keypair = MySSHKeyPair.create(
|
|
||||||
self.api_client,
|
|
||||||
name=random_gen() + ".pem",
|
|
||||||
account=self.account.user[0].account,
|
|
||||||
domainid=self.account.domainid)
|
|
||||||
|
|
||||||
self.cleanup.append(self.keypair)
|
|
||||||
self.debug("Created keypair with name: %s" % self.keypair.name)
|
|
||||||
self.debug("Writing the private key to local file")
|
|
||||||
keyPairFilePath = tempfile.gettempdir() + os.sep + self.keypair.name
|
|
||||||
self.tmp_files.append(keyPairFilePath)
|
|
||||||
self.debug("File path: %s" % keyPairFilePath)
|
|
||||||
with open(keyPairFilePath, "w+") as f:
|
|
||||||
f.write(self.keypair.privatekey)
|
|
||||||
os.system("chmod 400 " + keyPairFilePath)
|
|
||||||
return keyPairFilePath
|
|
||||||
|
|
||||||
def umountConfigDrive(self, ssh, iso_path):
|
|
||||||
"""umount config drive iso attached inside guest vm"""
|
|
||||||
ssh.execute("umount -d %s" % iso_path)
|
|
||||||
# Give the VM time to unlock the iso device
|
|
||||||
time.sleep(2)
|
|
||||||
# Verify umount
|
|
||||||
result = ssh.execute("ls %s" % iso_path)
|
|
||||||
self.assertTrue(len(result) == 0,
|
|
||||||
"After umount directory should be empty "
|
|
||||||
"but contains: %s" % result)
|
|
||||||
|
|
||||||
def update_provider_state(self, new_state):
|
|
||||||
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]
|
|
||||||
orig_state = configdriveprovider.state
|
|
||||||
NetworkServiceProvider.update(self.api_client,
|
|
||||||
configdriveprovider.id,
|
|
||||||
state=new_state)
|
|
||||||
self.validate_NetworkServiceProvider("ConfigDrive", state=new_state)
|
|
||||||
return orig_state
|
|
||||||
|
|
||||||
def verify_network_creation(self, offering=None,
|
|
||||||
offering_name=None,
|
|
||||||
gateway=None,
|
|
||||||
vpc=None, acl_list=None, testdata=None):
|
|
||||||
if offering is None:
|
|
||||||
self.debug("Creating Nuage VSP network offering...")
|
|
||||||
offering = self.create_NetworkOffering(
|
|
||||||
self.test_data["nuagevsp"][offering_name])
|
|
||||||
self.validate_NetworkOffering(offering, state="Enabled")
|
|
||||||
try:
|
|
||||||
network = self.create_Network(offering,
|
|
||||||
gateway=gateway,
|
|
||||||
vpc=vpc,
|
|
||||||
acl_list=acl_list,
|
|
||||||
testdata=testdata)
|
|
||||||
return self.CreateResult(True, offering=offering, network=network)
|
|
||||||
except Exception:
|
|
||||||
self.debug("Exception: %s" % sys.exc_info()[0])
|
|
||||||
return self.CreateResult(False, offering=offering)
|
|
||||||
|
|
||||||
def verify_vpc_creation(self, offering=None, offering_name=None):
|
|
||||||
|
|
||||||
if offering is None:
|
|
||||||
self.debug("Creating Nuage VSP VPC offering...")
|
|
||||||
offering = self.create_VpcOffering(
|
|
||||||
self.test_data["nuagevsp"][offering_name])
|
|
||||||
self.validate_VpcOffering(offering, state="Enabled")
|
|
||||||
try:
|
|
||||||
vpc = self.create_Vpc(offering, cidr='10.1.0.0/16')
|
|
||||||
self.validate_Vpc(vpc, state="Enabled")
|
|
||||||
return self.CreateResult(True, offering=offering, vpc=vpc)
|
|
||||||
except Exception:
|
|
||||||
return self.CreateResult(False, offering=offering)
|
|
||||||
|
|
||||||
def update_password_enable_in_template(self, new_state):
|
|
||||||
self.debug("Updating guest VM template to password %s" % new_state)
|
|
||||||
orig_state = self.template.passwordenabled
|
|
||||||
if self.template.passwordenabled is not new_state:
|
|
||||||
self.updateTemplate(new_state)
|
|
||||||
self.assertEqual(self.template.passwordenabled, new_state,
|
|
||||||
"Guest VM template is not password enabled")
|
|
||||||
return orig_state
|
|
||||||
|
|
||||||
def verify_config_drive_content(self, vm,
|
|
||||||
public_ip,
|
|
||||||
password_test,
|
|
||||||
userdata=None,
|
|
||||||
metadata=False,
|
|
||||||
sshkey=None,
|
|
||||||
ssh_client=None):
|
|
||||||
if self.isSimulator:
|
|
||||||
self.debug("Simulator Environment: Skipping Config Drive content verification")
|
|
||||||
return
|
|
||||||
|
|
||||||
self.debug("SSHing into the VM %s" % vm.name)
|
|
||||||
if ssh_client is None:
|
|
||||||
ssh = self.ssh_into_VM(vm, public_ip)
|
|
||||||
else:
|
|
||||||
ssh = ssh_client
|
|
||||||
d = {x.name: x for x in ssh.logger.handlers}
|
|
||||||
ssh.logger.handlers = list(d.values())
|
|
||||||
config_drive_path = self.getConfigDriveContent(ssh)
|
|
||||||
self.assertIsNotNone(config_drive_path,
|
|
||||||
'ConfigdriveIso is not attached to vm')
|
|
||||||
if metadata:
|
|
||||||
self.debug("Verifying metadata for vm: %s" % vm.name)
|
|
||||||
self.verifyMetaData(vm, ssh, config_drive_path)
|
|
||||||
self.debug("Verifying openstackdata for vm: %s" % vm.name)
|
|
||||||
self.verifyOpenStackData(ssh, config_drive_path)
|
|
||||||
|
|
||||||
if userdata is not None:
|
|
||||||
self.debug("Verifying userdata for vm: %s" % vm.name)
|
|
||||||
self.verifyUserData(ssh, config_drive_path, userdata)
|
|
||||||
self.verifyOpenStackUserData(ssh, config_drive_path, userdata)
|
|
||||||
if password_test.test_presence:
|
|
||||||
self.debug("Verifying password for vm: %s" % vm.name)
|
|
||||||
test_result = self.verifyPassword(ssh, config_drive_path,
|
|
||||||
password_test)
|
|
||||||
self.assertEqual(test_result[0], password_test.presence,
|
|
||||||
"Expected is that password is present: %s "
|
|
||||||
" but found is: %s"
|
|
||||||
% (test_result[0], password_test.presence))
|
|
||||||
if password_test.password is not None:
|
|
||||||
self.debug("Password for vm is %s" % password_test.password)
|
|
||||||
self.assertEqual(test_result[1], True,
|
|
||||||
"Password value test failed.")
|
|
||||||
if sshkey is not None:
|
|
||||||
self.debug("Verifying sshkey for vm: %s" % vm.name)
|
|
||||||
self.verifySshKey(ssh, config_drive_path, sshkey)
|
|
||||||
|
|
||||||
self.umountConfigDrive(ssh, config_drive_path)
|
|
||||||
return ssh
|
|
||||||
|
|
||||||
def create_guest_vm(self, networks, acl_item=None,
|
def create_guest_vm(self, networks, acl_item=None,
|
||||||
vpc=None, keypair=None):
|
vpc=None, keypair=None):
|
||||||
@ -579,92 +229,13 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.verify_vsd_firewall_rule(acl_item)
|
self.verify_vsd_firewall_rule(acl_item)
|
||||||
return vm
|
return vm
|
||||||
|
|
||||||
# nic_operation_VM - Performs NIC operations such as add, remove, and
|
# =========================================================================
|
||||||
# update default NIC in the given VM and network
|
# --- Gherkin style helper methods ---
|
||||||
def nic_operation_VM(self, vm, network, operation="add"):
|
# =========================================================================
|
||||||
self.debug("Performing %s NIC operation in VM with ID - %s and "
|
|
||||||
"network with ID - %s" % (operation, vm.id, network.id))
|
|
||||||
if operation is "add":
|
|
||||||
vm.add_nic(self.api_client, network.id)
|
|
||||||
self.debug("Added NIC in VM with ID - %s and network with ID - %s"
|
|
||||||
% (vm.id, network.id))
|
|
||||||
vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0]
|
|
||||||
for nic in vm_info.nic:
|
|
||||||
if nic.networkid == network.id:
|
|
||||||
nic_id = nic.id
|
|
||||||
if operation is "update":
|
|
||||||
vm.update_default_nic(self.api_client, nic_id)
|
|
||||||
self.debug("Updated default NIC to NIC with ID- %s in VM with ID "
|
|
||||||
"- %s and network with ID - %s" %
|
|
||||||
(nic_id, vm.id, network.id))
|
|
||||||
if operation is "remove":
|
|
||||||
vm.remove_nic(self.api_client, nic_id)
|
|
||||||
self.debug("Removed NIC with ID - %s in VM with ID - %s and "
|
|
||||||
"network with ID - %s" % (nic_id, vm.id, network.id))
|
|
||||||
|
|
||||||
def update_userdata(self, vm, expected_user_data):
|
# =========================================================================
|
||||||
updated_user_data = base64.b64encode(expected_user_data)
|
# --- TEST CASES ---
|
||||||
vm.update(self.api_client, userdata=updated_user_data)
|
# =========================================================================
|
||||||
return expected_user_data
|
|
||||||
|
|
||||||
def reset_password(self, vm):
|
|
||||||
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))
|
|
||||||
|
|
||||||
def wait_until_done(self, thread_list, name):
|
|
||||||
for aThread in thread_list:
|
|
||||||
self.debug("[Concurrency]Join %s for vm %s" % (name,
|
|
||||||
aThread.get_vm()))
|
|
||||||
aThread.join()
|
|
||||||
|
|
||||||
def resetsshkey(self, vm, keypair, account=None, domainid=None):
|
|
||||||
"""Resets SSH key"""
|
|
||||||
cmd = resetSSHKeyForVirtualMachine.resetSSHKeyForVirtualMachineCmd()
|
|
||||||
cmd.id = vm.id
|
|
||||||
cmd.keypair = keypair
|
|
||||||
cmd.account = account
|
|
||||||
cmd.domainid = domainid
|
|
||||||
return self.api_client.resetSSHKeyForVirtualMachine(cmd)
|
|
||||||
|
|
||||||
def update_sshkeypair(self, vm):
|
|
||||||
vm.stop(self.api_client)
|
|
||||||
self.resetsshkey(vm,
|
|
||||||
self.keypair.name,
|
|
||||||
account=self.account.user[0].account,
|
|
||||||
domainid=self.account.domainid)
|
|
||||||
self.debug("Sshkey reset to - %s" % self.keypair.name)
|
|
||||||
vm.start(self.api_client)
|
|
||||||
|
|
||||||
def add_subnet_verify(self, network, services):
|
|
||||||
"""verify required nic is present in the VM"""
|
|
||||||
|
|
||||||
self.debug("Going to add new ip range in shared network %s" %
|
|
||||||
network.name)
|
|
||||||
cmd = createVlanIpRange.createVlanIpRangeCmd()
|
|
||||||
cmd.networkid = network.id
|
|
||||||
cmd.gateway = services["gateway"]
|
|
||||||
cmd.netmask = services["netmask"]
|
|
||||||
cmd.startip = services["startip"]
|
|
||||||
cmd.endip = services["endip"]
|
|
||||||
cmd.forVirtualNetwork = services["forvirtualnetwork"]
|
|
||||||
addedsubnet = self.api_client.createVlanIpRange(cmd)
|
|
||||||
|
|
||||||
self.debug("verify above iprange is successfully added in shared "
|
|
||||||
"network %s or not" % network.name)
|
|
||||||
|
|
||||||
cmd1 = listVlanIpRanges.listVlanIpRangesCmd()
|
|
||||||
cmd1.networkid = network.id
|
|
||||||
cmd1.id = addedsubnet.vlan.id
|
|
||||||
|
|
||||||
allsubnets = self.api_client.listVlanIpRanges(cmd1)
|
|
||||||
self.assertEqual(
|
|
||||||
allsubnets[0].id,
|
|
||||||
addedsubnet.vlan.id,
|
|
||||||
"Check New subnet is successfully added to the shared Network"
|
|
||||||
)
|
|
||||||
return addedsubnet
|
|
||||||
|
|
||||||
@attr(tags=["advanced", "nuagevsp", "isonw"], required_hardware="true")
|
@attr(tags=["advanced", "nuagevsp", "isonw"], required_hardware="true")
|
||||||
def test_nuage_configdrive_isolated_network(self):
|
def test_nuage_configdrive_isolated_network(self):
|
||||||
@ -673,27 +244,23 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
with Nuage VSP SDN plugin
|
with Nuage VSP SDN plugin
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# 1. When ConfigDrive is disabled as provider in zone
|
# 2. Given ConfigDrive provider is enabled in zone
|
||||||
# Verify Isolated Network creation with a network offering
|
# And a network offering which has
|
||||||
# which has userdata provided by ConfigDrive fails
|
# * user data provided by ConfigDrive
|
||||||
# 2. When ConfigDrive is enabled as provider in zone
|
# * No DNS
|
||||||
# Create an Isolated Network with Nuage VSP Isolated Network
|
# When I create an Isolated Network using that network offering
|
||||||
# offering specifying ConfigDrive as serviceProvider
|
# Then the network is successfully created,
|
||||||
# for userdata,
|
# And is in the "Allocated" state.
|
||||||
# make sure no Dns is in the offering so no VR is spawned.
|
#
|
||||||
# check if it is successfully created and
|
# 3. When I deploy a VM in the created Isolated network with user data,
|
||||||
# is in the "Allocated" state.
|
# Then the Isolated network state is changed to "Implemented"
|
||||||
# 3. Deploy a VM in the created Isolated network with user data,
|
# And the VM is successfully deployed and is in the "Running" state
|
||||||
# check if the Isolated network state is changed to
|
# And there is no VR is deployed.
|
||||||
# "Implemented", and the VM is successfully deployed and
|
# 4. And the user data in the ConfigDrive device is as expected
|
||||||
# is in the "Running" state.
|
# 5. And the the vm's password in the ConfigDrive device is as expected
|
||||||
# Check that no VR is deployed.
|
#
|
||||||
# 4. SSH into the deployed VM and verify its user data in the iso
|
# 6. When I stop, reset the password, and start the VM
|
||||||
# (expected user data == actual user data).
|
# 7. Then I can login into the VM using the new password.
|
||||||
# 5. Verify that the guest VM's password in the iso.
|
|
||||||
# 6. Reset VM password, and start the VM.
|
|
||||||
# 7. Verify that the new guest VM template is password enabled by
|
|
||||||
# checking the VM's password (password != "password").
|
|
||||||
# 8. SSH into the VM for verifying its new password
|
# 8. SSH into the VM for verifying its new password
|
||||||
# after its password reset.
|
# after its password reset.
|
||||||
# 9. Verify various scenarios and check the data in configdriveIso
|
# 9. Verify various scenarios and check the data in configdriveIso
|
||||||
@ -706,6 +273,12 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
# Configure VSD sessions
|
# Configure VSD sessions
|
||||||
self.configureVSDSessions()
|
self.configureVSDSessions()
|
||||||
|
|
||||||
|
# 1. Given ConfigDrive provider is disabled in zone
|
||||||
|
# And a network offering which has
|
||||||
|
# user data provided by ConfigDrive
|
||||||
|
# Then creating an Isolated Network
|
||||||
|
# using that network offering fails
|
||||||
|
|
||||||
self.debug("+++Testing configdrive in an Isolated network fails..."
|
self.debug("+++Testing configdrive in an Isolated network fails..."
|
||||||
"as provider configdrive is still disabled...")
|
"as provider configdrive is still disabled...")
|
||||||
self.update_provider_state("Disabled")
|
self.update_provider_state("Disabled")
|
||||||
@ -717,6 +290,8 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
'Network found success = %s, expected success =%s'
|
'Network found success = %s, expected success =%s'
|
||||||
% (str(create_network.success), 'False'))
|
% (str(create_network.success), 'False'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.debug("+++Test user data & password reset functionality "
|
self.debug("+++Test user data & password reset functionality "
|
||||||
"using configdrive in an Isolated network without VR")
|
"using configdrive in an Isolated network without VR")
|
||||||
self.update_provider_state("Enabled")
|
self.update_provider_state("Enabled")
|
||||||
@ -763,7 +338,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=self.test_data[
|
userdata=self.test_data[
|
||||||
"virtual_machine_userdata"]["userdata"],
|
"virtual_machine_userdata"]["userdata"],
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
expected_user_data1 = self.update_userdata(vm1, "helloworld vm1")
|
expected_user_data1 = self.update_userdata(vm1, "helloworld vm1")
|
||||||
self.verify_config_drive_content(vm1, public_ip_1,
|
self.verify_config_drive_content(vm1, public_ip_1,
|
||||||
@ -776,7 +351,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(True),
|
self.PasswordTest(True),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
# After sshkey reset we need to have the vm password again
|
# After sshkey reset we need to have the vm password again
|
||||||
vm1.password = vm1.resetPassword(self.api_client)
|
vm1.password = vm1.resetPassword(self.api_client)
|
||||||
self.debug("Password reset to - %s" % vm1.password)
|
self.debug("Password reset to - %s" % vm1.password)
|
||||||
@ -791,7 +366,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
vm1.password = vm1.resetPassword(self.api_client)
|
vm1.password = vm1.resetPassword(self.api_client)
|
||||||
self.debug("Password reset to - %s" % vm1.password)
|
self.debug("Password reset to - %s" % vm1.password)
|
||||||
self.debug("VM - %s password - %s !" %
|
self.debug("VM - %s password - %s !" %
|
||||||
@ -802,7 +377,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.verify_config_drive_content(vm1, public_ip_1,
|
self.verify_config_drive_content(vm1, public_ip_1,
|
||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("updating non-default nic as the default nic "
|
self.debug("updating non-default nic as the default nic "
|
||||||
"of the multi-nic VM and enable staticnat...")
|
"of the multi-nic VM and enable staticnat...")
|
||||||
@ -887,7 +462,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("+++ Restarting the created Isolated network without "
|
self.debug("+++ Restarting the created Isolated network without "
|
||||||
"VR with cleanup...")
|
"VR with cleanup...")
|
||||||
@ -898,7 +473,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("+++ Upgrade offering of created Isolated network with "
|
self.debug("+++ Upgrade offering of created Isolated network with "
|
||||||
"a dns offering which spins a VR")
|
"a dns offering which spins a VR")
|
||||||
@ -996,14 +571,14 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata for VM - %s" % vm1.name)
|
self.debug("Updating userdata for VM - %s" % vm1.name)
|
||||||
expected_user_data1 = self.update_userdata(vm1, "hello afterboot")
|
expected_user_data1 = self.update_userdata(vm1, "hello afterboot")
|
||||||
self.verify_config_drive_content(vm1, public_ip_1,
|
self.verify_config_drive_content(vm1, public_ip_1,
|
||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
self.debug("Resetting password for VM - %s" % vm1.name)
|
self.debug("Resetting password for VM - %s" % vm1.name)
|
||||||
self.reset_password(vm1)
|
self.reset_password(vm1)
|
||||||
self.debug("SSHing into the VM for verifying its new password "
|
self.debug("SSHing into the VM for verifying its new password "
|
||||||
@ -1018,7 +593,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata after migrating VM - %s" % vm1.name)
|
self.debug("Updating userdata after migrating VM - %s" % vm1.name)
|
||||||
expected_user_data1 = self.update_userdata(vm1,
|
expected_user_data1 = self.update_userdata(vm1,
|
||||||
@ -1040,7 +615,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata for VM - %s" % vm1.name)
|
self.debug("Updating userdata for VM - %s" % vm1.name)
|
||||||
expected_user_data1 = self.update_userdata(vm1,
|
expected_user_data1 = self.update_userdata(vm1,
|
||||||
@ -1064,7 +639,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
self.update_provider_state("Disabled")
|
self.update_provider_state("Disabled")
|
||||||
expected_user_data1 = self.update_userdata(vm1,
|
expected_user_data1 = self.update_userdata(vm1,
|
||||||
"hello after recover")
|
"hello after recover")
|
||||||
@ -1072,7 +647,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("+++ When template is not password enabled, "
|
self.debug("+++ When template is not password enabled, "
|
||||||
"verify configdrive of VM - %s" % vm1.name)
|
"verify configdrive of VM - %s" % vm1.name)
|
||||||
@ -1094,7 +669,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
vm1.delete(self.api_client, expunge=True)
|
vm1.delete(self.api_client, expunge=True)
|
||||||
create_network1.network.delete(self.api_client)
|
create_network1.network.delete(self.api_client)
|
||||||
|
|
||||||
@ -1205,21 +780,21 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||||
self.PasswordTest(True),
|
self.PasswordTest(True),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
expected_user_data = self.update_userdata(vm, "helloworld vm1")
|
expected_user_data = self.update_userdata(vm, "helloworld vm1")
|
||||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||||
self.PasswordTest(True),
|
self.PasswordTest(True),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Resetting password for VM - %s" % vm.name)
|
self.debug("Resetting password for VM - %s" % vm.name)
|
||||||
self.reset_password(vm)
|
self.reset_password(vm)
|
||||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.generate_ssh_keys()
|
self.generate_ssh_keys()
|
||||||
self.update_sshkeypair(vm)
|
self.update_sshkeypair(vm)
|
||||||
@ -1227,7 +802,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(True),
|
self.PasswordTest(True),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
# After sshkey reset we need to have the vm password again
|
# After sshkey reset we need to have the vm password again
|
||||||
vm.password = vm.resetPassword(self.api_client)
|
vm.password = vm.resetPassword(self.api_client)
|
||||||
self.debug("Password reset to - %s" % vm.password)
|
self.debug("Password reset to - %s" % vm.password)
|
||||||
@ -1242,7 +817,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Adding a non-default nic to the VM "
|
self.debug("Adding a non-default nic to the VM "
|
||||||
"making it a multi-nic VM...")
|
"making it a multi-nic VM...")
|
||||||
@ -1252,7 +827,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
vm.password = vm.resetPassword(self.api_client)
|
vm.password = vm.resetPassword(self.api_client)
|
||||||
self.debug("Password reset to - %s" % vm.password)
|
self.debug("Password reset to - %s" % vm.password)
|
||||||
self.debug("VM - %s password - %s !" %
|
self.debug("VM - %s password - %s !" %
|
||||||
@ -1262,7 +837,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("updating non-default nic as the default nic "
|
self.debug("updating non-default nic as the default nic "
|
||||||
"of the multi-nic VM and enable staticnat...")
|
"of the multi-nic VM and enable staticnat...")
|
||||||
@ -1323,7 +898,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("+++ Restarting the created VPC Tier network without "
|
self.debug("+++ Restarting the created VPC Tier network without "
|
||||||
"cleanup...")
|
"cleanup...")
|
||||||
@ -1334,7 +909,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("+++ Restarting the created VPC Tier network with "
|
self.debug("+++ Restarting the created VPC Tier network with "
|
||||||
"cleanup...")
|
"cleanup...")
|
||||||
@ -1345,7 +920,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Testing user data & password reset functionality "
|
self.debug("Testing user data & password reset functionality "
|
||||||
" using configdrive in a VPC network with VR...")
|
" using configdrive in a VPC network with VR...")
|
||||||
@ -1464,7 +1039,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata for VM - %s" % vm.name)
|
self.debug("Updating userdata for VM - %s" % vm.name)
|
||||||
expected_user_data = self.update_userdata(vm,
|
expected_user_data = self.update_userdata(vm,
|
||||||
@ -1472,7 +1047,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
self.debug("Resetting password for VM - %s" % vm.name)
|
self.debug("Resetting password for VM - %s" % vm.name)
|
||||||
self.reset_password(vm)
|
self.reset_password(vm)
|
||||||
self.debug("SSHing into the VM for verifying its new password "
|
self.debug("SSHing into the VM for verifying its new password "
|
||||||
@ -1487,7 +1062,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata after migrating VM - %s" % vm.name)
|
self.debug("Updating userdata after migrating VM - %s" % vm.name)
|
||||||
expected_user_data = self.update_userdata(vm,
|
expected_user_data = self.update_userdata(vm,
|
||||||
@ -1495,7 +1070,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||||
self.PasswordTest(vm.password),
|
self.PasswordTest(vm.password),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
self.debug("Resetting password for VM - %s" % vm.name)
|
self.debug("Resetting password for VM - %s" % vm.name)
|
||||||
self.reset_password(vm)
|
self.reset_password(vm)
|
||||||
self.debug("SSHing into the VM for verifying its new password "
|
self.debug("SSHing into the VM for verifying its new password "
|
||||||
@ -1510,7 +1085,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata for VM - %s" % vm.name)
|
self.debug("Updating userdata for VM - %s" % vm.name)
|
||||||
expected_user_data = self.update_userdata(vm,
|
expected_user_data = self.update_userdata(vm,
|
||||||
@ -1518,7 +1093,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
self.debug("Resetting password for VM - %s" % vm.name)
|
self.debug("Resetting password for VM - %s" % vm.name)
|
||||||
self.reset_password(vm)
|
self.reset_password(vm)
|
||||||
self.debug("SSHing into the VM for verifying its new password "
|
self.debug("SSHing into the VM for verifying its new password "
|
||||||
@ -1535,13 +1110,13 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
self.update_provider_state("Disabled")
|
self.update_provider_state("Disabled")
|
||||||
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
self.verify_config_drive_content(vm, vpc_public_ip_1,
|
||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("+++ When template is not password enabled "
|
self.debug("+++ When template is not password enabled "
|
||||||
"verify configdrive of VM - %s" % vm.name)
|
"verify configdrive of VM - %s" % vm.name)
|
||||||
@ -1567,7 +1142,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
vm.delete(self.api_client, expunge=True)
|
vm.delete(self.api_client, expunge=True)
|
||||||
create_tiernetwork.network.delete(self.api_client)
|
create_tiernetwork.network.delete(self.api_client)
|
||||||
|
|
||||||
@ -1637,7 +1212,6 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
|
|
||||||
self.debug("\n+++ [Concurrency]Start update on all VM's")
|
self.debug("\n+++ [Concurrency]Start update on all VM's")
|
||||||
#
|
#
|
||||||
# 5. Concurrently update all VM's
|
# 5. Concurrently update all VM's
|
||||||
@ -1684,7 +1258,6 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
# 10. Verify the passwords
|
# 10. Verify the passwords
|
||||||
self.debug("\n+++ [Concurrency]Verify passwords on all VM's")
|
self.debug("\n+++ [Concurrency]Verify passwords on all VM's")
|
||||||
for aThread in my_reset_threads:
|
for aThread in my_reset_threads:
|
||||||
|
|
||||||
# create floating ip
|
# create floating ip
|
||||||
self.create_and_verify_fip_and_fw(aThread.get_vm(),
|
self.create_and_verify_fip_and_fw(aThread.get_vm(),
|
||||||
public_ip_1,
|
public_ip_1,
|
||||||
@ -1753,7 +1326,8 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
# Configure VSD sessions
|
# Configure VSD sessions
|
||||||
self.configureVSDSessions()
|
self.configureVSDSessions()
|
||||||
if not self.isNuageInfraUnderlay:
|
if not self.isNuageInfraUnderlay:
|
||||||
self.skipTest("Configured Nuage VSP SDN platform infrastructure "
|
self.skipTest(
|
||||||
|
"Configured Nuage VSP SDN platform infrastructure "
|
||||||
"does not support underlay networking: "
|
"does not support underlay networking: "
|
||||||
"skipping test")
|
"skipping test")
|
||||||
|
|
||||||
@ -1872,7 +1446,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
vm1.password = vm1.resetPassword(self.api_client)
|
vm1.password = vm1.resetPassword(self.api_client)
|
||||||
self.debug("Password reset to - %s" % vm1.password)
|
self.debug("Password reset to - %s" % vm1.password)
|
||||||
self.debug("VM - %s password - %s !" %
|
self.debug("VM - %s password - %s !" %
|
||||||
@ -1883,7 +1457,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.verify_config_drive_content(vm1, public_ip,
|
self.verify_config_drive_content(vm1, public_ip,
|
||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("+++ Updating non-default nic as the default nic "
|
self.debug("+++ Updating non-default nic as the default nic "
|
||||||
"of the multi-nic VM...")
|
"of the multi-nic VM...")
|
||||||
@ -1963,14 +1537,14 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata for VM - %s" % vm1.name)
|
self.debug("Updating userdata for VM - %s" % vm1.name)
|
||||||
expected_user_data1 = self.update_userdata(vm1, "hello afterboot")
|
expected_user_data1 = self.update_userdata(vm1, "hello afterboot")
|
||||||
self.verify_config_drive_content(vm1, public_ip,
|
self.verify_config_drive_content(vm1, public_ip,
|
||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
self.debug("Resetting password for VM - %s" % vm1.name)
|
self.debug("Resetting password for VM - %s" % vm1.name)
|
||||||
self.reset_password(vm1)
|
self.reset_password(vm1)
|
||||||
self.debug("SSHing into the VM for verifying its new password "
|
self.debug("SSHing into the VM for verifying its new password "
|
||||||
@ -1985,7 +1559,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata after migrating VM - %s" % vm1.name)
|
self.debug("Updating userdata after migrating VM - %s" % vm1.name)
|
||||||
expected_user_data1 = self.update_userdata(vm1,
|
expected_user_data1 = self.update_userdata(vm1,
|
||||||
@ -2007,7 +1581,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("Updating userdata for VM - %s" % vm1.name)
|
self.debug("Updating userdata for VM - %s" % vm1.name)
|
||||||
expected_user_data1 = self.update_userdata(vm1,
|
expected_user_data1 = self.update_userdata(vm1,
|
||||||
@ -2031,7 +1605,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
self.update_provider_state("Disabled")
|
self.update_provider_state("Disabled")
|
||||||
expected_user_data1 = self.update_userdata(vm1,
|
expected_user_data1 = self.update_userdata(vm1,
|
||||||
"hello after recover")
|
"hello after recover")
|
||||||
@ -2039,7 +1613,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
self.debug("+++ When template is not password enabled, "
|
self.debug("+++ When template is not password enabled, "
|
||||||
"verify configdrive of VM - %s" % vm1.name)
|
"verify configdrive of VM - %s" % vm1.name)
|
||||||
@ -2059,7 +1633,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(False),
|
self.PasswordTest(False),
|
||||||
userdata=expected_user_data1,
|
userdata=expected_user_data1,
|
||||||
metadata=True,
|
metadata=True,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
vm1.delete(self.api_client, expunge=True)
|
vm1.delete(self.api_client, expunge=True)
|
||||||
shared_network.network.delete(self.api_client)
|
shared_network.network.delete(self.api_client)
|
||||||
|
|
||||||
@ -2120,7 +1694,7 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name)
|
ssh_key=self.keypair)
|
||||||
|
|
||||||
for i in range(0, 300):
|
for i in range(0, 300):
|
||||||
self.verify_config_drive_content(
|
self.verify_config_drive_content(
|
||||||
@ -2128,8 +1702,11 @@ class TestNuageConfigDrive(nuageTestCase):
|
|||||||
self.PasswordTest(vm1.password),
|
self.PasswordTest(vm1.password),
|
||||||
metadata=True,
|
metadata=True,
|
||||||
userdata=expected_user_data,
|
userdata=expected_user_data,
|
||||||
sshkey=self.keypair.name,
|
ssh_key=self.keypair,
|
||||||
ssh_client=ssh_client)
|
ssh_client=ssh_client)
|
||||||
expected_user_data = \
|
expected_user_data = \
|
||||||
self.update_userdata(vm1,
|
self.update_userdata(vm1,
|
||||||
'This is sample data %s' % i)
|
'This is sample data %s' % i)
|
||||||
|
|
||||||
|
if __name__ == "__main__" and __package__ is None:
|
||||||
|
__package__ = "integration.plugins.nuage"
|
||||||
|
|||||||
@ -43,6 +43,12 @@ class jsonLoader(object):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def __getitem__(self, val):
|
||||||
|
if val in self.__dict__:
|
||||||
|
return self.__dict__[val]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
|
return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
|
||||||
in self.__dict__.iteritems()))
|
in self.__dict__.iteritems()))
|
||||||
|
|||||||
@ -1627,6 +1627,7 @@ var dictionary = {
|
|||||||
"label.storage.tags":"Storage Tags",
|
"label.storage.tags":"Storage Tags",
|
||||||
"label.storage.traffic":"Storage Traffic",
|
"label.storage.traffic":"Storage Traffic",
|
||||||
"label.storage.type":"Storage Type",
|
"label.storage.type":"Storage Type",
|
||||||
|
"label.storagepolicy":"Storage policy",
|
||||||
"label.subdomain.access":"Subdomain Access",
|
"label.subdomain.access":"Subdomain Access",
|
||||||
"label.submit":"Submit",
|
"label.submit":"Submit",
|
||||||
"label.submitted.by":"[Submitted by: <span id=\"submitted_by\"></span>]",
|
"label.submitted.by":"[Submitted by: <span id=\"submitted_by\"></span>]",
|
||||||
|
|||||||
@ -19886,6 +19886,7 @@
|
|||||||
$form.find('.form-item[rel=account]').hide();
|
$form.find('.form-item[rel=account]').hide();
|
||||||
$form.find('.form-item[rel=username]').hide();
|
$form.find('.form-item[rel=username]').hide();
|
||||||
$form.find('.form-item[rel=key]').hide();
|
$form.find('.form-item[rel=key]').hide();
|
||||||
|
$form.find('.form-item[rel=storagepolicy]').hide();
|
||||||
} else if ($(this).val() == "SMB") {
|
} else if ($(this).val() == "SMB") {
|
||||||
//NFS, SMB
|
//NFS, SMB
|
||||||
$form.find('.form-item[rel=zoneid]').css('display', 'inline-block');
|
$form.find('.form-item[rel=zoneid]').css('display', 'inline-block');
|
||||||
@ -19918,6 +19919,7 @@
|
|||||||
$form.find('.form-item[rel=account]').hide();
|
$form.find('.form-item[rel=account]').hide();
|
||||||
$form.find('.form-item[rel=username]').hide();
|
$form.find('.form-item[rel=username]').hide();
|
||||||
$form.find('.form-item[rel=key]').hide();
|
$form.find('.form-item[rel=key]').hide();
|
||||||
|
$form.find('.form-item[rel=storagepolicy]').hide();
|
||||||
} else if ($(this).val() == "S3") {
|
} else if ($(this).val() == "S3") {
|
||||||
//NFS, SMB
|
//NFS, SMB
|
||||||
$form.find('.form-item[rel=zoneid]').hide();
|
$form.find('.form-item[rel=zoneid]').hide();
|
||||||
@ -19952,6 +19954,7 @@
|
|||||||
$form.find('.form-item[rel=account]').hide();
|
$form.find('.form-item[rel=account]').hide();
|
||||||
$form.find('.form-item[rel=username]').hide();
|
$form.find('.form-item[rel=username]').hide();
|
||||||
$form.find('.form-item[rel=key]').hide();
|
$form.find('.form-item[rel=key]').hide();
|
||||||
|
$form.find('.form-item[rel=storagepolicy]').hide();
|
||||||
} else if ($(this).val() == "Swift") {
|
} else if ($(this).val() == "Swift") {
|
||||||
//NFS, SMB
|
//NFS, SMB
|
||||||
$form.find('.form-item[rel=zoneid]').hide();
|
$form.find('.form-item[rel=zoneid]').hide();
|
||||||
@ -19984,6 +19987,7 @@
|
|||||||
$form.find('.form-item[rel=account]').css('display', 'inline-block');
|
$form.find('.form-item[rel=account]').css('display', 'inline-block');
|
||||||
$form.find('.form-item[rel=username]').css('display', 'inline-block');
|
$form.find('.form-item[rel=username]').css('display', 'inline-block');
|
||||||
$form.find('.form-item[rel=key]').css('display', 'inline-block');
|
$form.find('.form-item[rel=key]').css('display', 'inline-block');
|
||||||
|
$form.find('.form-item[rel=storagepolicy]').css('display', 'inline-block');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -20174,13 +20178,25 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
account: {
|
account: {
|
||||||
label: 'label.account'
|
label: 'label.account',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
username: {
|
username: {
|
||||||
label: 'label.username'
|
label: 'label.username',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
key: {
|
key: {
|
||||||
label: 'label.key'
|
label: 'label.key',
|
||||||
|
validation: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
storagepolicy: {
|
||||||
|
label: 'label.storagepolicy'
|
||||||
}
|
}
|
||||||
//Swift (end)
|
//Swift (end)
|
||||||
}
|
}
|
||||||
@ -20348,6 +20364,11 @@
|
|||||||
data[ 'details[' + index.toString() + '].value'] = args.data.key;
|
data[ 'details[' + index.toString() + '].value'] = args.data.key;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
if (args.data.storagepolicy != null && args.data.storagepolicy.length > 0) {
|
||||||
|
data[ 'details[' + index.toString() + '].key'] = 'storagepolicy';
|
||||||
|
data[ 'details[' + index.toString() + '].value'] = args.data.storagepolicy;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: createURL('addImageStore'),
|
url: createURL('addImageStore'),
|
||||||
data: data,
|
data: data,
|
||||||
|
|||||||
@ -24,26 +24,29 @@ import java.net.URL;
|
|||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Formatter;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.cloud.utils.script.OutputInterpreter;
|
import com.cloud.utils.script.OutputInterpreter;
|
||||||
import com.cloud.utils.script.Script;
|
import com.cloud.utils.script.Script;
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
|
|
||||||
public class SwiftUtil {
|
public class SwiftUtil {
|
||||||
private static Logger logger = Logger.getLogger(SwiftUtil.class);
|
private static Logger logger = Logger.getLogger(SwiftUtil.class);
|
||||||
private static final long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
|
protected static final long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
|
||||||
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
|
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
|
||||||
|
private static final String CD_SRC = "cd %s;";
|
||||||
|
private static final String SWIFT_CMD= "/usr/bin/python %s -A %s -U %s:%s -K %s %s";
|
||||||
|
private static final String WITH_STORAGE_POLICY = " --storage-policy \"%s\"";
|
||||||
|
private static final String WITH_SEGMENTS = " -S "+SWIFT_MAX_SIZE;
|
||||||
|
private static final String[] OPERATIONS_WITH_STORAGE_POLICIES = {"post","upload"};
|
||||||
|
|
||||||
public interface SwiftClientCfg {
|
public interface SwiftClientCfg {
|
||||||
String getAccount();
|
String getAccount();
|
||||||
@ -53,6 +56,8 @@ public class SwiftUtil {
|
|||||||
String getKey();
|
String getKey();
|
||||||
|
|
||||||
String getEndPoint();
|
String getEndPoint();
|
||||||
|
|
||||||
|
String getStoragePolicy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getSwiftCLIPath() {
|
private static String getSwiftCLIPath() {
|
||||||
@ -65,19 +70,10 @@ public class SwiftUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean postMeta(SwiftClientCfg cfg, String container, String object, Map<String, String> metas) {
|
public static boolean postMeta(SwiftClientCfg cfg, String container, String object, Map<String, String> metas) {
|
||||||
String swiftCli = getSwiftCLIPath();
|
|
||||||
StringBuilder cms = new StringBuilder();
|
|
||||||
for (Map.Entry<String, String> entry : metas.entrySet()) {
|
|
||||||
cms.append(" -m ");
|
|
||||||
cms.append(entry.getKey());
|
|
||||||
cms.append(":");
|
|
||||||
cms.append(entry.getValue());
|
|
||||||
cms.append(" ");
|
|
||||||
}
|
|
||||||
Script command = new Script("/bin/bash", logger);
|
Script command = new Script("/bin/bash", logger);
|
||||||
command.add("-c");
|
command.add("-c");
|
||||||
command.add("/usr/bin/python " + swiftCli + " -A " + cfg.getEndPoint() + " -U " + cfg.getAccount() + ":" + cfg.getUserName() + " -K " + cfg.getKey() + " post " +
|
command.add(getSwiftObjectCmd(cfg, getSwiftCLIPath(),"post", container, object) + getMeta(metas));
|
||||||
container + " " + object + " " + cms.toString());
|
|
||||||
OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
|
OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
|
||||||
String result = command.execute(parser);
|
String result = command.execute(parser);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@ -87,21 +83,14 @@ public class SwiftUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String putObject(SwiftClientCfg cfg, File srcFile, String container, String fileName) {
|
public static String putObject(SwiftClientCfg cfg, File srcFile, String container, String fileName) {
|
||||||
String swiftCli = getSwiftCLIPath();
|
|
||||||
if (fileName == null) {
|
if (fileName == null) {
|
||||||
fileName = srcFile.getName();
|
fileName = srcFile.getName();
|
||||||
}
|
}
|
||||||
String srcDirectory = srcFile.getParent();
|
|
||||||
Script command = new Script("/bin/bash", logger);
|
Script command = new Script("/bin/bash", logger);
|
||||||
long size = srcFile.length();
|
|
||||||
command.add("-c");
|
command.add("-c");
|
||||||
if (size <= SWIFT_MAX_SIZE) {
|
command.add(String.format(CD_SRC, srcFile.getParent())+getUploadObjectCommand(cfg, getSwiftCLIPath(), container,fileName, srcFile.length()));
|
||||||
command.add("cd " + srcDirectory + ";/usr/bin/python " + swiftCli + " -A " + cfg.getEndPoint() + " -U " + cfg.getAccount() + ":" + cfg.getUserName() +
|
|
||||||
" -K " + cfg.getKey() + " upload " + container + " " + fileName);
|
|
||||||
} else {
|
|
||||||
command.add("cd " + srcDirectory + ";/usr/bin/python " + swiftCli + " -A " + cfg.getEndPoint() + " -U " + cfg.getAccount() + ":" + cfg.getUserName() +
|
|
||||||
" -K " + cfg.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + fileName);
|
|
||||||
}
|
|
||||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||||
String result = command.execute(parser);
|
String result = command.execute(parser);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@ -120,38 +109,19 @@ public class SwiftUtil {
|
|||||||
return container + File.separator + srcFile.getName();
|
return container + File.separator + srcFile.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StringBuilder buildSwiftCmd(SwiftClientCfg swift) {
|
|
||||||
String swiftCli = getSwiftCLIPath();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(" /usr/bin/python ");
|
|
||||||
sb.append(swiftCli);
|
|
||||||
sb.append(" -A ");
|
|
||||||
sb.append(swift.getEndPoint());
|
|
||||||
sb.append(" -U ");
|
|
||||||
sb.append(swift.getAccount());
|
|
||||||
sb.append(":");
|
|
||||||
sb.append(swift.getUserName());
|
|
||||||
sb.append(" -K ");
|
|
||||||
sb.append(swift.getKey());
|
|
||||||
sb.append(" ");
|
|
||||||
return sb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] list(SwiftClientCfg swift, String container, String rFilename) {
|
public static String[] list(SwiftClientCfg swift, String container, String rFilename) {
|
||||||
getSwiftCLIPath();
|
StringBuilder swiftCmdBuilder = new StringBuilder();
|
||||||
Script command = new Script("/bin/bash", logger);
|
swiftCmdBuilder.append(getSwiftContainerCmd(swift, getSwiftCLIPath(), "list", container));
|
||||||
command.add("-c");
|
|
||||||
|
|
||||||
StringBuilder swiftCmdBuilder = buildSwiftCmd(swift);
|
|
||||||
swiftCmdBuilder.append(" list ");
|
|
||||||
swiftCmdBuilder.append(container);
|
|
||||||
|
|
||||||
if (rFilename != null) {
|
if (rFilename != null) {
|
||||||
swiftCmdBuilder.append(" -p ");
|
swiftCmdBuilder.append(" -p ");
|
||||||
swiftCmdBuilder.append(rFilename);
|
swiftCmdBuilder.append(rFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Script command = new Script("/bin/bash", logger);
|
||||||
|
command.add("-c");
|
||||||
command.add(swiftCmdBuilder.toString());
|
command.add(swiftCmdBuilder.toString());
|
||||||
|
|
||||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||||
String result = command.execute(parser);
|
String result = command.execute(parser);
|
||||||
if (result == null && parser.getLines() != null && !parser.getLines().equalsIgnoreCase("")) {
|
if (result == null && parser.getLines() != null && !parser.getLines().equalsIgnoreCase("")) {
|
||||||
@ -178,11 +148,11 @@ public class SwiftUtil {
|
|||||||
} else {
|
} else {
|
||||||
destFilePath = destDirectory.getAbsolutePath();
|
destFilePath = destDirectory.getAbsolutePath();
|
||||||
}
|
}
|
||||||
String swiftCli = getSwiftCLIPath();
|
|
||||||
Script command = new Script("/bin/bash", logger);
|
Script command = new Script("/bin/bash", logger);
|
||||||
command.add("-c");
|
command.add("-c");
|
||||||
command.add("/usr/bin/python " + swiftCli + " -A " + cfg.getEndPoint() + " -U " + cfg.getAccount() + ":" + cfg.getUserName() + " -K " + cfg.getKey() +
|
command.add(getSwiftObjectCmd(cfg, getSwiftCLIPath(), "download", container, srcPath)+" -o " + destFilePath);
|
||||||
" download " + container + " " + srcPath + " -o " + destFilePath);
|
|
||||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||||
String result = command.execute(parser);
|
String result = command.execute(parser);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@ -203,27 +173,6 @@ public class SwiftUtil {
|
|||||||
return new File(destFilePath);
|
return new File(destFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getContainerName(String type, Long id) {
|
|
||||||
if (type.startsWith("T")) {
|
|
||||||
return "T-" + id;
|
|
||||||
} else if (type.startsWith("S")) {
|
|
||||||
return "S-" + id;
|
|
||||||
} else if (type.startsWith("V")) {
|
|
||||||
return "V-" + id;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] splitSwiftPath(String path) {
|
|
||||||
int index = path.indexOf(File.separator);
|
|
||||||
if (index == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String[] paths = new String[2];
|
|
||||||
paths[0] = path.substring(0, index);
|
|
||||||
paths[1] = path.substring(index + 1);
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean deleteObject(SwiftClientCfg cfg, String path) {
|
public static boolean deleteObject(SwiftClientCfg cfg, String path) {
|
||||||
Script command = new Script("/bin/bash", logger);
|
Script command = new Script("/bin/bash", logger);
|
||||||
@ -236,13 +185,8 @@ public class SwiftUtil {
|
|||||||
String container = paths[0];
|
String container = paths[0];
|
||||||
String objectName = paths[1];
|
String objectName = paths[1];
|
||||||
|
|
||||||
StringBuilder swiftCmdBuilder = buildSwiftCmd(cfg);
|
command.add(getSwiftObjectCmd(cfg, getSwiftCLIPath(), "delete", container, objectName));
|
||||||
swiftCmdBuilder.append(" delete ");
|
|
||||||
swiftCmdBuilder.append(container);
|
|
||||||
swiftCmdBuilder.append(" ");
|
|
||||||
swiftCmdBuilder.append(objectName);
|
|
||||||
|
|
||||||
command.add(swiftCmdBuilder.toString());
|
|
||||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||||
command.execute(parser);
|
command.execute(parser);
|
||||||
return true;
|
return true;
|
||||||
@ -284,7 +228,7 @@ public class SwiftUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String calculateRFC2104HMAC(String data, String key)
|
static String calculateRFC2104HMAC(String data, String key)
|
||||||
throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
|
throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
|
||||||
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
|
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
|
||||||
@ -294,12 +238,75 @@ public class SwiftUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toHexString(byte[] bytes) {
|
static String toHexString(byte[] bytes) {
|
||||||
|
return Hex.encodeHexString(bytes);
|
||||||
Formatter formatter = new Formatter();
|
|
||||||
for (byte b : bytes) {
|
|
||||||
formatter.format("%02x", b);
|
|
||||||
}
|
}
|
||||||
return formatter.toString();
|
|
||||||
|
/////////////// SWIFT CMD STRING HELPERS ///////////////
|
||||||
|
protected static String getSwiftCmd(SwiftClientCfg cfg, String swiftCli, String operation){
|
||||||
|
return String.format(SWIFT_CMD, swiftCli,cfg.getEndPoint(),cfg.getAccount(),cfg.getUserName(),cfg.getKey(),operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String getSwiftObjectCmd(SwiftClientCfg cfg, String swiftCliPath, String operation,String container, String objectName) {
|
||||||
|
String cmd = getSwiftCmd(cfg,swiftCliPath, operation) +" "+ container+" "+objectName;
|
||||||
|
if(StringUtils.isNotBlank(cfg.getStoragePolicy()) && supportsStoragePolicies(operation)){
|
||||||
|
return cmd + String.format(WITH_STORAGE_POLICY, cfg.getStoragePolicy());
|
||||||
|
}
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean supportsStoragePolicies(String operation) {
|
||||||
|
for(String supportedOp: OPERATIONS_WITH_STORAGE_POLICIES){
|
||||||
|
if(supportedOp.equals(operation)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String getSwiftContainerCmd(SwiftClientCfg cfg, String swiftCliPath, String operation, String container) {
|
||||||
|
return getSwiftCmd(cfg,swiftCliPath, operation) +" "+ container;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String getUploadObjectCommand(SwiftClientCfg cfg, String swiftCliPath, String container, String objectName, long size) {
|
||||||
|
String cmd = getSwiftObjectCmd(cfg, swiftCliPath, "upload", container, objectName);
|
||||||
|
if(size > SWIFT_MAX_SIZE){
|
||||||
|
return cmd + WITH_SEGMENTS;
|
||||||
|
}
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getContainerName(String type, Long id) {
|
||||||
|
if (type.startsWith("T")) {
|
||||||
|
return "T-" + id;
|
||||||
|
} else if (type.startsWith("S")) {
|
||||||
|
return "S-" + id;
|
||||||
|
} else if (type.startsWith("V")) {
|
||||||
|
return "V-" + id;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] splitSwiftPath(String path) {
|
||||||
|
int index = path.indexOf(File.separator);
|
||||||
|
if (index == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] paths = new String[2];
|
||||||
|
paths[0] = path.substring(0, index);
|
||||||
|
paths[1] = path.substring(index + 1);
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getMeta(Map<String, String> metas) {
|
||||||
|
StringBuilder cms = new StringBuilder();
|
||||||
|
for (Map.Entry<String, String> entry : metas.entrySet()) {
|
||||||
|
cms.append(" -m ");
|
||||||
|
cms.append(entry.getKey());
|
||||||
|
cms.append(":");
|
||||||
|
cms.append(entry.getValue());
|
||||||
|
cms.append(" ");
|
||||||
|
}
|
||||||
|
return cms.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,9 +19,15 @@
|
|||||||
|
|
||||||
package com.cloud.utils;
|
package com.cloud.utils;
|
||||||
|
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
import org.junit.Test;
|
import static org.mockito.BDDMockito.mock;
|
||||||
import org.mockito.Mockito;
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -29,10 +35,10 @@ import java.security.InvalidKeyException;
|
|||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.mockito.Mockito;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.mockito.Mockito.when;
|
import com.cloud.utils.SwiftUtil.SwiftClientCfg;
|
||||||
|
|
||||||
public class SwiftUtilTest {
|
public class SwiftUtilTest {
|
||||||
|
|
||||||
@ -90,4 +96,134 @@ public class SwiftUtilTest {
|
|||||||
|
|
||||||
assertEquals(expected, output);
|
assertEquals(expected, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSwiftCmd() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn(null);
|
||||||
|
|
||||||
|
String cmd = SwiftUtil.getSwiftCmd(cfg, "swift", "stat");
|
||||||
|
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword stat";
|
||||||
|
assertThat(cmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSwiftObjectCmd() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn(null);
|
||||||
|
|
||||||
|
String objectCmd = SwiftUtil.getSwiftObjectCmd(cfg, "swift", "delete", "T-123", "template.vhd");
|
||||||
|
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword delete T-123 template.vhd";
|
||||||
|
assertThat(objectCmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSwiftContainerCmd() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn(null);
|
||||||
|
|
||||||
|
String containerCmd = SwiftUtil.getSwiftContainerCmd(cfg, "swift", "list", "T-123");
|
||||||
|
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword list T-123";
|
||||||
|
assertThat(containerCmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUploadCmd() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn(null);
|
||||||
|
|
||||||
|
String uploadCmd = SwiftUtil.getUploadObjectCommand(cfg, "swift", "T-1", "template.vhd", 1024);
|
||||||
|
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword upload T-1 template.vhd";
|
||||||
|
assertThat(uploadCmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUploadCmdWithSegmentsBecauseOfSize() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn(null);
|
||||||
|
|
||||||
|
String uploadCmd = SwiftUtil.getUploadObjectCommand(cfg, "swift", "T-1", "template.vhd", 5368709121L);
|
||||||
|
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword upload T-1 template.vhd -S 5368709120";
|
||||||
|
assertThat(uploadCmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUploadCmdWithStoragePolicy() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn("policy1");
|
||||||
|
|
||||||
|
String uploadCmd = SwiftUtil.getUploadObjectCommand(cfg, "swift", "T-1", "template.vhd", 1024L);
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword upload T-1 template.vhd --storage-policy \"policy1\"";
|
||||||
|
assertThat(uploadCmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUploadCmdWithSegmentsAndStoragePolicy() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn("policy1");
|
||||||
|
String uploadCmd = SwiftUtil.getUploadObjectCommand(cfg, "swift", "T-1", "template.vhd", 5368709121L);
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword upload T-1 template.vhd --storage-policy \"policy1\" -S 5368709120";
|
||||||
|
assertThat(uploadCmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListContainerCmdWithStoragePolicyButNotSupportedByOperation() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn("policy1");
|
||||||
|
|
||||||
|
String uploadCmd = SwiftUtil.getSwiftContainerCmd(cfg, "swift", "list", "T-1");
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword list T-1";
|
||||||
|
assertThat(uploadCmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListContainerCmdWithoutStoragePolicy() {
|
||||||
|
SwiftClientCfg cfg = mock(SwiftClientCfg.class);
|
||||||
|
given(cfg.getEndPoint()).willReturn("swift.endpoint");
|
||||||
|
given(cfg.getAccount()).willReturn("cs");
|
||||||
|
given(cfg.getUserName()).willReturn("sec-storage");
|
||||||
|
given(cfg.getKey()).willReturn("mypassword");
|
||||||
|
given(cfg.getStoragePolicy()).willReturn(null);
|
||||||
|
|
||||||
|
String uploadCmd = SwiftUtil.getSwiftContainerCmd(cfg, "swift", "list", "T-1");
|
||||||
|
String expected = "/usr/bin/python swift -A swift.endpoint -U cs:sec-storage -K mypassword list T-1";
|
||||||
|
assertThat(uploadCmd, is(equalTo(expected)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user