Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ public class ApiConstants {
public static final String FILESYSTEM = "filesystem";
public static final String FIRSTNAME = "firstname";
public static final String FORCED = "forced";
public static final String ALLOW_DUPLICATE_MAC_ADDRESSES = "allowduplicatemacaddresses";
public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage";
public static final String FORCE_CONVERT_TO_POOL = "forceconverttopool";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,15 @@ public class ImportUnmanagedInstanceCmd extends BaseAsyncCmd {

@Parameter(name = ApiConstants.FORCED,
type = CommandType.BOOLEAN,
description = "Instance is imported despite some of its NIC's MAC addresses are already present, in case the MAC address exists then a new MAC address is generated")
description = "Instance is imported even if some NIC MAC addresses already exist. If a MAC address exists, a new MAC address is generated")
private Boolean forced;

@Parameter(name = ApiConstants.ALLOW_DUPLICATE_MAC_ADDRESSES,
type = CommandType.BOOLEAN,
since = "4.23.0",
description = "Preserve imported NIC MAC addresses even when they already exist on the target network. Intended for migration cutover workflows where the source and imported VMs are not active on the same L2 network at the same time")
private Boolean allowDuplicateMacAddresses;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -278,6 +284,10 @@ public boolean isForced() {
return BooleanUtils.isTrue(forced);
}

public boolean isAllowDuplicateMacAddresses() {
return BooleanUtils.isTrue(allowDuplicateMacAddresses);
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ void implementNetworkElementsAndResources(DeployDestination dest, ReservationCon
*/
void cleanupNicDhcpDnsEntry(Network network, VirtualMachineProfile vmProfile, NicProfile nicProfile);

Pair<NicProfile, Integer> importNic(final String macAddress, int deviceId, final Network network, final Boolean isDefaultNic, final VirtualMachine vm, final Network.IpAddresses ipAddresses, final DataCenter datacenter, boolean forced) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
Pair<NicProfile, Integer> importNic(final String macAddress, int deviceId, final Network network, final Boolean isDefaultNic, final VirtualMachine vm, final Network.IpAddresses ipAddresses, final DataCenter datacenter, boolean forced, boolean allowDuplicateMacAddress) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;

void unmanageNics(VirtualMachineProfile vm);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4770,7 +4770,7 @@ public NicVO savePlaceholderNic(final Network network, final String ip4Address,

@DB
@Override
public Pair<NicProfile, Integer> importNic(final String macAddress, int deviceId, final Network network, final Boolean isDefaultNic, final VirtualMachine vm, final Network.IpAddresses ipAddresses, final DataCenter dataCenter, final boolean forced)
public Pair<NicProfile, Integer> importNic(final String macAddress, int deviceId, final Network network, final Boolean isDefaultNic, final VirtualMachine vm, final Network.IpAddresses ipAddresses, final DataCenter dataCenter, final boolean forced, final boolean allowDuplicateMacAddress)
throws ConcurrentOperationException, InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
logger.debug("Allocating NIC for Instance {} in Network {} during import", vm, network);
String selectedIp = null;
Expand All @@ -4796,7 +4796,7 @@ public NicVO doInTransaction(TransactionStatus status) {
throw new CloudRuntimeException("Invalid mac address: " + macAddressToPersist);
}
NicVO existingNic = _nicDao.findByNetworkIdAndMacAddress(network.getId(), macAddressToPersist);
if (existingNic != null) {
if (existingNic != null && !allowDuplicateMacAddress) {
macAddressToPersist = generateNewMacAddressIfForced(network, macAddressToPersist, forced);
}
NicVO vo = new NicVO(network.getGuruName(), vm.getId(), network.getId(), vm.getType());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ public void testImportNicAcquireGuestIPFailed() throws Exception {
Mockito.when(testOrchestrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(Arrays.asList(Service.Dns, Service.Dhcp));
String macAddress = "02:01:01:82:00:01";
int deviceId = 0;
testOrchestrator.importNic(macAddress, deviceId, network, true, vm, ipAddresses, dataCenter, false);
testOrchestrator.importNic(macAddress, deviceId, network, true, vm, ipAddresses, dataCenter, false, false);
}

@Test(expected = InsufficientVirtualNetworkCapacityException.class)
Expand All @@ -932,7 +932,7 @@ public void testImportNicAutoAcquireGuestIPFailed() throws Exception {
Mockito.when(testOrchestrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(Arrays.asList(Service.Dns, Service.Dhcp));
String macAddress = "02:01:01:82:00:01";
int deviceId = 0;
testOrchestrator.importNic(macAddress, deviceId, network, true, vm, ipAddresses, dataCenter, false);
testOrchestrator.importNic(macAddress, deviceId, network, true, vm, ipAddresses, dataCenter, false, false);
}

@Test
Expand All @@ -959,7 +959,7 @@ public void testImportNicNoIP4Address() throws Exception {
Mockito.when(testOrchestrator._networkModel.getNetworkTag(hypervisorType, network)).thenReturn("testtag");
try (MockedStatic<Transaction> transactionMocked = Mockito.mockStatic(Transaction.class)) {
transactionMocked.when(() -> Transaction.execute(any(TransactionCallback.class))).thenReturn(nic);
Pair<NicProfile, Integer> nicProfileIntegerPair = testOrchestrator.importNic(macAddress, deviceId, network, true, vm, ipAddresses, dataCenter, false);
Pair<NicProfile, Integer> nicProfileIntegerPair = testOrchestrator.importNic(macAddress, deviceId, network, true, vm, ipAddresses, dataCenter, false, false);
verify(testOrchestrator._networkModel, times(1)).getNetworkRate(networkId, vmId);
verify(testOrchestrator._networkModel, times(1)).isSecurityGroupSupportedInNetwork(network);
verify(testOrchestrator._networkModel, times(1)).getNetworkTag(Hypervisor.HypervisorType.KVM, network);
Expand Down Expand Up @@ -997,7 +997,7 @@ public void testImportNicWithIP4Address() throws Exception {
Mockito.when(testOrchestrator._networkModel.getNetworkTag(hypervisorType, network)).thenReturn("testtag");
try (MockedStatic<Transaction> transactionMocked = Mockito.mockStatic(Transaction.class)) {
transactionMocked.when(() -> Transaction.execute(any(TransactionCallback.class))).thenReturn(nic);
Pair<NicProfile, Integer> nicProfileIntegerPair = testOrchestrator.importNic(macAddress, deviceId, network, true, vm, ipAddresses, dataCenter, false);
Pair<NicProfile, Integer> nicProfileIntegerPair = testOrchestrator.importNic(macAddress, deviceId, network, true, vm, ipAddresses, dataCenter, false, false);
verify(testOrchestrator, times(1)).getSelectedIpForNicImport(network, dataCenter, ipAddresses);
verify(testOrchestrator._networkModel, times(1)).getNetworkRate(networkId, vmId);
verify(testOrchestrator._networkModel, times(1)).isSecurityGroupSupportedInNetwork(network);
Expand Down
Loading
Loading