mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
vmware, ui: update portgroup on network update (#5470)
Enhanced update network form in the UI. On network offering change for an isolated network, - VMware portgroup should be updated accordingly. - VMs on the network should be placed on the correct VMware portgroup based on the network rate, https://docs.cloudstack.apache.org/en/latest/adminguide/service_offerings.html#network-throttling. Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
965a47fdfd
commit
4a42e7ef9e
@ -221,7 +221,7 @@ public interface VirtualMachineManager extends Manager {
|
||||
*/
|
||||
VirtualMachineTO toVmTO(VirtualMachineProfile profile);
|
||||
|
||||
boolean replugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException,
|
||||
boolean replugNic(Network network, NicTO nic, VirtualMachineTO vm, Host dest) throws ConcurrentOperationException,
|
||||
ResourceUnavailableException, InsufficientCapacityException;
|
||||
|
||||
VirtualMachine reConfigureVm(String vmUuid, ServiceOffering oldServiceOffering, ServiceOffering newServiceOffering, Map<String, String> customParameters, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException,
|
||||
|
||||
@ -43,7 +43,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||
@ -129,6 +128,7 @@ import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.agent.manager.allocator.HostAllocator;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.api.query.dao.DomainRouterJoinDao;
|
||||
import com.cloud.api.query.dao.UserVmJoinDao;
|
||||
import com.cloud.api.query.vo.DomainRouterJoinVO;
|
||||
@ -4047,16 +4047,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
//3) Convert nicProfile to NicTO
|
||||
final NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType());
|
||||
|
||||
if (network != null) {
|
||||
final Map<NetworkOffering.Detail, String> details = networkOfferingDetailsDao.getNtwkOffDetails(network.getNetworkOfferingId());
|
||||
if (details != null) {
|
||||
details.putIfAbsent(NetworkOffering.Detail.PromiscuousMode, NetworkOrchestrationService.PromiscuousMode.value().toString());
|
||||
details.putIfAbsent(NetworkOffering.Detail.MacAddressChanges, NetworkOrchestrationService.MacAddressChanges.value().toString());
|
||||
details.putIfAbsent(NetworkOffering.Detail.ForgedTransmits, NetworkOrchestrationService.ForgedTransmits.value().toString());
|
||||
}
|
||||
nicTO.setDetails(details);
|
||||
}
|
||||
|
||||
//4) plug the nic to the vm
|
||||
s_logger.debug("Plugging nic for vm " + vm + " in network " + network);
|
||||
|
||||
@ -4566,7 +4556,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
|
||||
public boolean replugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final Host host) throws ConcurrentOperationException,
|
||||
ResourceUnavailableException, InsufficientCapacityException {
|
||||
boolean result = true;
|
||||
|
||||
@ -4576,14 +4566,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
final ReplugNicCommand replugNicCmd = new ReplugNicCommand(nic, vm.getName(), vm.getType(), vm.getDetails());
|
||||
final Commands cmds = new Commands(Command.OnError.Stop);
|
||||
cmds.addCommand("replugnic", replugNicCmd);
|
||||
_agentMgr.send(dest.getHost().getId(), cmds);
|
||||
_agentMgr.send(host.getId(), cmds);
|
||||
final ReplugNicAnswer replugNicAnswer = cmds.getAnswer(ReplugNicAnswer.class);
|
||||
if (replugNicAnswer == null || !replugNicAnswer.getResult()) {
|
||||
s_logger.warn("Unable to replug nic for vm " + vm.getName());
|
||||
result = false;
|
||||
}
|
||||
} catch (final OperationTimedoutException e) {
|
||||
throw new AgentUnavailableException("Unable to plug nic for router " + vm.getName() + " in network " + network, dest.getHost().getId(), e);
|
||||
throw new AgentUnavailableException("Unable to plug nic for router " + vm.getName() + " in network " + network, host.getId(), e);
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Unable to apply ReplugNic, vm " + router + " is not in the right state " + router.getState());
|
||||
|
||||
@ -25,8 +25,11 @@ import javax.inject.Inject;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
@ -36,6 +39,7 @@ import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.gpu.GPU;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkDetailVO;
|
||||
@ -61,9 +65,6 @@ import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru, Configurable {
|
||||
public static final Logger s_logger = Logger.getLogger(HypervisorGuruBase.class);
|
||||
@ -97,6 +98,24 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
||||
public static ConfigKey<Boolean> VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.min.cpu.speed.equals.cpu.speed.divided.by.cpu.overprovisioning.factor", "true",
|
||||
"If we set this to 'true', a minimum CPU speed (cpu speed/ cpu.overprovisioning.factor) will be set on the VM, independent of using a scalable service offering or not.", true, ConfigKey.Scope.Cluster);
|
||||
|
||||
private Map<NetworkOffering.Detail, String> getNicDetails(Network network) {
|
||||
if (network == null) {
|
||||
s_logger.debug("Unable to get NIC details as the network is null");
|
||||
return null;
|
||||
}
|
||||
Map<NetworkOffering.Detail, String> details = networkOfferingDetailsDao.getNtwkOffDetails(network.getNetworkOfferingId());
|
||||
if (details != null) {
|
||||
details.putIfAbsent(NetworkOffering.Detail.PromiscuousMode, NetworkOrchestrationService.PromiscuousMode.value().toString());
|
||||
details.putIfAbsent(NetworkOffering.Detail.MacAddressChanges, NetworkOrchestrationService.MacAddressChanges.value().toString());
|
||||
details.putIfAbsent(NetworkOffering.Detail.ForgedTransmits, NetworkOrchestrationService.ForgedTransmits.value().toString());
|
||||
}
|
||||
NetworkDetailVO pvlantypeDetail = networkDetailsDao.findDetail(network.getId(), ApiConstants.ISOLATED_PVLAN_TYPE);
|
||||
if (pvlantypeDetail != null) {
|
||||
details.putIfAbsent(NetworkOffering.Detail.pvlanType, pvlantypeDetail.getValue());
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NicTO toNicTO(NicProfile profile) {
|
||||
NicTO to = new NicTO();
|
||||
@ -140,6 +159,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
||||
//FixMe: uuid and secondary IPs can be made part of nic profile
|
||||
to.setUuid(UUID.randomUUID().toString());
|
||||
}
|
||||
to.setDetails(getNicDetails(network));
|
||||
|
||||
//check whether the this nic has secondary ip addresses set
|
||||
//set nic secondary ip address in NicTO which are used for security group
|
||||
@ -217,20 +237,6 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
||||
nicProfile.setBroadcastType(BroadcastDomainType.Native);
|
||||
}
|
||||
NicTO nicTo = toNicTO(nicProfile);
|
||||
final NetworkVO network = _networkDao.findByUuid(nicTo.getNetworkUuid());
|
||||
if (network != null) {
|
||||
final Map<NetworkOffering.Detail, String> details = networkOfferingDetailsDao.getNtwkOffDetails(network.getNetworkOfferingId());
|
||||
if (details != null) {
|
||||
details.putIfAbsent(NetworkOffering.Detail.PromiscuousMode, NetworkOrchestrationService.PromiscuousMode.value().toString());
|
||||
details.putIfAbsent(NetworkOffering.Detail.MacAddressChanges, NetworkOrchestrationService.MacAddressChanges.value().toString());
|
||||
details.putIfAbsent(NetworkOffering.Detail.ForgedTransmits, NetworkOrchestrationService.ForgedTransmits.value().toString());
|
||||
}
|
||||
NetworkDetailVO pvlantypeDetail = networkDetailsDao.findDetail(network.getId(), ApiConstants.ISOLATED_PVLAN_TYPE);
|
||||
if (pvlantypeDetail != null) {
|
||||
details.putIfAbsent(NetworkOffering.Detail.pvlanType, pvlantypeDetail.getValue());
|
||||
}
|
||||
nicTo.setDetails(details);
|
||||
}
|
||||
nics[i++] = nicTo;
|
||||
}
|
||||
|
||||
|
||||
@ -556,7 +556,7 @@ public class NetworkMigrationManagerImpl implements NetworkMigrationManager {
|
||||
|
||||
try {
|
||||
nicProfile = _networkMgr.prepareNic(vmProfile, dest, context, nicProfile.getId(), networkInNewPhysicalNet);
|
||||
_itMgr.replugNic(networkInNewPhysicalNet, _itMgr.toNicTO(nicProfile, host.getHypervisorType()), _itMgr.toVmTO(vmProfile), context, dest);
|
||||
_itMgr.replugNic(networkInNewPhysicalNet, _itMgr.toNicTO(nicProfile, host.getHypervisorType()), _itMgr.toVmTO(vmProfile), dest.getHost());
|
||||
} catch (ResourceUnavailableException | InsufficientCapacityException e) {
|
||||
throw new CloudRuntimeException("Migration of Nic failed", e);
|
||||
}
|
||||
|
||||
@ -34,17 +34,15 @@ import java.util.TreeSet;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.StringUtils;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.configuration.Config;
|
||||
@ -116,6 +114,7 @@ import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.DB;
|
||||
@ -1014,24 +1013,34 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
||||
// or on NULL from network.throttling.rate
|
||||
// For others: Use network rate from their network offering,
|
||||
// or on NULL from network.throttling.rate setting at zone > global level
|
||||
// http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/service_offerings.html#network-throttling
|
||||
// http://docs.cloudstack.apache.org/en/latest/adminguide/service_offerings.html#network-throttling
|
||||
if (vm != null) {
|
||||
if (vm.getType() == Type.User) {
|
||||
final Nic nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
|
||||
if (nic != null && nic.isDefaultNic()) {
|
||||
return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), network.getDataCenterId());
|
||||
}
|
||||
}
|
||||
if (vm.getType() == Type.DomainRouter && (network.getTrafficType() == TrafficType.Public || network.getTrafficType() == TrafficType.Guest)) {
|
||||
for (final Nic nic: _nicDao.listByVmId(vmId)) {
|
||||
final NetworkVO nw = _networksDao.findById(nic.getNetworkId());
|
||||
if (nw.getTrafficType() == TrafficType.Guest) {
|
||||
return _configMgr.getNetworkOfferingNetworkRate(nw.getNetworkOfferingId(), network.getDataCenterId());
|
||||
switch (vm.getType()) {
|
||||
case User:
|
||||
final Nic nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
|
||||
if (nic != null && nic.isDefaultNic()) {
|
||||
return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), network.getDataCenterId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm) {
|
||||
return -1;
|
||||
break;
|
||||
case DomainRouter:
|
||||
if (TrafficType.Guest.equals(network.getTrafficType())) {
|
||||
final Nic routerNic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
|
||||
if (routerNic != null) {
|
||||
return _configMgr.getNetworkOfferingNetworkRate(network.getNetworkOfferingId(), network.getDataCenterId());
|
||||
}
|
||||
} else if (TrafficType.Public.equals(network.getTrafficType())) {
|
||||
List<NicVO> routerNics = _nicDao.listByVmId(vmId);
|
||||
for (final Nic routerNic : routerNics) {
|
||||
final NetworkVO nw = _networksDao.findById(routerNic.getNetworkId());
|
||||
if (TrafficType.Guest.equals(nw.getTrafficType())) {
|
||||
return _configMgr.getNetworkOfferingNetworkRate(nw.getNetworkOfferingId(), network.getDataCenterId());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ConsoleProxy:
|
||||
case SecondaryStorageVm:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (ntwkOff != null) {
|
||||
|
||||
@ -16,6 +16,9 @@
|
||||
// under the License.
|
||||
package com.cloud.network;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang.StringUtils.isNotBlank;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
@ -38,7 +41,6 @@ import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.network.Network.PVlanType;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
@ -92,11 +94,14 @@ import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.UnsupportedServiceException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.network.IpAddress.State;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.GuestType;
|
||||
import com.cloud.network.Network.IpAddresses;
|
||||
import com.cloud.network.Network.PVlanType;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
@ -187,6 +192,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.exception.ExceptionUtil;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicSecondaryIp;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
@ -195,15 +201,15 @@ import com.cloud.vm.SecondaryStorageVmVO;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpVO;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* NetworkServiceImpl implements NetworkService.
|
||||
*/
|
||||
@ -327,6 +333,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
||||
AccountService _accountService;
|
||||
@Inject
|
||||
NetworkAccountDao _networkAccountDao;
|
||||
@Inject
|
||||
VirtualMachineManager vmManager;
|
||||
|
||||
int _cidrLimit;
|
||||
boolean _allowSubdomainNetworkAccess;
|
||||
@ -2144,6 +2152,38 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
||||
return vms.isEmpty();
|
||||
}
|
||||
|
||||
private void replugNicsForUpdatedNetwork(NetworkVO network) throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
|
||||
Network updatedNetwork = getNetwork(network.getId());
|
||||
for (NicVO nic : nics) {
|
||||
long vmId = nic.getInstanceId();
|
||||
VMInstanceVO vm = _vmDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
s_logger.error(String.format("Cannot replug NIC: %s as VM for it is not found with ID: %d", nic, vmId));
|
||||
continue;
|
||||
}
|
||||
if (!Hypervisor.HypervisorType.VMware.equals(vm.getHypervisorType())) {
|
||||
s_logger.debug(String.format("Cannot replug NIC: %s for VM: %s as it is not on VMware", nic, vm));
|
||||
continue;
|
||||
}
|
||||
if (!VirtualMachine.Type.User.equals(vm.getType())) {
|
||||
s_logger.debug(String.format("Cannot replug NIC: %s for VM: %s as it is not a user VM", nic, vm));
|
||||
continue;
|
||||
}
|
||||
if (!VirtualMachine.State.Running.equals(vm.getState())) {
|
||||
s_logger.debug(String.format("Cannot replug NIC: %s for VM: %s as it is not in running state", nic, vm));
|
||||
continue;
|
||||
}
|
||||
Host host = _hostDao.findById(vm.getHostId());
|
||||
VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vm, null, null, null, null);
|
||||
NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(),
|
||||
_networkModel.getNetworkRate(network.getId(), vm.getId()),
|
||||
_networkModel.isSecurityGroupSupportedInNetwork(updatedNetwork),
|
||||
_networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network));
|
||||
vmManager.replugNic(updatedNetwork, vmManager.toNicTO(nicProfile, vm.getHypervisorType()), vmManager.toVmTO(vmProfile), host);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = true)
|
||||
@ -2545,6 +2585,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if (networkOfferingChanged) {
|
||||
replugNicsForUpdatedNetwork(network);
|
||||
}
|
||||
}
|
||||
|
||||
// 4) if network has been upgraded from a non persistent ntwk offering to a persistent ntwk offering,
|
||||
|
||||
@ -820,6 +820,7 @@
|
||||
"label.disksizeusedgb": "Used",
|
||||
"label.display.text": "Display Text",
|
||||
"label.displayname": "Display Name",
|
||||
"label.displaynetwork": "Display Network",
|
||||
"label.displaytext": "Description",
|
||||
"label.distributedvpcrouter": "Distributed VPC Router",
|
||||
"label.dns": "DNS",
|
||||
@ -2241,6 +2242,7 @@
|
||||
"label.untagged": "Untagged",
|
||||
"label.update.instance.group": "Update Instance Group",
|
||||
"label.update.ip.range": "Update IP range",
|
||||
"label.update.network": "Update Network",
|
||||
"label.update.physical.network": "Update Physical Network",
|
||||
"label.update.project.resources": "Update project resources",
|
||||
"label.update.project.role": "Update project role",
|
||||
@ -3080,6 +3082,10 @@
|
||||
"message.network.error": "Network Error",
|
||||
"message.network.error.description": "Unable to reach the management server or a browser extension may be blocking the network request.",
|
||||
"message.network.hint": "Configure network components and public/guest/management traffic including IP addresses.",
|
||||
"message.network.offering.change.warning": "WARNING: Changing the offering will cause connectivity downtime for the VMs with NICs in the network.",
|
||||
"message.network.offering.forged.transmits": "Applicable for guest networks on VMware hypervisor only.\nReject - The switch drops any outbound frame from a virtual machine adapter with a source MAC address that is different from the one in the .vmx configuration file.\nAccept - The switch does not perform filtering, and permits all outbound frames.\nNone - Default to value from global setting.",
|
||||
"message.network.offering.mac.address.changes": "Applicable for guest networks on VMware hypervisor only.\nReject - If the guest OS changes the effective MAC address of the virtual machine to a value that is different from the MAC address of the VM network adapter (set in the .vmx configuration file), the switch drops all inbound frames to the adapter.\nIf the guest OS changes the effective MAC address of the virtual machine back to the MAC address of the VM network adapter, the virtual machine receives frames again.\nAccept - If the guest OS changes the effective MAC address of the virtual machine to a value that is different from the MAC address of the VM network adapter, the switch allows frames to the new address to pass.\nNone - Default to value from global setting.",
|
||||
"message.network.offering.promiscuous.mode": "Applicable for guest networks on VMware hypervisor only.\nReject - The switch drops any outbound frame from a virtual machine adapter with a source MAC address that is different from the one in the .vmx configuration file.\nAccept - The switch does not perform filtering, and permits all outbound frames.\nNone - Default to value from global setting.",
|
||||
"message.network.remote.access.vpn.configuration": "Remote Access VPN configuration has been generated, but it failed to apply. Please check connectivity of the network element, then re-try.",
|
||||
"message.network.removenic": "Please confirm that want to remove this NIC, which will also remove the associated network from the VM.",
|
||||
"message.network.secondaryip": "Please confirm that you would like to acquire a new secondary IP for this NIC. \n NOTE: You need to manually configure the newly-acquired secondary IP inside the virtual machine.",
|
||||
@ -3291,6 +3297,7 @@
|
||||
"message.success.update.ipaddress": "Successfully updated IP Address",
|
||||
"message.success.update.iprange": "Successfully updated IP range",
|
||||
"message.success.update.kubeversion": "Successfully updated Kubernetes supported version",
|
||||
"message.success.update.network": "Successfully updated Network",
|
||||
"message.success.update.user": "Successfully updated user",
|
||||
"message.success.upgrade.kubernetes": "Successfully upgraded Kubernetes cluster",
|
||||
"message.success.upload": "Upload Successfully",
|
||||
|
||||
@ -75,15 +75,10 @@ export default {
|
||||
{
|
||||
api: 'updateNetwork',
|
||||
icon: 'edit',
|
||||
label: 'label.edit',
|
||||
label: 'label.update.network',
|
||||
dataView: true,
|
||||
args: (record) => {
|
||||
var fields = ['name', 'displaytext', 'guestvmcidr']
|
||||
if (record.type === 'Isolated') {
|
||||
fields.push(...['networkofferingid', 'networkdomain'])
|
||||
}
|
||||
return fields
|
||||
}
|
||||
popup: true,
|
||||
component: () => import('@/views/network/UpdateNetwork.vue')
|
||||
},
|
||||
{
|
||||
api: 'restartNetwork',
|
||||
|
||||
@ -1073,6 +1073,13 @@ export default {
|
||||
params.isofilter = 'executable'
|
||||
} else if (possibleApi === 'listHosts') {
|
||||
params.type = 'routing'
|
||||
} else if (possibleApi === 'listNetworkOfferings' && this.resource) {
|
||||
if (this.resource.type) {
|
||||
params.guestiptype = this.resource.type
|
||||
}
|
||||
if (!this.resource.vpcid) {
|
||||
params.forvpc = false
|
||||
}
|
||||
}
|
||||
if (showIcon) {
|
||||
params.showicon = true
|
||||
|
||||
257
ui/src/views/network/UpdateNetwork.vue
Normal file
257
ui/src/views/network/UpdateNetwork.vue
Normal file
@ -0,0 +1,257 @@
|
||||
// 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.
|
||||
|
||||
<template>
|
||||
<div class="form-layout" v-ctrl-enter="handleSubmit">
|
||||
<a-spin :spinning="loading">
|
||||
<a-form
|
||||
:form="form"
|
||||
@submit="handleSubmit"
|
||||
layout="vertical">
|
||||
<a-form-item>
|
||||
<tooltip-label slot="label" :title="$t('label.name')" :tooltip="apiParams.name.description"/>
|
||||
<a-input
|
||||
v-decorator="['name', {
|
||||
rules: [{ required: true, message: `${$t('message.error.required.input')}` }]
|
||||
}]"
|
||||
:placeholder="apiParams.name.description"
|
||||
autoFocus />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<tooltip-label slot="label" :title="$t('label.displaytext')" :tooltip="apiParams.displaytext.description"/>
|
||||
<a-input
|
||||
v-decorator="['displaytext', {
|
||||
rules: [{ required: true, message: `${$t('message.error.required.input')}` }]
|
||||
}]"
|
||||
:placeholder="apiParams.displaytext.description"
|
||||
autoFocus />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isUpdatingIsolatedNetwork">
|
||||
<tooltip-label slot="label" :title="$t('label.networkofferingid')" :tooltip="apiParams.networkofferingid.description"/>
|
||||
<span v-if="networkOffering.id && networkOffering.id != resource.networkofferingid">
|
||||
<a-alert type="warning">
|
||||
<span slot="message" v-html="$t('message.network.offering.change.warning')" />
|
||||
</a-alert>
|
||||
<br/>
|
||||
</span>
|
||||
<a-select
|
||||
id="offering-selection"
|
||||
v-decorator="['networkofferingid', {}]"
|
||||
showSearch
|
||||
optionFilterProp="children"
|
||||
:filterOption="(input, option) => {
|
||||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}"
|
||||
:loading="networkOfferingLoading"
|
||||
:placeholder="apiParams.networkofferingid.description"
|
||||
@change="val => { networkOffering = networkOfferings[val] }">
|
||||
<a-select-option v-for="(opt, optIndex) in networkOfferings" :key="optIndex">
|
||||
{{ opt.displaytext || opt.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<tooltip-label slot="label" :title="$t('label.guestvmcidr')" :tooltip="apiParams.guestvmcidr.description"/>
|
||||
<a-input
|
||||
v-decorator="['guestvmcidr', {}]"
|
||||
:placeholder="apiParams.guestvmcidr.description"
|
||||
@change="(e) => { cidrChanged = e.target.value !== resource.cidr }" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="cidrChanged">
|
||||
<tooltip-label slot="label" :title="$t('label.changecidr')" :tooltip="apiParams.changecidr.description"/>
|
||||
<a-switch v-decorator="['changecidr', {}]" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isUpdatingIsolatedNetwork">
|
||||
<tooltip-label slot="label" :title="$t('label.networkdomain')" :tooltip="apiParams.guestvmcidr.description"/>
|
||||
<a-input
|
||||
v-decorator="['networkdomain', {}]"
|
||||
:placeholder="apiParams.networkdomain.description"
|
||||
autoFocus />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="resource.redundantrouter">
|
||||
<tooltip-label slot="label" :title="$t('label.updateinsequence')" :tooltip="apiParams.updateinsequence.description"/>
|
||||
<a-switch v-decorator="['maclearning', {initialValue: false}]" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isAdmin()">
|
||||
<tooltip-label slot="label" :title="$t('label.displaynetwork')" :tooltip="apiParams.displaynetwork.description"/>
|
||||
<a-switch v-decorator="['displaynetwork', {}]" :defaultChecked="resource.displaynetwork" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isAdmin()">
|
||||
<tooltip-label slot="label" :title="$t('label.forced')" :tooltip="apiParams.forced.description"/>
|
||||
<a-switch v-decorator="['forced', {}]" />
|
||||
</a-form-item>
|
||||
|
||||
<div :span="24" class="action-button">
|
||||
<a-button @click="closeAction">{{ $t('label.cancel') }}</a-button>
|
||||
<a-button :loading="loading" ref="submit" type="primary" @click="handleSubmit">{{ this.$t('label.ok') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
||||
export default {
|
||||
name: 'UpdateNetwork',
|
||||
components: {
|
||||
TooltipLabel
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
resourceValues: {},
|
||||
networkOfferings: [],
|
||||
networkOfferingLoading: false,
|
||||
networkOffering: {},
|
||||
cidrChanged: false,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
this.form = this.$form.createForm(this)
|
||||
this.apiParams = this.$getApiParams('updateNetwork')
|
||||
},
|
||||
created () {
|
||||
this.resourceValues = {
|
||||
name: this.resource.name,
|
||||
displaytext: this.resource.displaytext,
|
||||
guestvmcidr: this.resource.cidr
|
||||
}
|
||||
if (this.isUpdatingIsolatedNetwork) {
|
||||
this.resourceValues.networkdomain = this.resource.networkdomain
|
||||
}
|
||||
for (var field in this.resourceValues) {
|
||||
var fieldValue = this.resourceValues[field]
|
||||
if (fieldValue) {
|
||||
this.form.getFieldDecorator(field, { initialValue: fieldValue })
|
||||
}
|
||||
}
|
||||
this.fetchData()
|
||||
},
|
||||
computed: {
|
||||
isUpdatingIsolatedNetwork () {
|
||||
return this.resource && this.resource.type === 'Isolated'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isAdmin () {
|
||||
return ['Admin'].includes(this.$store.getters.userInfo.roletype)
|
||||
},
|
||||
fetchData () {
|
||||
this.fetchNetworkOfferingData()
|
||||
},
|
||||
arrayHasItems (array) {
|
||||
return array !== null && array !== undefined && Array.isArray(array) && array.length > 0
|
||||
},
|
||||
fetchNetworkOfferingData () {
|
||||
this.networkOfferings = []
|
||||
if (!this.isUpdatingIsolatedNetwork) return
|
||||
const params = {
|
||||
zoneid: this.resource.zoneid,
|
||||
state: 'Enabled',
|
||||
guestiptype: this.resource.type,
|
||||
forvpc: !!this.resource.vpcid
|
||||
}
|
||||
this.networkOfferingLoading = true
|
||||
api('listNetworkOfferings', params).then(json => {
|
||||
this.networkOfferings = json.listnetworkofferingsresponse.networkoffering
|
||||
}).finally(() => {
|
||||
this.networkOfferingLoading = false
|
||||
if (this.arrayHasItems(this.networkOfferings)) {
|
||||
for (var i = 0; i < this.networkOfferings.length; i++) {
|
||||
if (this.networkOfferings[i].id === this.resource.networkofferingid) {
|
||||
this.networkOffering = this.networkOfferings[i]
|
||||
this.form.setFieldsValue({
|
||||
networkofferingid: i
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
if (this.loading) return
|
||||
this.form.validateFields((err, values) => {
|
||||
if (err) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
var manualFields = ['name', 'networkofferingid']
|
||||
const params = {
|
||||
id: this.resource.id,
|
||||
name: values.name
|
||||
}
|
||||
for (var field in values) {
|
||||
if (manualFields.includes(field)) continue
|
||||
var fieldValue = values[field]
|
||||
if (fieldValue !== undefined &&
|
||||
fieldValue !== null &&
|
||||
(!(field in this.resourceValues) || this.resourceValues[field] !== fieldValue)) {
|
||||
params[field] = fieldValue
|
||||
}
|
||||
}
|
||||
if (values.networkofferingid !== undefined &&
|
||||
values.networkofferingid != null &&
|
||||
this.networkOfferings &&
|
||||
this.networkOfferings[values.networkofferingid].id !== this.resource.networkofferingid) {
|
||||
params.networkofferingid = this.networkOfferings[values.networkofferingid].id
|
||||
}
|
||||
api('updateNetwork', params).then(json => {
|
||||
const jobId = json.updatenetworkresponse.jobid
|
||||
this.$pollJob({
|
||||
jobId,
|
||||
title: this.$t('label.update.network'),
|
||||
description: this.resource.name,
|
||||
loadingMessage: `${this.$t('label.update.network')} ${this.resource.name} ${this.$t('label.in.progress')}`,
|
||||
catchMessage: this.$t('error.fetching.async.job.result'),
|
||||
successMessage: `${this.$t('message.success.update.network')} ${this.resource.name}`
|
||||
})
|
||||
this.closeAction()
|
||||
}).catch(error => {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
closeAction () {
|
||||
this.$emit('close-action')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.form-layout {
|
||||
width: 60vw;
|
||||
|
||||
@media (min-width: 500px) {
|
||||
width: 450px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -108,13 +108,13 @@
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.promiscuousmode')">
|
||||
<a-form-item>
|
||||
<tooltip-label slot="label" :title="$t('label.promiscuousmode')" :tooltip="$t('message.network.offering.promiscuous.mode')"/>
|
||||
<a-radio-group
|
||||
v-decorator="['promiscuousmode', {
|
||||
initialValue: promiscuousMode
|
||||
initialValue: ''
|
||||
}]"
|
||||
buttonStyle="solid"
|
||||
@change="selected => { handlePromiscuousModeChange(selected.target.value) }">
|
||||
buttonStyle="solid">
|
||||
<a-radio-button value="">
|
||||
{{ $t('label.none') }}
|
||||
</a-radio-button>
|
||||
@ -126,13 +126,13 @@
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.macaddresschanges')">
|
||||
<a-form-item>
|
||||
<tooltip-label slot="label" :title="$t('label.macaddresschanges')" :tooltip="$t('message.network.offering.mac.address.changes')"/>
|
||||
<a-radio-group
|
||||
v-decorator="['macaddresschanges', {
|
||||
initialValue: macAddressChanges
|
||||
initialValue: ''
|
||||
}]"
|
||||
buttonStyle="solid"
|
||||
@change="selected => { handleMacAddressChangesChange(selected.target.value) }">
|
||||
buttonStyle="solid">
|
||||
<a-radio-button value="">
|
||||
{{ $t('label.none') }}
|
||||
</a-radio-button>
|
||||
@ -144,13 +144,13 @@
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.forgedtransmits')">
|
||||
<a-form-item>
|
||||
<tooltip-label slot="label" :title="$t('label.forgedtransmits')" :tooltip="$t('message.network.offering.forged.transmits')"/>
|
||||
<a-radio-group
|
||||
v-decorator="['forgedtransmits', {
|
||||
initialValue: forgedTransmits
|
||||
initialValue: ''
|
||||
}]"
|
||||
buttonStyle="solid"
|
||||
@change="selected => { handleForgedTransmitsChange(selected.target.value) }">
|
||||
buttonStyle="solid">
|
||||
<a-radio-button value="">
|
||||
{{ $t('label.none') }}
|
||||
</a-radio-button>
|
||||
@ -418,9 +418,6 @@ export default {
|
||||
hasAdvanceZone: false,
|
||||
requiredNetworkOfferingExists: false,
|
||||
guestType: 'isolated',
|
||||
promiscuousMode: '',
|
||||
macAddressChanges: '',
|
||||
forgedTransmits: '',
|
||||
selectedDomains: [],
|
||||
selectedZones: [],
|
||||
forVpc: false,
|
||||
@ -502,15 +499,6 @@ export default {
|
||||
handleGuestTypeChange (val) {
|
||||
this.guestType = val
|
||||
},
|
||||
handlePromiscuousModeChange (val) {
|
||||
this.promiscuousMode = val
|
||||
},
|
||||
handleMacAddressChangesChange (val) {
|
||||
this.macAddressChanges = val
|
||||
},
|
||||
handleForgedTransmitsChange (val) {
|
||||
this.forgedTransmits = val
|
||||
},
|
||||
fetchSupportedServiceData () {
|
||||
const params = {}
|
||||
params.listAll = true
|
||||
@ -697,7 +685,8 @@ export default {
|
||||
var self = this
|
||||
var selectedServices = null
|
||||
var keys = Object.keys(values)
|
||||
var ignoredKeys = ['state', 'status', 'allocationstate', 'forvpc', 'specifyvlan', 'ispublic', 'domainid', 'zoneid', 'egressdefaultpolicy', 'promiscuousmode', 'macaddresschanges', 'forgedtransmits', 'isolation', 'supportspublicaccess']
|
||||
const detailsKey = ['promiscuousmode', 'macaddresschanges', 'forgedtransmits']
|
||||
const ignoredKeys = [...detailsKey, 'state', 'status', 'allocationstate', 'forvpc', 'specifyvlan', 'ispublic', 'domainid', 'zoneid', 'egressdefaultpolicy', 'isolation', 'supportspublicaccess']
|
||||
keys.forEach(function (key, keyIndex) {
|
||||
if (self.isSupportedServiceObject(values[key])) {
|
||||
if (selectedServices == null) {
|
||||
@ -840,14 +829,10 @@ export default {
|
||||
if ('egressdefaultpolicy' in values && values.egressdefaultpolicy !== 'allow') {
|
||||
params.egressdefaultpolicy = false
|
||||
}
|
||||
if (values.promiscuousmode) {
|
||||
params['details[0].promiscuousMode'] = values.promiscuousmode
|
||||
}
|
||||
if (values.macaddresschanges) {
|
||||
params['details[0].macaddresschanges'] = values.macaddresschanges
|
||||
}
|
||||
if (values.forgedtransmits) {
|
||||
params['details[0].forgedtransmits'] = values.forgedtransmits
|
||||
for (const key of detailsKey) {
|
||||
if (values[key]) {
|
||||
params['details[0].' + key] = values[key]
|
||||
}
|
||||
}
|
||||
if (values.ispublic !== true) {
|
||||
var domainIndexes = values.domainid
|
||||
|
||||
@ -525,17 +525,9 @@ public class HypervisorHostHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ethPortProfileName
|
||||
* @param namePrefix
|
||||
* @param hostMo
|
||||
* @param vlanId
|
||||
* @param networkRateMbps
|
||||
* @param networkRateMulticastMbps
|
||||
* @param timeOutMs
|
||||
* @param vSwitchType
|
||||
* @param numPorts
|
||||
* @param details
|
||||
* @return
|
||||
* Prepares network (for non-standard virtual switch) for the VM NIC based on the parameters.
|
||||
* Can create a new portgroup or update an existing.
|
||||
* @return Pair of network's ManagedObjectReference and name
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
@ -1416,10 +1408,10 @@ public class HypervisorHostHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (secPolicyInSpec != null && securityPolicy != null
|
||||
if (secPolicyInSpec != null
|
||||
&& ((securityPolicy.isAllowPromiscuous() != null && !securityPolicy.isAllowPromiscuous().equals(secPolicyInSpec.isAllowPromiscuous()))
|
||||
|| (securityPolicy.isForgedTransmits() != null && !securityPolicy.isForgedTransmits().equals(secPolicyInSpec.isForgedTransmits()))
|
||||
|| (securityPolicy.isMacChanges() != null && securityPolicy.isMacChanges().equals(secPolicyInSpec.isMacChanges())))) {
|
||||
|| (securityPolicy.isMacChanges() != null && !securityPolicy.isMacChanges().equals(secPolicyInSpec.isMacChanges())))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user