CLOUDSTACK-10047: DVSwitch fixes and improvements (#2293)

Allow security policies to apply on port groups:
- Accepts security policies while creating network offering
- Deployed network will have security policies from the network offering
  applied on the port group (in vmware environment)
- Global settings as fallback when security policies are not defined for a network
  offering
- Default promiscuous mode security policy set to REJECT as it's the default
  for standard/default vswitch

Portgroup vlan-trunking options for dvswitch: This allows admins to define
a network with comma separated vlan id and vlan
range such as vlan://200-400,21,30-50 and use the provided vlan range to
configure vlan-trunking for a portgroup in dvswitch based environment.

VLAN overlap checks are performed for:
- isolated network against existing shared and isolated networks
- dedicated vlan ranges for the physical/public network for the zone
- shared network against existing isolated network

Allow shared networks to bypass vlan overlap checks: This allows admins
to create shared networks with a `bypassvlanoverlapcheck` API flag
which when set to 'true' will create a shared network without
performing vlan overlap checks against isolated network and against
the vlans allocated to the datacenter's physical network (vlan ranges).

Notes:
- No vlan-range overlap checks are performed when creating shared networks
- Multiple vlan id/ranges should include the vlan:// scheme prefix

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2017-10-25 15:14:42 +05:30 committed by GitHub
parent 4d19373d36
commit 41fdb88970
33 changed files with 738 additions and 192 deletions

View File

@ -16,7 +16,10 @@
// under the License.
package com.cloud.agent.api.to;
import com.cloud.offering.NetworkOffering;
import java.util.List;
import java.util.Map;
public class NicTO extends NetworkTO {
int deviceId;
@ -26,6 +29,7 @@ public class NicTO extends NetworkTO {
boolean pxeDisable;
String nicUuid;
List<String> nicSecIps;
Map<NetworkOffering.Detail, String> details;
public NicTO() {
super();
@ -97,4 +101,12 @@ public class NicTO extends NetworkTO {
public void setNetworkUuid(String uuid) {
super.setUuid(uuid);
}
public Map<NetworkOffering.Detail, String> getDetails() {
return details;
}
public void setDetails(final Map<NetworkOffering.Detail, String> details) {
this.details = details;
}
}

View File

@ -75,6 +75,10 @@ public class Networks {
throw new CloudRuntimeException("Unable to convert to broadcast URI: " + value);
}
}
@Override
public String getValueFrom(URI uri) {
return uri.getAuthority();
}
},
Vswitch("vs", String.class), LinkLocal(null, null), Vnet("vnet", Long.class), Storage("storage", Integer.class), Lswitch("lswitch", String.class) {
@Override

View File

@ -38,7 +38,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
}
public enum Detail {
InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription
InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits
}
public final static String SystemPublicNetwork = "System-Public-Network";

View File

@ -38,6 +38,7 @@ public class ApiConstants {
public static final String BIND_PASSWORD = "bindpass";
public static final String BYTES_READ_RATE = "bytesreadrate";
public static final String BYTES_WRITE_RATE = "byteswriterate";
public static final String BYPASS_VLAN_OVERLAP_CHECK = "bypassvlanoverlapcheck";
public static final String CATEGORY = "category";
public static final String CAN_REVERT = "canrevert";
public static final String CA_CERTIFICATES = "cacertificates";

View File

@ -40,6 +40,9 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd {
@Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network")
private String vlan;
@Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during network creation for shared networks")
private Boolean bypassVlanOverlapCheck;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -48,6 +51,13 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd {
return vlan;
}
public Boolean getBypassVlanOverlapCheck() {
if (bypassVlanOverlapCheck != null) {
return bypassVlanOverlapCheck;
}
return false;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -113,7 +113,8 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
private Boolean isPersistent;
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = "4.2.0", description = "Network offering details in key/value pairs."
+ " Supported keys are internallbprovider/publiclbprovider with service provider as a value")
+ " Supported keys are internallbprovider/publiclbprovider with service provider as a value, and"
+ " promiscuousmode/macaddresschanges/forgedtransmits with true/false as value to accept/reject the security settings if available for a nic/portgroup")
protected Map details;
@Parameter(name = ApiConstants.EGRESS_DEFAULT_POLICY,

View File

@ -16,16 +16,16 @@
// under the License.
package com.cloud.network;
import java.net.URISyntaxException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.cloud.dc.Vlan;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.IsolationType;
import com.cloud.utils.exception.CloudRuntimeException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.net.URI;
import java.net.URISyntaxException;
/**
* @author dhoogland
@ -43,6 +43,13 @@ public class NetworksTest {
Assert.assertEquals("an empty uri should mean a broadcasttype of undecided", BroadcastDomainType.UnDecided, type);
}
@Test
public void vlanCommaSeparatedTest() throws URISyntaxException {
Assert.assertEquals(BroadcastDomainType.getValue(new URI("vlan://100")), "100");
Assert.assertEquals(BroadcastDomainType.getValue(new URI("vlan://100-200")), "100-200");
Assert.assertEquals(BroadcastDomainType.getValue(new URI("vlan://10-50,12,11,112-170")), "10-50,12,11,112-170");
}
@Test
public void vlanBroadcastDomainTypeTest() throws URISyntaxException {
String uri1 = "vlan://1";

View File

@ -77,6 +77,15 @@ public interface NetworkOrchestrationService {
ConfigKey<Integer> NetworkThrottlingRate = new ConfigKey<Integer>("Network", Integer.class, NetworkThrottlingRateCK, "200",
"Default data transfer rate in megabits per second allowed in network.", true, ConfigKey.Scope.Zone);
ConfigKey<Boolean> PromiscuousMode = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.promiscuous.mode", "false",
"Whether to allow or deny promiscuous mode on nics for applicable network elements such as for vswitch/dvswitch portgroups.", true);
ConfigKey<Boolean> MacAddressChanges = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.mac.address.changes", "true",
"Whether to allow or deny mac address changes on nics for applicable network elements such as for vswitch/dvswitch porgroups.", true);
ConfigKey<Boolean> ForgedTransmits = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.forged.transmits", "true",
"Whether to allow or deny forged transmits on nics for applicable network elements such as for vswitch/dvswitch portgroups.", true);
List<? extends Network> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault)
throws ConcurrentOperationException;
@ -136,7 +145,7 @@ public interface NetworkOrchestrationService {
boolean destroyNetwork(long networkId, ReservationContext context, boolean forced);
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner,
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain, Account owner,
Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;

View File

@ -214,7 +214,7 @@ public interface ConfigurationManager {
Map<NetworkOffering.Detail, String> details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive);
Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP,
String vlanGateway, String vlanNetmask, String vlanId, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr)
String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr)
throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException;
void createDefaultSystemNetworks(long zoneId) throws ConcurrentOperationException;

View File

@ -32,18 +32,10 @@ import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.network.dao.NetworkDetailsDao;
import com.cloud.network.dao.RemoteAccessVpnDao;
import com.cloud.network.dao.RemoteAccessVpnVO;
import com.cloud.network.dao.VpnUserDao;
import com.cloud.network.element.RedundantResource;
import com.cloud.network.router.VirtualRouter;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.dao.DomainRouterDao;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO;
@ -58,6 +50,8 @@ import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.PublishScope;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.region.PortableIpDao;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.Listener;
import com.cloud.agent.api.AgentControlAnswer;
@ -129,6 +123,7 @@ import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkAccountDao;
import com.cloud.network.dao.NetworkAccountVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkDetailsDao;
import com.cloud.network.dao.NetworkDomainDao;
import com.cloud.network.dao.NetworkDomainVO;
import com.cloud.network.dao.NetworkServiceMapDao;
@ -139,17 +134,22 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.dao.RemoteAccessVpnDao;
import com.cloud.network.dao.RemoteAccessVpnVO;
import com.cloud.network.dao.VpnUserDao;
import com.cloud.network.element.AggregatedCommandExecutor;
import com.cloud.network.element.DhcpServiceProvider;
import com.cloud.network.element.DnsServiceProvider;
import com.cloud.network.element.IpDeployer;
import com.cloud.network.element.LoadBalancingServiceProvider;
import com.cloud.network.element.NetworkElement;
import com.cloud.network.element.RedundantResource;
import com.cloud.network.element.StaticNatServiceProvider;
import com.cloud.network.element.UserDataServiceProvider;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.guru.NetworkGuruAdditionalFunctions;
import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.rules.FirewallManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.Purpose;
@ -197,6 +197,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.utils.fsm.StateMachine2;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.Nic;
import com.cloud.vm.Nic.ReservationStrategy;
import com.cloud.vm.NicIpAlias;
@ -209,6 +210,7 @@ import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicIpAliasDao;
import com.cloud.vm.dao.NicIpAliasVO;
@ -2017,9 +2019,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
@Override
@DB
public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, Boolean subdomainAccess,
final Long vpcId, final String ip6Gateway, final String ip6Cidr, final Boolean isDisplayNetworkEnabled, final String isolatedPvlan)
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
// this method supports only guest network creation
@ -2136,19 +2138,19 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
if (vlanSpecified) {
URI uri = BroadcastDomainType.fromString(vlanId);
//don't allow to specify vlan tag used by physical network for dynamic vlan allocation
if (_dcDao.findVnet(zoneId, pNtwk.getId(), vlanId).size() > 0) {
if (!(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
+ zone.getName());
}
if (! UuidUtils.validateUUID(vlanId)){
final String uri = BroadcastDomainType.fromString(vlanId).toString();
// For Isolated networks, don't allow to create network with vlan that already exists in the zone
if (ntwkOff.getGuestType() == GuestType.Isolated) {
if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) {
throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
if (_networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), null).size() > 0) {
throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists or overlaps with other network vlans in zone " + zoneId);
} else {
final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString());
final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, BroadcastDomainType.getValue(uri));
//for the network that is created as part of private gateway,
//the vnet is not coming from the data center vnet table, so the list can be empty
if (!dcVnets.isEmpty()) {
@ -2177,8 +2179,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
} else {
// don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
// shared network with same Vlan ID in the zone
if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0 ) {
throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId);
if (!bypassVlanOverlapCheck && _networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), GuestType.Isolated).size() > 0 ) {
throw new InvalidParameterValueException("There is an existing isolated/shared network that overlaps with vlan id:" + vlanId + " in zone " + zoneId);
}
}
}
@ -3663,6 +3665,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {NetworkGcWait, NetworkGcInterval, NetworkLockTimeout, GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion};
return new ConfigKey<?>[] {NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
PromiscuousMode, MacAddressChanges, ForgedTransmits};
}
}

View File

@ -27,10 +27,10 @@ public interface DataCenterVnetDao extends GenericDao<DataCenterVnetVO, Long> {
public List<DataCenterVnetVO> listAllocatedVnetsInRange(long dcId, long physicalNetworkId, Integer start, Integer end);
public List<DataCenterVnetVO> findVnet(long dcId, String vnet);
public int countZoneVlans(long dcId, boolean onlyCountAllocated);
public List<DataCenterVnetVO> findVnet(long dcId, String vnet);
public List<DataCenterVnetVO> findVnet(long dcId, long physicalNetworkId, String vnet);
public void add(long dcId, long physicalNetworkId, List<String> vnets);

View File

@ -18,6 +18,7 @@ package com.cloud.dc.dao;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -30,6 +31,8 @@ import org.springframework.stereotype.Component;
import com.cloud.dc.DataCenterVnetVO;
import com.cloud.network.dao.AccountGuestVlanMapDao;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.UriUtils;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
@ -99,15 +102,6 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
lockRows(sc, null, true);
}
@Override
public List<DataCenterVnetVO> findVnet(long dcId, String vnet) {
SearchCriteria<DataCenterVnetVO> sc = VnetDcSearch.create();
;
sc.setParameters("dc", dcId);
sc.setParameters("vnet", vnet);
return listBy(sc);
}
@Override
public int countZoneVlans(long dcId, boolean onlyCountAllocated) {
SearchCriteria<Integer> sc = onlyCountAllocated ? countAllocatedZoneVlans.create() : countZoneVlans.create();
@ -115,14 +109,37 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
return customSearch(sc, null).get(0);
}
@Override
public List<DataCenterVnetVO> findVnet(long dcId, long physicalNetworkId, String vnet) {
private List<DataCenterVnetVO> findOverlappingVnets(final long dcId, final Long physicalNetworkId, final String vnet) {
final List<Integer> searchVnets = UriUtils.expandVlanUri(vnet);
final List<DataCenterVnetVO> overlappingVnets = new ArrayList<>();
if (searchVnets == null || searchVnets.isEmpty()) {
return overlappingVnets;
}
SearchCriteria<DataCenterVnetVO> sc = VnetDcSearch.create();
sc.setParameters("dc", dcId);
if (physicalNetworkId != null) {
sc.setParameters("physicalNetworkId", physicalNetworkId);
sc.setParameters("vnet", vnet);
}
for (final DataCenterVnetVO dcVNet : listBy(sc)) {
if (dcVNet == null || dcVNet.getVnet() == null) {
continue;
}
final Integer vnetValue = NumbersUtil.parseInt(dcVNet.getVnet(), -1);
if (vnetValue != -1 && searchVnets.contains(vnetValue)) {
overlappingVnets.add(dcVNet);
}
}
return overlappingVnets;
}
return listBy(sc);
@Override
public List<DataCenterVnetVO> findVnet(long dcId, String vnet) {
return findOverlappingVnets(dcId, null, vnet);
}
@Override
public List<DataCenterVnetVO> findVnet(long dcId, long physicalNetworkId, String vnet) {
return findOverlappingVnets(dcId, physicalNetworkId, vnet);
}
@Override

View File

@ -61,9 +61,7 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
List<NetworkVO> listBy(long accountId, long networkId);
long countByZoneAndUri(long zoneId, String broadcastUri);
long countByZoneUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType);
List<NetworkVO> listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType);
List<NetworkVO> listByZone(long zoneId);

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.network.dao;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
@ -24,9 +26,8 @@ import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.persistence.TableGenerator;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.springframework.stereotype.Component;
import com.cloud.network.Network;
import com.cloud.network.Network.Event;
@ -42,6 +43,7 @@ import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.server.ResourceTag.ResourceObjectType;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.utils.UriUtils;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
@ -71,7 +73,6 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
GenericSearchBuilder<NetworkVO, Long> NetworksRegularUserCanCreateSearch;
GenericSearchBuilder<NetworkVO, Integer> NetworksCount;
SearchBuilder<NetworkVO> SourceNATSearch;
GenericSearchBuilder<NetworkVO, Long> CountByZoneAndURI;
GenericSearchBuilder<NetworkVO, Long> VpcNetworksCount;
SearchBuilder<NetworkVO> OfferingAccountNetworkSearch;
@ -152,14 +153,6 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
ZoneBroadcastUriSearch.and("guestType", ZoneBroadcastUriSearch.entity().getGuestType(), Op.EQ);
ZoneBroadcastUriSearch.done();
CountByZoneAndURI = createSearchBuilder(Long.class);
CountByZoneAndURI.select(null, Func.COUNT, null);
CountByZoneAndURI.and("dataCenterId", CountByZoneAndURI.entity().getDataCenterId(), Op.EQ);
CountByZoneAndURI.and("broadcastUri", CountByZoneAndURI.entity().getBroadcastUri(), Op.EQ);
CountByZoneAndURI.and("guestType", CountByZoneAndURI.entity().getGuestType(), Op.EQ);
CountByZoneAndURI.done();
ZoneSecurityGroupSearch = createSearchBuilder();
ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ);
final SearchBuilder<NetworkServiceMapVO> offJoin = _ntwkSvcMap.createSearchBuilder();
@ -399,13 +392,35 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
}
@Override
public long countByZoneAndUri(final long zoneId, final String broadcastUri) {
public List<NetworkVO> listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) {
final URI searchUri = BroadcastDomainType.fromString(broadcastUri);
final String searchRange = BroadcastDomainType.getValue(searchUri);
final List<Integer> searchVlans = UriUtils.expandVlanUri(searchRange);
final List<NetworkVO> overlappingNetworks = new ArrayList<>();
final SearchCriteria<Long> sc = CountByZoneAndURI.create();
final SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
sc.setParameters("dataCenterId", zoneId);
sc.setParameters("broadcastUri", broadcastUri);
if (guestType != null) {
sc.setParameters("guestType", guestType);
}
return customSearch(sc, null).get(0);
for (final NetworkVO network : listBy(sc)) {
if (network.getBroadcastUri() == null || !network.getBroadcastUri().getScheme().equalsIgnoreCase(searchUri.getScheme())) {
continue;
}
final String networkVlanRange = BroadcastDomainType.getValue(network.getBroadcastUri());
if (networkVlanRange == null || networkVlanRange.isEmpty()) {
continue;
}
for (final Integer networkVlan : UriUtils.expandVlanUri(networkVlanRange)) {
if (searchVlans.contains(networkVlan)) {
overlappingNetworks.add(network);
break;
}
}
}
return overlappingNetworks;
}
@Override
@ -415,15 +430,6 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
return search(sc, null);
}
@Override
public long countByZoneUriAndGuestType(final long zoneId, final String broadcastUri, final GuestType guestType) {
final SearchCriteria<Long> sc = CountByZoneAndURI.create();
sc.setParameters("dataCenterId", zoneId);
sc.setParameters("broadcastUri", broadcastUri);
sc.setParameters("guestType", guestType);
return customSearch(sc, null).get(0);
}
@Override
public List<NetworkVO> listByZoneSecurityGroup(final Long zoneId) {
final SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create();

View File

@ -392,11 +392,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
//The management network is probably always going to be a physical network with islation type of vlans, so assume BroadcastDomainType VLAN
if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null);
HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
}
else {
HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, null, 180000,
vsType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, null);
vsType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, null, null);
}
}

View File

@ -1178,11 +1178,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) {
networkInfo = HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(),
"cloud.public", vmMo.getRunningHost(), vlanId, null, null,
_opsTimeout, true, BroadcastDomainType.Vlan, null);
_opsTimeout, true, BroadcastDomainType.Vlan, null, null);
} else {
networkInfo =
HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, null, null,
_opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, _vsmCredentials);
_opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, _vsmCredentials, null);
}
int nicIndex = allocPublicNicIndex(vmMo);
@ -3032,7 +3032,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (VirtualSwitchType.StandardVirtualSwitch == switchType) {
networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo,
getVlanInfo(nicTo, vlanToken), nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(),
_opsTimeout, !namePrefix.startsWith("cloud.private"), nicTo.getBroadcastType(), nicTo.getUuid());
_opsTimeout, true, nicTo.getBroadcastType(), nicTo.getUuid(), nicTo.getDetails());
}
else {
String vlanId = getVlanInfo(nicTo, vlanToken);
@ -3047,7 +3047,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, vlanId, svlanId,
nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _opsTimeout, switchType,
_portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials);
_portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials, nicTo.getDetails());
}
return networkInfo;

View File

@ -199,6 +199,7 @@ import com.cloud.user.dao.UserDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.UriUtils;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.EntityManager;
@ -2893,7 +2894,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
newVlanNetmask = sameSubnet.second().second();
}
final Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId,
domain, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
false, domain, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
// create an entry in the nic_secondary table. This will be the new
// gateway that will be configured on the corresponding routervm.
return vlan;
@ -3010,7 +3011,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
@Override
@DB
public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final boolean forVirtualNetwork, final Long podId, final String startIP, final String endIP,
final String vlanGateway, final String vlanNetmask, String vlanId, Domain domain, final Account vlanOwner, final String startIPv6, final String endIPv6, final String vlanIp6Gateway, final String vlanIp6Cidr) {
final String vlanGateway, final String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, final Account vlanOwner, final String startIPv6, final String endIPv6, final String vlanIp6Gateway, final String vlanIp6Cidr) {
final Network network = _networkModel.getNetwork(networkId);
boolean ipv4 = false, ipv6 = false;
@ -3077,9 +3078,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
final String[] vlan = uri.toString().split("vlan:\\/\\/");
networkVlanId = vlan[1];
// For pvlan
if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) {
networkVlanId = networkVlanId.split("-")[0];
}
}
}
if (vlanId != null && !connectivityWithoutVlan) {
// if vlan is specified, throw an error if it's not equal to
@ -3168,7 +3171,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
continue;
}
// from here, subnet overlaps
if ( !vlanId.equals(vlan.getVlanTag()) ) {
if (!UriUtils.checkVlanUriOverlap(
BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId)),
BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlan.getVlanTag())))) {
boolean overlapped = false;
if( network.getTrafficType() == TrafficType.Public ) {
overlapped = true;
@ -3239,7 +3244,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
// Check if the vlan is being used
if (_zoneDao.findVnet(zoneId, physicalNetworkId, vlanId).size() > 0) {
if (!bypassVlanOverlapCheck && _zoneDao.findVnet(zoneId, physicalNetworkId, BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId))).size() > 0) {
throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
+ zone.getName());
}

View File

@ -22,6 +22,7 @@ import java.util.UUID;
import javax.inject.Inject;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Command;
@ -29,9 +30,12 @@ import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.gpu.GPU;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
import com.cloud.resource.ResourceManager;
import com.cloud.service.ServiceOfferingDetailsVO;
import com.cloud.service.dao.ServiceOfferingDao;
@ -48,7 +52,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 com.cloud.network.Networks.BroadcastDomainType;
public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
public static final Logger s_logger = Logger.getLogger(HypervisorGuruBase.class);
@ -58,6 +61,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
@Inject
private NetworkDao _networkDao;
@Inject
private NetworkOfferingDetailsDao networkOfferingDetailsDao;
@Inject
private VMInstanceDao _virtualMachineDao;
@Inject
private UserVmDetailsDao _userVmDetailsDao;
@ -138,7 +143,18 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
if(vm.getType() == VirtualMachine.Type.NetScalerVm) {
nicProfile.setBroadcastType(BroadcastDomainType.Native);
}
nics[i++] = toNicTO(nicProfile);
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());
}
nicTo.setDetails(details);
}
nics[i++] = nicTo;
}
to.setNics(nics);

View File

@ -1631,7 +1631,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
+ " as a part of createVlanIpRange process");
guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
+ "-network", null, null, null, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null);
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null);
if (guestNetwork == null) {
s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT "

View File

@ -1038,9 +1038,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
String netmask = cmd.getNetmask();
String networkDomain = cmd.getNetworkDomain();
String vlanId = null;
boolean bypassVlanOverlapCheck = false;
if (cmd instanceof CreateNetworkCmdByAdmin) {
vlanId = ((CreateNetworkCmdByAdmin)cmd).getVlan();
}
if (cmd instanceof CreateNetworkCmdByAdmin) {
bypassVlanOverlapCheck = ((CreateNetworkCmdByAdmin)cmd).getBypassVlanOverlapCheck();
}
String name = cmd.getNetworkName();
String displayText = cmd.getDisplayText();
Account caller = CallContext.current().getCallingAccount();
@ -1259,8 +1264,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
// Don't allow to specify vlan if the caller is not ROOT admin
if (!_accountMgr.isRootAdmin(caller.getId()) && (ntwkOff.getSpecifyVlan() || vlanId != null)) {
throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId");
if (!_accountMgr.isRootAdmin(caller.getId()) && (ntwkOff.getSpecifyVlan() || vlanId != null || bypassVlanOverlapCheck)) {
throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId or bypass vlan overlap check");
}
if (ipv4) {
@ -1319,7 +1324,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
throw ex;
}
Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, name, displayText, caller, physicalNetworkId, zoneId, domainId,
Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId, domainId,
isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, isolatedPvlan, ntwkOff, pNtwk, aclType, owner, cidr,
createVlan);
@ -1351,7 +1356,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
private Network commitNetwork(final Long networkOfferingId, final String gateway, final String startIP, final String endIP, final String netmask, final String networkDomain,
final String vlanId, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
final String vlanId, final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway,
final String ip6Cidr, final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk,
final ACLType aclType, final Account ownerFinal, final String cidr, final boolean createVlan) throws InsufficientCapacityException, ResourceAllocationException {
@ -1408,14 +1413,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only");
}
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId,
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk, zoneId,
aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan);
}
if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
// Create vlan ip range
_configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, null, startIP, endIP, gateway, netmask, vlanId,
null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
bypassVlanOverlapCheck, null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
}
return network;
}
@ -4079,7 +4084,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId);
if (privateNetwork == null) {
//create Guest network
privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, null, owner, null, pNtwk,
privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, false, null, owner, null, pNtwk,
pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null);
if (privateNetwork != null) {
s_logger.debug("Successfully created guest network " + privateNetwork);

View File

@ -2359,7 +2359,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
validateNtwkOffForNtwkInVpc(null, ntwkOffId, cidr, networkDomain, vpc, gateway, owner, aclId);
// 2) Create network
final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, false, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null);
if (guestNetwork != null) {

View File

@ -3103,7 +3103,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network",
null, null, null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
if (newNetwork != null) {
defaultNetwork = _networkDao.findById(newNetwork.getId());
}
@ -5723,7 +5723,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId()
+ " as a part of deployVM process");
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network",
newAccount.getAccountName() + "-network", null, null, null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
null, null, true, null);
// if the network offering has persistent set to true, implement the network
if (requiredOfferings.get(0).getIsPersistent()) {

View File

@ -121,7 +121,7 @@ public class CreatePrivateNetworkTest {
new NetworkVO(1L, TrafficType.Guest, Mode.None, BroadcastDomainType.Vlan, 1L, 1L, 1L, 1L, "bla", "fake", "eet.net", GuestType.Isolated, 1L, 1L,
ACLType.Account, false, 1L, false);
when(
networkService._networkMgr.createGuestNetwork(eq(ntwkOff.getId()), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), anyString(), anyString(),
networkService._networkMgr.createGuestNetwork(eq(ntwkOff.getId()), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), anyString(), anyBoolean(), anyString(),
eq(account), anyLong(), eq(physicalNetwork), eq(physicalNetwork.getDataCenterId()), eq(ACLType.Account), anyBoolean(), eq(1L), anyString(), anyString(),
anyBoolean(), anyString())).thenReturn(net);

View File

@ -440,7 +440,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
*/
@Override
public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP,
String vlanGateway, String vlanNetmask, String vlanId, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanGatewayv6, String vlanCidrv6)
String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanGatewayv6, String vlanCidrv6)
throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException {
// TODO Auto-generated method stub
return null;

View File

@ -611,9 +611,9 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
* @see com.cloud.network.NetworkManager#createGuestNetwork(long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.cloud.user.Account, java.lang.Long, com.cloud.network.PhysicalNetwork, long, org.apache.cloudstack.acl.ControlledEntity.ACLType, java.lang.Boolean, java.lang.Long)
*/
@Override
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain,
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain,
Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6,
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan ) throws ConcurrentOperationException, InsufficientCapacityException,
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException,
ResourceAllocationException {
// TODO Auto-generated method stub
return null;

View File

@ -85,13 +85,8 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
}
@Override
public long countByZoneAndUri(final long zoneId, final String broadcastUri) {
return 0;
}
@Override
public long countByZoneUriAndGuestType(final long zoneId, final String broadcastUri, final GuestType guestType) {
return 0;
public List<NetworkVO> listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) {
return null;
}
@Override

View File

@ -761,6 +761,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
"label.firewall":"Firewall",
"label.first.name":"First Name",
"label.firstname.lower":"firstname",
"label.forged.transmits":"Forged Transmits",
"label.format":"Format",
"label.format.lower":"format",
"label.friday":"Friday",
@ -991,6 +992,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
"label.management":"Management",
"label.management.ips":"Management IP Addresses",
"label.management.server":"Management Server",
"label.mac.address.changes":"MAC Address Changes",
"label.max.cpus":"Max. CPU cores",
"label.max.guest.limit":"Max guest limit",
"label.max.instances":"Max Instances",
@ -1299,6 +1301,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
"label.project.name":"Project name",
"label.project.view":"Project View",
"label.projects":"Projects",
"label.promiscuous.mode":"Promiscuous Mode",
"label.protocol":"Protocol",
"label.protocol.number":"Protocol Number",
"label.provider":"Provider",

View File

@ -2811,6 +2811,60 @@
}
},
promiscuousMode: {
label: 'label.promiscuous.mode',
select: function(args) {
args.response.success({
data: [{
id: '',
description: ''
}, {
id: 'true',
description: 'Accept'
}, {
id: 'false',
description: 'Reject'
}]
});
}
},
macAddressChanges: {
label: 'label.mac.address.changes',
select: function(args) {
args.response.success({
data: [{
id: '',
description: ''
}, {
id: 'true',
description: 'Accept'
}, {
id: 'false',
description: 'Reject'
}]
});
}
},
forgedTransmits: {
label: 'label.forged.transmits',
select: function(args) {
args.response.success({
data: [{
id: '',
description: ''
}, {
id: 'true',
description: 'Accept'
}, {
id: 'false',
description: 'Reject'
}]
});
}
},
supportedServices: {
label: 'label.supported.services',
@ -3341,6 +3395,22 @@
delete inputData.egressdefaultpolicy;
}
if ("promiscuousMode" in inputData) {
inputData['details[0].promiscuousMode'] = inputData.promiscuousMode;
delete inputData.promiscuousMode;
}
if ("macAddressChanges" in inputData) {
inputData['details[0].macAddressChanges'] = inputData.macAddressChanges;
delete inputData.macAddressChanges;
}
if ("forgedTransmits" in inputData) {
inputData['details[0].forgedTransmits'] = inputData.forgedTransmits;
delete inputData.forgedTransmits;
}
if (args.$form.find('.form-item[rel=serviceofferingid]').css("display") == "none")
delete inputData.serviceofferingid;
@ -3639,6 +3709,9 @@
},
tags: {
label: 'label.tags'
},
details: {
label: 'label.details'
}
}],
@ -3649,9 +3722,16 @@
async: true,
success: function(json) {
var item = json.listnetworkofferingsresponse.networkoffering[0];
if (!item.hasOwnProperty('details')) {
item.details = {};
}
args.response.success({
actionFilter: networkOfferingActionfilter,
data: $.extend(item, {
details: $.map(item.details, function(val, key) {
return key + "=" + val;
}).join(', '),
supportedServices: $.map(item.service, function(service) {
return service.name;
}).join(', '),

View File

@ -30,6 +30,7 @@ import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.StringTokenizer;
@ -55,6 +56,7 @@ import org.apache.log4j.Logger;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import com.google.common.base.Strings;
public class UriUtils {
@ -391,4 +393,52 @@ public class UriUtils {
return null;
}
}
/**
* Expands a given vlan URI to a list of vlan IDs
* @param vlanAuthority the URI part without the vlan:// scheme
* @return returns list of vlan integer ids
*/
public static List<Integer> expandVlanUri(final String vlanAuthority) {
final List<Integer> expandedVlans = new ArrayList<>();
if (Strings.isNullOrEmpty(vlanAuthority)) {
return expandedVlans;
}
for (final String vlanPart: vlanAuthority.split(",")) {
if (Strings.isNullOrEmpty(vlanPart)) {
continue;
}
final String[] range = vlanPart.split("-");
if (range.length == 2) {
Integer start = NumbersUtil.parseInt(range[0], -1);
Integer end = NumbersUtil.parseInt(range[1], -1);
if (start <= end && end > -1 && start > -1) {
while (start <= end) {
expandedVlans.add(start++);
}
}
} else {
final Integer value = NumbersUtil.parseInt(range[0], -1);
if (value > -1) {
expandedVlans.add(value);
}
}
}
return expandedVlans;
}
/**
* Checks if given vlan URI authorities overlap
* @param vlanRange1
* @param vlanRange2
* @return true if they overlap
*/
public static boolean checkVlanUriOverlap(final String vlanRange1, final String vlanRange2) {
final List<Integer> vlans1 = expandVlanUri(vlanRange1);
final List<Integer> vlans2 = expandVlanUri(vlanRange2);
if (vlans1 == null || vlans2 == null) {
return true;
}
return !Collections.disjoint(vlans1, vlans2);
}
}

View File

@ -20,9 +20,12 @@
package com.cloud.utils;
import junit.framework.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class UriUtilsTest {
@Test
public void encodeURIComponent() {
@ -57,4 +60,45 @@ public class UriUtilsTest {
//XXX: Interesting cases not covered:
// * port is ignored and left out from the return value
}
@Test
public void expandVlanEmpty() {
List<Integer> vlans = UriUtils.expandVlanUri("");
Assert.assertTrue(vlans.size() == 0);
}
@Test
public void expandVlanSingleValue() {
List<Integer> vlans = UriUtils.expandVlanUri("10");
Assert.assertTrue(vlans.size() == 1);
Assert.assertEquals(vlans, Collections.singletonList(10));
}
@Test
public void expandVlanValidRange() {
List<Integer> vlans = UriUtils.expandVlanUri("10-12,14,17,40-43");
Assert.assertEquals(vlans, Arrays.asList(10,11,12,14,17,40,41,42,43));
}
@Test
public void expandVlanInvalidRange() {
List<Integer> vlans = UriUtils.expandVlanUri("10-,12-14,-4,5-2");
Assert.assertEquals(vlans, Arrays.asList(10,12,13,14));
}
@Test
public void testVlanUriOverlap() {
Assert.assertTrue(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", "10"));
Assert.assertTrue(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", "32,33-44,30-31"));
Assert.assertTrue(UriUtils.checkVlanUriOverlap("10-30", "25-35"));
}
@Test
public void testVlanUriNoOverlap() {
Assert.assertFalse(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", null));
Assert.assertFalse(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", ""));
Assert.assertFalse(UriUtils.checkVlanUriOverlap("10-30,45,50,12,31", "32"));
Assert.assertFalse(UriUtils.checkVlanUriOverlap("10,22,111", "12"));
Assert.assertFalse(UriUtils.checkVlanUriOverlap("100-200", "30-40,50,201-250"));
}
}

View File

@ -42,6 +42,11 @@
<artifactId>cloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>

View File

@ -16,11 +16,45 @@
// under the License.
package com.cloud.hypervisor.vmware.mo;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.SAXException;
import com.cloud.exception.CloudException;
import com.cloud.hypervisor.vmware.util.VmwareContext;
import com.cloud.hypervisor.vmware.util.VmwareHelper;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.offering.NetworkOffering;
import com.cloud.utils.ActionDelegate;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
import com.cloud.utils.cisco.n1kv.vsm.PolicyMap;
@ -54,6 +88,7 @@ import com.vmware.vim25.LocalizedMethodFault;
import com.vmware.vim25.LongPolicy;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.MethodFault;
import com.vmware.vim25.NumericRange;
import com.vmware.vim25.ObjectContent;
import com.vmware.vim25.OvfCreateImportSpecParams;
import com.vmware.vim25.OvfCreateImportSpecResult;
@ -79,35 +114,9 @@ import com.vmware.vim25.VirtualMachineVideoCard;
import com.vmware.vim25.VirtualSCSIController;
import com.vmware.vim25.VirtualSCSISharing;
import com.vmware.vim25.VmwareDistributedVirtualSwitchPvlanSpec;
import com.vmware.vim25.VmwareDistributedVirtualSwitchTrunkVlanSpec;
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class HypervisorHostHelper {
private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class);
@ -452,13 +461,14 @@ public class HypervisorHostHelper {
* @param timeOutMs
* @param vSwitchType
* @param numPorts
* @param details
* @return
* @throws Exception
*/
public static Pair<ManagedObjectReference, String> prepareNetwork(String physicalNetwork, String namePrefix, HostMO hostMo, String vlanId, String secondaryvlanId,
Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs, VirtualSwitchType vSwitchType, int numPorts, String gateway,
boolean configureVServiceInNexus, BroadcastDomainType broadcastDomainType, Map<String, String> vsmCredentials) throws Exception {
boolean configureVServiceInNexus, BroadcastDomainType broadcastDomainType, Map<String, String> vsmCredentials, Map<NetworkOffering.Detail, String> details) throws Exception {
ManagedObjectReference morNetwork = null;
VmwareContext context = hostMo.getContext();
ManagedObjectReference dcMor = hostMo.getHyperHostDatacenter();
@ -501,12 +511,18 @@ public class HypervisorHostHelper {
// No doubt about this, depending on vid=null to avoid lots of code below
vid = null;
} else {
if (vlanId != null) {
vlanId = vlanId.replace("vlan://", "");
}
networkName = composeCloudNetworkName(namePrefix, vlanId, secondaryvlanId, networkRateMbps, physicalNetwork);
if (vlanId != null && !UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId)) {
if (vlanId != null && !UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId) && !StringUtils.containsAny(vlanId, ",-")) {
createGCTag = true;
vid = Integer.parseInt(vlanId);
}
if (vlanId != null && StringUtils.containsAny(vlanId, ",-")) {
createGCTag = true;
}
if (secondaryvlanId != null) {
spvlanid = Integer.parseInt(secondaryvlanId);
}
@ -544,7 +560,7 @@ public class HypervisorHostHelper {
dvSwitchMo = new DistributedVirtualSwitchMO(context, morDvSwitch);
shapingPolicy = getDVSShapingPolicy(networkRateMbps);
secPolicy = createDVSSecurityPolicy();
secPolicy = createDVSSecurityPolicy(details);
// First, if both vlan id and pvlan id are provided, we need to
// reconfigure the DVSwitch to have a tuple <vlan id, pvlan id> of
@ -562,7 +578,7 @@ public class HypervisorHostHelper {
portGroupPolicy.setPortConfigResetAtDisconnect(true);
}
// Next, create the port group. For this, we need to create a VLAN spec.
createPortGroup(physicalNetwork, networkName, vid, spvlanid, dataCenterMo, shapingPolicy, secPolicy, portGroupPolicy, dvSwitchMo, numPorts, autoExpandSupported);
createPortGroup(physicalNetwork, networkName, vlanId, vid, spvlanid, dataCenterMo, shapingPolicy, secPolicy, portGroupPolicy, dvSwitchMo, numPorts, autoExpandSupported);
bWaitPortGroupReady = true;
}
} else if (vSwitchType == VirtualSwitchType.NexusDistributedVirtualSwitch) {
@ -699,7 +715,7 @@ public class HypervisorHostHelper {
}
private static void createPortGroup(String physicalNetwork, String networkName, Integer vid, Integer spvlanid, DatacenterMO dataCenterMo,
private static void createPortGroup(String physicalNetwork, String networkName, String vlanRange, Integer vid, Integer spvlanid, DatacenterMO dataCenterMo,
DVSTrafficShapingPolicy shapingPolicy, DVSSecurityPolicy secPolicy, VMwareDVSPortgroupPolicy portGroupPolicy, DistributedVirtualSwitchMO dvSwitchMo, int numPorts, boolean autoExpandSupported)
throws Exception {
VmwareDistributedVirtualSwitchVlanSpec vlanSpec = null;
@ -710,7 +726,7 @@ public class HypervisorHostHelper {
// Next, create the port group. For this, we need to create a VLAN spec.
// NOTE - VmwareDistributedVirtualSwitchPvlanSpec extends VmwareDistributedVirtualSwitchVlanSpec.
if (vid == null || spvlanid == null) {
vlanSpec = createDVPortVlanIdSpec(vid);
vlanSpec = createDVPortVlanSpec(vid, vlanRange);
dvsPortSetting = createVmwareDVPortSettingSpec(shapingPolicy, secPolicy, vlanSpec);
} else if (spvlanid != null) {
// Create a pvlan spec. The pvlan spec is different from the pvlan config spec
@ -851,12 +867,57 @@ public class HypervisorHostHelper {
}
}
VmwareDistributedVirtualSwitchVlanIdSpec oldVlanSpec = (VmwareDistributedVirtualSwitchVlanIdSpec)((
VMwareDVSPortSetting)currentDvPortgroupInfo.getDefaultPortConfig()).getVlan();
VmwareDistributedVirtualSwitchVlanIdSpec newVlanSpec = (VmwareDistributedVirtualSwitchVlanIdSpec)((
VMwareDVSPortSetting)newDvPortGroupSpec.getDefaultPortConfig()).getVlan();
int oldVlanId = oldVlanSpec.getVlanId();
int newVlanId = newVlanSpec.getVlanId();
VMwareDVSPortSetting currentPortSetting = ((VMwareDVSPortSetting)currentDvPortgroupInfo.getDefaultPortConfig());
VMwareDVSPortSetting newPortSetting = ((VMwareDVSPortSetting)newDvPortGroupSpec.getDefaultPortConfig());
if ((currentPortSetting.getSecurityPolicy() == null && newPortSetting.getSecurityPolicy() != null) ||
(currentPortSetting.getSecurityPolicy() != null && newPortSetting.getSecurityPolicy() == null)) {
specMatches = false;
}
if (currentPortSetting.getSecurityPolicy() != null && newPortSetting.getSecurityPolicy() != null) {
if (currentPortSetting.getSecurityPolicy().getAllowPromiscuous() != null &&
newPortSetting.getSecurityPolicy().getAllowPromiscuous() != null &&
newPortSetting.getSecurityPolicy().getAllowPromiscuous().isValue() != null &&
!newPortSetting.getSecurityPolicy().getAllowPromiscuous().isValue().equals(currentPortSetting.getSecurityPolicy().getAllowPromiscuous().isValue())) {
specMatches = false;
}
if (currentPortSetting.getSecurityPolicy().getForgedTransmits() != null &&
newPortSetting.getSecurityPolicy().getForgedTransmits() != null &&
newPortSetting.getSecurityPolicy().getForgedTransmits().isValue() != null &&
!newPortSetting.getSecurityPolicy().getForgedTransmits().isValue().equals(currentPortSetting.getSecurityPolicy().getForgedTransmits().isValue())) {
specMatches = false;
}
if (currentPortSetting.getSecurityPolicy().getMacChanges() != null &&
newPortSetting.getSecurityPolicy().getMacChanges() != null &&
newPortSetting.getSecurityPolicy().getMacChanges().isValue() != null &&
!newPortSetting.getSecurityPolicy().getMacChanges().isValue().equals(currentPortSetting.getSecurityPolicy().getMacChanges().isValue())) {
specMatches = false;
}
}
VmwareDistributedVirtualSwitchVlanSpec oldVlanSpec = currentPortSetting.getVlan();
VmwareDistributedVirtualSwitchVlanSpec newVlanSpec = newPortSetting.getVlan();
int oldVlanId, newVlanId;
if (oldVlanSpec instanceof VmwareDistributedVirtualSwitchPvlanSpec && newVlanSpec instanceof VmwareDistributedVirtualSwitchPvlanSpec) {
VmwareDistributedVirtualSwitchPvlanSpec oldpVlanSpec = (VmwareDistributedVirtualSwitchPvlanSpec) oldVlanSpec;
VmwareDistributedVirtualSwitchPvlanSpec newpVlanSpec = (VmwareDistributedVirtualSwitchPvlanSpec) newVlanSpec;
oldVlanId = oldpVlanSpec.getPvlanId();
newVlanId = newpVlanSpec.getPvlanId();
} else if (oldVlanSpec instanceof VmwareDistributedVirtualSwitchTrunkVlanSpec && newVlanSpec instanceof VmwareDistributedVirtualSwitchTrunkVlanSpec) {
VmwareDistributedVirtualSwitchTrunkVlanSpec oldpVlanSpec = (VmwareDistributedVirtualSwitchTrunkVlanSpec) oldVlanSpec;
VmwareDistributedVirtualSwitchTrunkVlanSpec newpVlanSpec = (VmwareDistributedVirtualSwitchTrunkVlanSpec) newVlanSpec;
oldVlanId = oldpVlanSpec.getVlanId().get(0).getStart();
newVlanId = newpVlanSpec.getVlanId().get(0).getStart();
} else if (oldVlanSpec instanceof VmwareDistributedVirtualSwitchVlanIdSpec && newVlanSpec instanceof VmwareDistributedVirtualSwitchVlanIdSpec) {
VmwareDistributedVirtualSwitchVlanIdSpec oldVlanIdSpec = (VmwareDistributedVirtualSwitchVlanIdSpec) oldVlanSpec;
VmwareDistributedVirtualSwitchVlanIdSpec newVlanIdSpec = (VmwareDistributedVirtualSwitchVlanIdSpec) newVlanSpec;
oldVlanId = oldVlanIdSpec.getVlanId();
newVlanId = newVlanIdSpec.getVlanId();
} else {
s_logger.debug("Old and new vlan spec type mismatch found for [" + dvPortGroupName + "] has changed. Old spec type is: " + oldVlanSpec.getClass() + ", and new spec type is:" + newVlanSpec.getClass());
return false;
}
if (oldVlanId != newVlanId) {
s_logger.info("Detected that new VLAN [" + newVlanId + "] of dvPortGroup [" + dvPortGroupName +
"] is different from current VLAN [" + oldVlanId + "]");
@ -994,25 +1055,114 @@ public class HypervisorHostHelper {
return pvlanConfigSpec;
}
public static VmwareDistributedVirtualSwitchVlanIdSpec createDVPortVlanIdSpec(Integer vlanId) {
public static VmwareDistributedVirtualSwitchVlanSpec createDVPortVlanSpec(Integer vlanId, String vlanRange) {
if (vlanId == null && vlanRange != null && !vlanRange.isEmpty()) {
s_logger.debug("Creating dvSwitch port vlan-trunk spec with range: " + vlanRange);
VmwareDistributedVirtualSwitchTrunkVlanSpec trunkVlanSpec = new VmwareDistributedVirtualSwitchTrunkVlanSpec();
for (final String vlanRangePart : vlanRange.split(",")) {
if (vlanRangePart == null || vlanRange.isEmpty()) {
continue;
}
final NumericRange numericRange = new NumericRange();
if (vlanRangePart.contains("-")) {
final String[] range = vlanRangePart.split("-");
if (range.length == 2 && range[0] != null && range[1] != null) {
numericRange.setStart(NumbersUtil.parseInt(range[0], 0));
numericRange.setEnd(NumbersUtil.parseInt(range[1], 0));
} else {
continue;
}
} else {
numericRange.setStart(NumbersUtil.parseInt(vlanRangePart, 0));
numericRange.setEnd(NumbersUtil.parseInt(vlanRangePart, 0));
}
trunkVlanSpec.getVlanId().add(numericRange);
}
if (trunkVlanSpec.getVlanId().size() != 0) {
return trunkVlanSpec;
}
}
VmwareDistributedVirtualSwitchVlanIdSpec vlanIdSpec = new VmwareDistributedVirtualSwitchVlanIdSpec();
vlanIdSpec.setVlanId(vlanId == null ? 0 : vlanId.intValue());
vlanIdSpec.setVlanId(vlanId == null ? 0 : vlanId);
s_logger.debug("Creating dvSwitch port vlan-id spec with id: " + vlanIdSpec.getVlanId());
return vlanIdSpec;
}
public static DVSSecurityPolicy createDVSSecurityPolicy() {
public static Map<NetworkOffering.Detail, String> getDefaultSecurityDetails() {
final Map<NetworkOffering.Detail, String> details = new HashMap<>();
details.put(NetworkOffering.Detail.PromiscuousMode, NetworkOrchestrationService.PromiscuousMode.value().toString());
details.put(NetworkOffering.Detail.MacAddressChanges, NetworkOrchestrationService.MacAddressChanges.value().toString());
details.put(NetworkOffering.Detail.ForgedTransmits, NetworkOrchestrationService.ForgedTransmits.value().toString());
return details;
}
public static DVSSecurityPolicy createDVSSecurityPolicy(Map<NetworkOffering.Detail, String> nicDetails) {
DVSSecurityPolicy secPolicy = new DVSSecurityPolicy();
BoolPolicy allow = new BoolPolicy();
allow.setValue(true);
BoolPolicy deny = new BoolPolicy();
deny.setValue(false);
secPolicy.setAllowPromiscuous(deny);
secPolicy.setForgedTransmits(allow);
secPolicy.setAllowPromiscuous(allow);
secPolicy.setMacChanges(allow);
if (nicDetails == null) {
nicDetails = getDefaultSecurityDetails();
}
if (nicDetails.containsKey(NetworkOffering.Detail.PromiscuousMode)) {
if (Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.PromiscuousMode))) {
secPolicy.setAllowPromiscuous(allow);
} else {
secPolicy.setAllowPromiscuous(deny);
}
}
if (nicDetails.containsKey(NetworkOffering.Detail.ForgedTransmits)) {
if (Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.ForgedTransmits))) {
secPolicy.setForgedTransmits(allow);
} else {
secPolicy.setForgedTransmits(deny);
}
}
if (nicDetails.containsKey(NetworkOffering.Detail.MacAddressChanges)) {
if (Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.MacAddressChanges))) {
secPolicy.setMacChanges(allow);
} else {
secPolicy.setMacChanges(deny);
}
}
return secPolicy;
}
public static HostNetworkSecurityPolicy createVSSecurityPolicy(Map<NetworkOffering.Detail, String> nicDetails) {
HostNetworkSecurityPolicy secPolicy = new HostNetworkSecurityPolicy();
secPolicy.setAllowPromiscuous(Boolean.FALSE);
secPolicy.setForgedTransmits(Boolean.TRUE);
secPolicy.setMacChanges(Boolean.TRUE);
if (nicDetails == null) {
nicDetails = getDefaultSecurityDetails();
}
if (nicDetails.containsKey(NetworkOffering.Detail.PromiscuousMode)) {
secPolicy.setAllowPromiscuous(Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.PromiscuousMode)));
}
if (nicDetails.containsKey(NetworkOffering.Detail.ForgedTransmits)) {
secPolicy.setForgedTransmits(Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.ForgedTransmits)));
}
if (nicDetails.containsKey(NetworkOffering.Detail.MacAddressChanges)) {
secPolicy.setMacChanges(Boolean.valueOf(nicDetails.get(NetworkOffering.Detail.MacAddressChanges)));
}
return secPolicy;
}
public static Pair<ManagedObjectReference, String> prepareNetwork(String vSwitchName, String namePrefix, HostMO hostMo, String vlanId, Integer networkRateMbps,
Integer networkRateMulticastMbps, long timeOutMs, boolean syncPeerHosts, BroadcastDomainType broadcastDomainType, String nicUuid) throws Exception {
Integer networkRateMulticastMbps, long timeOutMs, boolean syncPeerHosts, BroadcastDomainType broadcastDomainType, String nicUuid, Map<NetworkOffering.Detail, String> nicDetails) throws Exception {
HostVirtualSwitch vSwitch;
if (vSwitchName == null) {
@ -1059,13 +1209,8 @@ public class HypervisorHostHelper {
}
}
HostNetworkSecurityPolicy secPolicy = null;
if (namePrefix.equalsIgnoreCase("cloud.private")) {
secPolicy = new HostNetworkSecurityPolicy();
secPolicy.setAllowPromiscuous(Boolean.TRUE);
secPolicy.setForgedTransmits(Boolean.TRUE);
secPolicy.setMacChanges(Boolean.TRUE);
}
HostNetworkSecurityPolicy secPolicy = createVSSecurityPolicy(nicDetails);
HostNetworkTrafficShapingPolicy shapingPolicy = null;
if (networkRateMbps != null && networkRateMbps.intValue() > 0) {
shapingPolicy = new HostNetworkTrafficShapingPolicy();
@ -1105,7 +1250,7 @@ public class HypervisorHostHelper {
bWaitPortGroupReady = false;
} else {
HostPortGroupSpec spec = hostMo.getPortGroupSpec(networkName);
if (!isSpecMatch(spec, vid, shapingPolicy)) {
if (!isSpecMatch(spec, vid, secPolicy, shapingPolicy)) {
hostMo.updatePortGroup(vSwitch, networkName, vid, secPolicy, shapingPolicy);
bWaitPortGroupReady = true;
}
@ -1149,7 +1294,7 @@ public class HypervisorHostHelper {
if (s_logger.isDebugEnabled())
s_logger.debug("Prepare network on other host, vlan: " + vlanId + ", host: " + otherHostMo.getHostName());
prepareNetwork(vSwitchName, namePrefix, otherHostMo, vlanId, networkRateMbps, networkRateMulticastMbps, timeOutMs, false,
broadcastDomainType, nicUuid);
broadcastDomainType, nicUuid, nicDetails);
} catch (Exception e) {
s_logger.warn("Unable to prepare network on other host, vlan: " + vlanId + ", host: " + otherHostMo.getHostName());
}
@ -1172,7 +1317,7 @@ public class HypervisorHostHelper {
return new Pair<ManagedObjectReference, String>(morNetwork, networkName);
}
private static boolean isSpecMatch(HostPortGroupSpec spec, Integer vlanId, HostNetworkTrafficShapingPolicy shapingPolicy) {
private static boolean isSpecMatch(HostPortGroupSpec spec, Integer vlanId, HostNetworkSecurityPolicy securityPolicy, HostNetworkTrafficShapingPolicy shapingPolicy) {
// check VLAN configuration
if (vlanId != null) {
if (vlanId.intValue() != spec.getVlanId())
@ -1182,16 +1327,36 @@ public class HypervisorHostHelper {
return false;
}
// check security policy for the portgroup
HostNetworkSecurityPolicy secPolicyInSpec = null;
if (spec.getPolicy() != null) {
secPolicyInSpec = spec.getPolicy().getSecurity();
}
if ((secPolicyInSpec != null && securityPolicy == null) || (secPolicyInSpec == null && securityPolicy != null)) {
return false;
}
if (secPolicyInSpec != null && securityPolicy != 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())))) {
return false;
}
// check traffic shaping configuration
HostNetworkTrafficShapingPolicy policyInSpec = null;
if (spec.getPolicy() != null)
if (spec.getPolicy() != null) {
policyInSpec = spec.getPolicy().getShapingPolicy();
}
if (policyInSpec != null && shapingPolicy == null || policyInSpec == null && shapingPolicy != null)
if ((policyInSpec != null && shapingPolicy == null) || (policyInSpec == null && shapingPolicy != null)) {
return false;
}
if (policyInSpec == null && shapingPolicy == null)
if (policyInSpec == null && shapingPolicy == null) {
return true;
}
// so far policyInSpec and shapingPolicy should both not be null
if (policyInSpec.isEnabled() == null || !policyInSpec.isEnabled().booleanValue())

View File

@ -16,16 +16,17 @@
// under the License.
package com.cloud.hypervisor.vmware.mo;
import com.cloud.hypervisor.vmware.util.VmwareContext;
import com.vmware.vim25.AboutInfo;
import com.vmware.vim25.BoolPolicy;
import com.vmware.vim25.DVPortgroupConfigInfo;
import com.vmware.vim25.DVPortgroupConfigSpec;
import com.vmware.vim25.DVSTrafficShapingPolicy;
import com.vmware.vim25.LongPolicy;
import com.vmware.vim25.ServiceContent;
import com.vmware.vim25.VMwareDVSPortSetting;
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@ -34,13 +35,21 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import com.cloud.hypervisor.vmware.util.VmwareContext;
import com.cloud.offering.NetworkOffering;
import com.vmware.vim25.AboutInfo;
import com.vmware.vim25.BoolPolicy;
import com.vmware.vim25.DVPortgroupConfigInfo;
import com.vmware.vim25.DVPortgroupConfigSpec;
import com.vmware.vim25.DVSSecurityPolicy;
import com.vmware.vim25.DVSTrafficShapingPolicy;
import com.vmware.vim25.HostNetworkSecurityPolicy;
import com.vmware.vim25.LongPolicy;
import com.vmware.vim25.ServiceContent;
import com.vmware.vim25.VMwareDVSPortSetting;
import com.vmware.vim25.VmwareDistributedVirtualSwitchTrunkVlanSpec;
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec;
public class HypervisorHostHelperTest {
@Mock
@ -774,4 +783,104 @@ public class HypervisorHostHelperTest {
"</Envelope>";
assertEquals(expected, HypervisorHostHelper.removeOVFNetwork(ovfString));
}
private Map<NetworkOffering.Detail, String> getSecurityDetails() {
final Map<NetworkOffering.Detail, String> details = new HashMap<>();
details.put(NetworkOffering.Detail.PromiscuousMode, "false");
details.put(NetworkOffering.Detail.ForgedTransmits, "false");
details.put(NetworkOffering.Detail.MacAddressChanges, "false");
return details;
}
@Test
public void testVSSecurityPolicyDefault() {
HostNetworkSecurityPolicy secPolicy = HypervisorHostHelper.createVSSecurityPolicy(null);
assertFalse(secPolicy.isAllowPromiscuous());
assertTrue(secPolicy.isForgedTransmits());
assertTrue(secPolicy.isMacChanges());
}
@Test
public void testVSSecurityPolicyDefaultWithDetail() {
HostNetworkSecurityPolicy secPolicy = HypervisorHostHelper.createVSSecurityPolicy(getSecurityDetails());
assertFalse(secPolicy.isAllowPromiscuous());
assertFalse(secPolicy.isForgedTransmits());
assertFalse(secPolicy.isMacChanges());
}
@Test
public void testVSSecurityPolicyWithDetail() {
Map<NetworkOffering.Detail, String> details = getSecurityDetails();
details.put(NetworkOffering.Detail.MacAddressChanges, "true");
HostNetworkSecurityPolicy secPolicy = HypervisorHostHelper.createVSSecurityPolicy(details);
assertFalse(secPolicy.isAllowPromiscuous());
assertFalse(secPolicy.isForgedTransmits());
assertTrue(secPolicy.isMacChanges());
}
@Test
public void testDVSSecurityPolicyDefault() {
DVSSecurityPolicy secPolicy = HypervisorHostHelper.createDVSSecurityPolicy(null);
assertFalse(secPolicy.getAllowPromiscuous().isValue());
assertTrue(secPolicy.getForgedTransmits().isValue());
assertTrue(secPolicy.getMacChanges().isValue());
}
@Test
public void testDVSSecurityPolicyDefaultWithDetail() {
Map<NetworkOffering.Detail, String> details = getSecurityDetails();
details.remove(NetworkOffering.Detail.ForgedTransmits);
details.remove(NetworkOffering.Detail.PromiscuousMode);
DVSSecurityPolicy secPolicy = HypervisorHostHelper.createDVSSecurityPolicy(details);
assertFalse(secPolicy.getAllowPromiscuous().isValue());
assertFalse(secPolicy.getMacChanges().isValue());
assertTrue(secPolicy.getForgedTransmits().isValue());
}
@Test
public void testDVSSecurityPolicyWithDetail() {
Map<NetworkOffering.Detail, String> details = getSecurityDetails();
details.put(NetworkOffering.Detail.ForgedTransmits, "true");
DVSSecurityPolicy secPolicy = HypervisorHostHelper.createDVSSecurityPolicy(details);
assertFalse(secPolicy.getAllowPromiscuous().isValue());
assertTrue(secPolicy.getForgedTransmits().isValue());
assertFalse(secPolicy.getMacChanges().isValue());
}
@Test
public void testCreateDVPortVlanSpecNullVlanId() {
VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(null, null);
assertTrue(spec instanceof VmwareDistributedVirtualSwitchVlanIdSpec);
assertTrue(((VmwareDistributedVirtualSwitchVlanIdSpec) spec).getVlanId() == 0);
}
@Test
public void testCreateDVPortVlanSpecValidVlanId() {
VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(100, "400");
assertTrue(spec instanceof VmwareDistributedVirtualSwitchVlanIdSpec);
assertTrue(((VmwareDistributedVirtualSwitchVlanIdSpec) spec).getVlanId() == 100);
}
@Test
public void testCreateDVPortVlanSpecValidVlanRange() {
VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(null, "200-250");
assertTrue(spec instanceof VmwareDistributedVirtualSwitchTrunkVlanSpec);
assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getStart() == 200);
assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getEnd() == 250);
}
@Test
public void testCreateDVPortVlanSpecInvalidMissingVlanRange() {
VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(null, "200-");
assertTrue(spec instanceof VmwareDistributedVirtualSwitchVlanIdSpec);
assertTrue(((VmwareDistributedVirtualSwitchVlanIdSpec) spec).getVlanId() == 0);
}
@Test
public void testCreateDVPortVlanSpecInvalidInputVlanRange() {
VmwareDistributedVirtualSwitchVlanSpec spec = HypervisorHostHelper.createDVPortVlanSpec(null, "a-b");
assertTrue(spec instanceof VmwareDistributedVirtualSwitchTrunkVlanSpec);
assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getStart() == 0);
assertTrue(((VmwareDistributedVirtualSwitchTrunkVlanSpec) spec).getVlanId().get(0).getEnd() == 0);
}
}