Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 06321200D27 for ; Wed, 25 Oct 2017 11:45:23 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 046D2160BDA; Wed, 25 Oct 2017 09:45:23 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 788251609E5 for ; Wed, 25 Oct 2017 11:45:20 +0200 (CEST) Received: (qmail 76606 invoked by uid 500); 25 Oct 2017 09:45:19 -0000 Mailing-List: contact issues-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list issues@cloudstack.apache.org Received: (qmail 76596 invoked by uid 500); 25 Oct 2017 09:45:19 -0000 Delivered-To: apmail-incubator-cloudstack-issues@incubator.apache.org Received: (qmail 76590 invoked by uid 99); 25 Oct 2017 09:45:19 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 25 Oct 2017 09:45:19 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 8D8B31A1663 for ; Wed, 25 Oct 2017 09:45:18 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -99.202 X-Spam-Level: X-Spam-Status: No, score=-99.202 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001, USER_IN_WHITELIST=-100] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id AnvuM_uzuHU4 for ; Wed, 25 Oct 2017 09:45:05 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with ESMTP id A26845FC1C for ; Wed, 25 Oct 2017 09:45:04 +0000 (UTC) Received: from jira-lw-us.apache.org (unknown [207.244.88.139]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 24156E2573 for ; Wed, 25 Oct 2017 09:45:03 +0000 (UTC) Received: from jira-lw-us.apache.org (localhost [127.0.0.1]) by jira-lw-us.apache.org (ASF Mail Server at jira-lw-us.apache.org) with ESMTP id 1F94921307 for ; Wed, 25 Oct 2017 09:45:01 +0000 (UTC) Date: Wed, 25 Oct 2017 09:45:01 +0000 (UTC) From: "ASF GitHub Bot (JIRA)" To: cloudstack-issues@incubator.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (CLOUDSTACK-10047) DVSwitch improvements MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 archived-at: Wed, 25 Oct 2017 09:45:23 -0000 [ https://issues.apache.org/jira/browse/CLOUDSTACK-10047?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16218310#comment-16218310 ] ASF GitHub Bot commented on CLOUDSTACK-10047: --------------------------------------------- rhtyd closed pull request #2293: CLOUDSTACK-10047: DVSwitch fixes and improvements URL: https://github.com/apache/cloudstack/pull/2293 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java index bd681f282cd..3863e1bafe7 100644 --- a/api/src/com/cloud/agent/api/to/NicTO.java +++ b/api/src/com/cloud/agent/api/to/NicTO.java @@ -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 @@ boolean pxeDisable; String nicUuid; List nicSecIps; + Map details; public NicTO() { super(); @@ -97,4 +101,12 @@ public String getNetworkUuid() { public void setNetworkUuid(String uuid) { super.setUuid(uuid); } + + public Map getDetails() { + return details; + } + + public void setDetails(final Map details) { + this.details = details; + } } diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index f027cf9fe99..37746f0d0f7 100644 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -75,6 +75,10 @@ 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 diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 59045dccd97..402846202e7 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -38,7 +38,7 @@ } public enum Detail { - InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription + InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits } public final static String SystemPublicNetwork = "System-Public-Network"; diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 582ead6693d..1ec340df1e8 100644 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -38,6 +38,7 @@ 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"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java index 6cf9e2308dc..6d346e9a4db 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java @@ -40,6 +40,9 @@ @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 String getVlan() { return vlan; } + public Boolean getBypassVlanOverlapCheck() { + if (bypassVlanOverlapCheck != null) { + return bypassVlanOverlapCheck; + } + return false; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index d1a34185eed..259c4905ed1 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -113,7 +113,8 @@ 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, diff --git a/api/test/com/cloud/network/NetworksTest.java b/api/test/com/cloud/network/NetworksTest.java index c9102d3a02a..ef582924342 100644 --- a/api/test/com/cloud/network/NetworksTest.java +++ b/api/test/com/cloud/network/NetworksTest.java @@ -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 @@ -44,6 +44,13 @@ public void emptyBroadcastDomainTypeTest() throws URISyntaxException { } @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"; Long value2 = 2L; diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java index 68531e3ab3d..8a7a516f3d7 100644 --- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java +++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java @@ -77,6 +77,15 @@ ConfigKey NetworkThrottlingRate = new ConfigKey("Network", Integer.class, NetworkThrottlingRateCK, "200", "Default data transfer rate in megabits per second allowed in network.", true, ConfigKey.Scope.Zone); + ConfigKey PromiscuousMode = new ConfigKey("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 MacAddressChanges = new ConfigKey("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 ForgedTransmits = new ConfigKey("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 setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault) throws ConcurrentOperationException; @@ -136,9 +145,9 @@ void prepare(VirtualMachineProfile profile, DeployDestination dest, ReservationC 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, - Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr, - Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; + 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; UserDataServiceProvider getPasswordResetProvider(Network network); diff --git a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java b/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java index 46be654f581..eee159523cb 100644 --- a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java +++ b/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java @@ -214,7 +214,7 @@ NetworkOfferingVO createNetworkOffering(String name, String displayText, Traffic Map 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; diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 3956617859c..755fba2f74c 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -32,18 +32,10 @@ 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.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.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.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.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.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 void expungeNics(final VirtualMachineProfile vm) { @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 Network createGuestNetwork(final long networkOfferingId, final String nam } 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 dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString()); + final List 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 Network createGuestNetwork(final long networkOfferingId, final String nam } 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 String getConfigComponentName() { @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}; } } diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java index 1783231f4fb..556ab451391 100644 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java @@ -27,10 +27,10 @@ public List listAllocatedVnetsInRange(long dcId, long physicalNetworkId, Integer start, Integer end); - public List findVnet(long dcId, String vnet); - public int countZoneVlans(long dcId, boolean onlyCountAllocated); + public List findVnet(long dcId, String vnet); + public List findVnet(long dcId, long physicalNetworkId, String vnet); public void add(long dcId, long physicalNetworkId, List vnets); diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java index 3205fcd6af6..1c29e6a944c 100644 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java @@ -18,6 +18,7 @@ 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 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; @@ -100,29 +103,43 @@ public void lockRange(long dcId, long physicalNetworkId, Integer start, Integer } @Override - public List findVnet(long dcId, String vnet) { - SearchCriteria sc = VnetDcSearch.create(); - ; - sc.setParameters("dc", dcId); - sc.setParameters("vnet", vnet); - return listBy(sc); - } - - @Override public int countZoneVlans(long dcId, boolean onlyCountAllocated) { SearchCriteria sc = onlyCountAllocated ? countAllocatedZoneVlans.create() : countZoneVlans.create(); sc.setParameters("dc", dcId); return customSearch(sc, null).get(0); } - @Override - public List findVnet(long dcId, long physicalNetworkId, String vnet) { + private List findOverlappingVnets(final long dcId, final Long physicalNetworkId, final String vnet) { + final List searchVnets = UriUtils.expandVlanUri(vnet); + final List overlappingVnets = new ArrayList<>(); + if (searchVnets == null || searchVnets.isEmpty()) { + return overlappingVnets; + } SearchCriteria sc = VnetDcSearch.create(); sc.setParameters("dc", dcId); - sc.setParameters("physicalNetworkId", physicalNetworkId); - sc.setParameters("vnet", vnet); + if (physicalNetworkId != null) { + sc.setParameters("physicalNetworkId", physicalNetworkId); + } + 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 findVnet(long dcId, String vnet) { + return findOverlappingVnets(dcId, null, vnet); + } + + @Override + public List findVnet(long dcId, long physicalNetworkId, String vnet) { + return findOverlappingVnets(dcId, physicalNetworkId, vnet); } @Override diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDao.java b/engine/schema/src/com/cloud/network/dao/NetworkDao.java index 85544e78901..5091ebd75df 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkDao.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkDao.java @@ -61,9 +61,7 @@ List listBy(long accountId, long networkId); - long countByZoneAndUri(long zoneId, String broadcastUri); - - long countByZoneUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType); + List listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType); List listByZone(long zoneId); diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java index 49a5944f838..11444b0d008 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -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.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.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 @@ GenericSearchBuilder NetworksRegularUserCanCreateSearch; GenericSearchBuilder NetworksCount; SearchBuilder SourceNATSearch; - GenericSearchBuilder CountByZoneAndURI; GenericSearchBuilder VpcNetworksCount; SearchBuilder OfferingAccountNetworkSearch; @@ -152,14 +153,6 @@ protected void init() { 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 offJoin = _ntwkSvcMap.createSearchBuilder(); @@ -399,13 +392,35 @@ public String getNextAvailableMacAddress(final long networkConfigId, Integer zon } @Override - public long countByZoneAndUri(final long zoneId, final String broadcastUri) { + public List listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) { + final URI searchUri = BroadcastDomainType.fromString(broadcastUri); + final String searchRange = BroadcastDomainType.getValue(searchUri); + final List searchVlans = UriUtils.expandVlanUri(searchRange); + final List overlappingNetworks = new ArrayList<>(); - final SearchCriteria sc = CountByZoneAndURI.create(); + final SearchCriteria 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 @@ -416,15 +431,6 @@ public long countByZoneAndUri(final long zoneId, final String broadcastUri) { } @Override - public long countByZoneUriAndGuestType(final long zoneId, final String broadcastUri, final GuestType guestType) { - final SearchCriteria sc = CountByZoneAndURI.create(); - sc.setParameters("dataCenterId", zoneId); - sc.setParameters("broadcastUri", broadcastUri); - sc.setParameters("guestType", guestType); - return customSearch(sc, null).get(0); - } - - @Override public List listByZoneSecurityGroup(final Long zoneId) { final SearchCriteria sc = ZoneSecurityGroupSearch.create(); if (zoneId != null) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 53e3239113e..b7149ab2bf9 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -392,11 +392,11 @@ private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Excep 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); } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 17064ff0d1e..9d32f3424de 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1178,11 +1178,11 @@ private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final Str 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 @@ private String getVlanInfo(NicTO nicTo, String defaultVlan) { 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 @@ private String getVlanInfo(NicTO nicTo, String defaultVlan) { } 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; diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 3d2c236c39c..4dd52632338 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -199,6 +199,7 @@ 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 Vlan doInTransaction(final TransactionStatus status) { 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 boolean hasSameSubnet(boolean ipv4, String vlanGateway, String vlanNetmas @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,8 +3078,10 @@ public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final String[] vlan = uri.toString().split("vlan:\\/\\/"); networkVlanId = vlan[1]; // For pvlan - networkVlanId = networkVlanId.split("-")[0]; - } + if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) { + networkVlanId = networkVlanId.split("-")[0]; + } + } } if (vlanId != null && !connectivityWithoutVlan) { @@ -3168,7 +3171,9 @@ public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, 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 Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, } // 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()); } diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index d84c104f76b..0bf1c705759 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -22,6 +22,7 @@ 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.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.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 @@ @Inject private NetworkDao _networkDao; @Inject + private NetworkOfferingDetailsDao networkOfferingDetailsDao; + @Inject private VMInstanceDao _virtualMachineDao; @Inject private UserVmDetailsDao _userVmDetailsDao; @@ -138,7 +143,18 @@ protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) { 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 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); diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index 9056ed5cdfc..e34f90861c3 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -1631,7 +1631,7 @@ public boolean associateIpAddressListToAccount(long userId, final long accountId 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 " diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 36dd53fe33e..966c0e4475b 100644 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -1038,9 +1038,14 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac 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 Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac } // 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 Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac 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,10 +1356,10 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac } 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 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 { + 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 { try { Network network = Transaction.execute(new TransactionCallbackWithException() { @Override @@ -1408,14 +1413,14 @@ public Network doInTransaction(TransactionStatus status) throws InsufficientCapa 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 Network doInTransaction(TransactionStatus status) throws ResourceAllocati 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); diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 706f4c4abff..9f5ff834c06 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -2359,7 +2359,7 @@ public Network createVpcGuestNetwork(final long ntwkOffId, final String name, fi 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) { diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index e4fc56fe6af..07dd0ea8466 100644 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3103,7 +3103,7 @@ public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serv } 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 void doInTransactionWithoutResult(TransactionStatus status) { 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()) { diff --git a/server/test/com/cloud/network/CreatePrivateNetworkTest.java b/server/test/com/cloud/network/CreatePrivateNetworkTest.java index 8a7b54cb20f..178ed84d748 100644 --- a/server/test/com/cloud/network/CreatePrivateNetworkTest.java +++ b/server/test/com/cloud/network/CreatePrivateNetworkTest.java @@ -121,7 +121,7 @@ public void setup() throws Exception { 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); diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java index bcee896ca30..9ac0648a533 100644 --- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java +++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java @@ -440,7 +440,7 @@ public NetworkOfferingVO createNetworkOffering(String name, String displayText, */ @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; diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index f6f818d1733..9b895c25541 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -611,9 +611,9 @@ public boolean destroyNetwork(long networkId, ReservationContext context, boolea * @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, - 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, + 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, ResourceAllocationException { // TODO Auto-generated method stub return null; diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java index 4c4a0a19026..11f3f81f357 100644 --- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java +++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java @@ -85,13 +85,8 @@ public String getNextAvailableMacAddress(final long networkConfigId, Integer zon } @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 listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) { + return null; } @Override diff --git a/ui/l10n/en.js b/ui/l10n/en.js index 16e0b8894ef..3727dc6a313 100644 --- a/ui/l10n/en.js +++ b/ui/l10n/en.js @@ -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", diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 8fb7ebefb7a..6c3ffd81687 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -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(', '), diff --git a/utils/src/main/java/com/cloud/utils/UriUtils.java b/utils/src/main/java/com/cloud/utils/UriUtils.java index 631c629aed3..8805891cd2a 100644 --- a/utils/src/main/java/com/cloud/utils/UriUtils.java +++ b/utils/src/main/java/com/cloud/utils/UriUtils.java @@ -30,6 +30,7 @@ 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 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 static InputStream getInputStreamFromUrl(String url, String user, String 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 expandVlanUri(final String vlanAuthority) { + final List 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 vlans1 = expandVlanUri(vlanRange1); + final List vlans2 = expandVlanUri(vlanRange2); + if (vlans1 == null || vlans2 == null) { + return true; + } + return !Collections.disjoint(vlans1, vlans2); + } } diff --git a/utils/src/test/java/com/cloud/utils/UriUtilsTest.java b/utils/src/test/java/com/cloud/utils/UriUtilsTest.java index d2fd9976558..b8d951db340 100644 --- a/utils/src/test/java/com/cloud/utils/UriUtilsTest.java +++ b/utils/src/test/java/com/cloud/utils/UriUtilsTest.java @@ -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 void getUpdateUri() { //XXX: Interesting cases not covered: // * port is ignored and left out from the return value } + + @Test + public void expandVlanEmpty() { + List vlans = UriUtils.expandVlanUri(""); + Assert.assertTrue(vlans.size() == 0); + } + + @Test + public void expandVlanSingleValue() { + List vlans = UriUtils.expandVlanUri("10"); + Assert.assertTrue(vlans.size() == 1); + Assert.assertEquals(vlans, Collections.singletonList(10)); + } + + @Test + public void expandVlanValidRange() { + List 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 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")); + } } diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index 44681e9a8b3..01cfb3a52f1 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -43,6 +43,11 @@ ${project.version} + org.apache.cloudstack + cloud-engine-api + ${project.version} + + com.google.code.gson gson diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java index ef3f0ae327c..bece91a98f5 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -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.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.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 static void updatePortProfile(VmwareContext context, String ethPortProfil * @param timeOutMs * @param vSwitchType * @param numPorts + * @param details * @return * @throws Exception */ public static Pair 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 vsmCredentials) throws Exception { + Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs, VirtualSwitchType vSwitchType, int numPorts, String gateway, + boolean configureVServiceInNexus, BroadcastDomainType broadcastDomainType, Map vsmCredentials, Map details) throws Exception { ManagedObjectReference morNetwork = null; VmwareContext context = hostMo.getContext(); ManagedObjectReference dcMor = hostMo.getHyperHostDatacenter(); @@ -501,12 +511,18 @@ public static void updatePortProfile(VmwareContext context, String ethPortProfil // 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 static void updatePortProfile(VmwareContext context, String ethPortProfil 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 of @@ -562,7 +578,7 @@ public static void updatePortProfile(VmwareContext context, String ethPortProfil 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,8 +715,8 @@ private static void setupPVlanPair(DistributedVirtualSwitchMO dvSwitchMo, Manage } - private static void createPortGroup(String physicalNetwork, String networkName, Integer vid, Integer spvlanid, DatacenterMO dataCenterMo, - DVSTrafficShapingPolicy shapingPolicy, DVSSecurityPolicy secPolicy, VMwareDVSPortgroupPolicy portGroupPolicy, DistributedVirtualSwitchMO dvSwitchMo, int numPorts, boolean autoExpandSupported) + 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; VmwareDistributedVirtualSwitchPvlanSpec pvlanSpec = null; @@ -710,7 +726,7 @@ private static void createPortGroup(String physicalNetwork, String networkName, // 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 static boolean isSpecMatch(DVPortgroupConfigInfo currentDvPortgroupInfo, } } - 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 static VMwareDVSPvlanConfigSpec createDVPortPvlanConfigSpec(int vlanId, i 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 getDefaultSecurityDetails() { + final Map 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 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 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 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 nicDetails) throws Exception { HostVirtualSwitch vSwitch; if (vSwitchName == null) { @@ -1059,13 +1209,8 @@ public static DVSSecurityPolicy createDVSSecurityPolicy() { } } - 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 static DVSSecurityPolicy createDVSSecurityPolicy() { 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 static DVSSecurityPolicy createDVSSecurityPolicy() { 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 static DVSSecurityPolicy createDVSSecurityPolicy() { return new Pair(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 @@ private static boolean isSpecMatch(HostPortGroupSpec spec, Integer vlanId, HostN 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()) diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java b/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java index 2fc9995091b..545104d91fc 100644 --- a/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java +++ b/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java @@ -16,31 +16,40 @@ // under the License. package com.cloud.hypervisor.vmware.mo; +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; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + 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 org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -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.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec; public class HypervisorHostHelperTest { @Mock @@ -774,4 +783,104 @@ public void testOvfDomRewriter() { ""; assertEquals(expected, HypervisorHostHelper.removeOVFNetwork(ovfString)); } + + private Map getSecurityDetails() { + final Map 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 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 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 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); + } } ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: users@infra.apache.org > DVSwitch improvements > --------------------- > > Key: CLOUDSTACK-10047 > URL: https://issues.apache.org/jira/browse/CLOUDSTACK-10047 > Project: CloudStack > Issue Type: Bug > Security Level: Public(Anyone can view this level - this is the default.) > Reporter: Rohit Yadav > Assignee: Rohit Yadav > Fix For: Future, 4.11.0.0 > > > All vlan trunking and list of vlan id/range, along with security policy settings on dvswitches. -- This message was sent by Atlassian JIRA (v6.4.14#64029)