rhtyd closed pull request #2281: CLOUDSTACK-10102: New network type (L2)
URL: https://github.com/apache/cloudstack/pull/2281
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/network/Network.java
b/api/src/com/cloud/network/Network.java
index a02c8cfdbe2..95833d86b63 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -38,7 +38,7 @@
public interface Network extends ControlledEntity, StateObject<Network.State>,
InternalIdentity, Identity, Serializable, Displayable {
public enum GuestType {
- Shared, Isolated
+ Shared, Isolated, L2
}
public String updatingInSequence ="updatingInSequence";
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 1ddff84f991..2d30cedcb8d 100644
---
a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++
b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -2207,8 +2207,8 @@ public Network createGuestNetwork(final long
networkOfferingId, final String nam
+ zone.getName());
}
if (! UuidUtils.validateUUID(vlanId)){
- // For Isolated networks, don't allow to create network with
vlan that already exists in the zone
- if (ntwkOff.getGuestType() == GuestType.Isolated) {
+ // For Isolated and L2 networks, don't allow to create network
with vlan that already exists in the zone
+ if (ntwkOff.getGuestType() == GuestType.Isolated ||
ntwkOff.getGuestType() == GuestType.L2) {
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 {
@@ -2289,8 +2289,9 @@ public Network createGuestNetwork(final long
networkOfferingId, final String nam
// with different Cidrs for the same Shared network
final boolean cidrRequired = zone.getNetworkType() ==
NetworkType.Advanced
&& ntwkOff.getTrafficType() == TrafficType.Guest
- && (ntwkOff.getGuestType() == GuestType.Shared ||
ntwkOff.getGuestType() == GuestType.Isolated &&
!_networkModel.areServicesSupportedByNetworkOffering(
- ntwkOff.getId(), Service.SourceNat));
+ && (ntwkOff.getGuestType() == GuestType.Shared ||
(ntwkOff.getGuestType() == GuestType.Isolated
+ &&
!_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(),
Service.SourceNat))
+ || ntwkOff.getGuestType() == GuestType.L2 &&
!_networkModel.listNetworkOfferingServices(ntwkOff.getId()).isEmpty());
if (cidr == null && ip6Cidr == null && cidrRequired) {
throw new
InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when
create network of" + " type " + Network.GuestType.Shared
+ " and network of type " + GuestType.Isolated + " with
service " + Service.SourceNat.getName() + " disabled");
@@ -2560,7 +2561,6 @@ public boolean destroyNetwork(final long networkId, final
ReservationContext con
s_logger.debug("Unable to find network with id: " + networkId);
return false;
}
-
// Make sure that there are no user vms in the network that are not
Expunged/Error
final List<UserVmVO> userVms =
_userVmDao.listByNetworkIdAndStates(networkId);
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
index b1ff7060ba1..d13234d1016 100644
--- a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
+++ b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
@@ -29,6 +29,9 @@
import javax.annotation.PostConstruct;
import javax.inject.Inject;
+import com.cloud.network.Network;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
import org.apache.log4j.Logger;
import com.cloud.server.ResourceTag.ResourceObjectType;
@@ -77,6 +80,8 @@
// ResourceTagsDaoImpl _tagsDao =
ComponentLocator.inject(ResourceTagsDaoImpl.class);
@Inject
ResourceTagDao _tagsDao;
+ @Inject
+ NetworkDao networkDao;
private static final String LIST_PODS_HAVING_VMS_FOR_ACCOUNT =
"SELECT pod_id FROM cloud.vm_instance WHERE data_center_id = ? AND
account_id = ? AND pod_id IS NOT NULL AND (state = 'Running' OR state =
'Stopped') "
@@ -299,21 +304,32 @@ public void updateVM(long id, String displayName, boolean
enable, Long osTypeId,
return listBy(sc);
}
- @Override
- public List<UserVmVO> listByNetworkIdAndStates(long networkId, State...
states) {
- if (UserVmSearch == null) {
+ /**
+ * Recreates UserVmSearch depending on network type, as nics on L2
networks have no ip addresses
+ * @param network network
+ */
+ private void recreateUserVmSeach(NetworkVO network) {
+ if (network != null) {
SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
nicSearch.and("networkId", nicSearch.entity().getNetworkId(),
SearchCriteria.Op.EQ);
nicSearch.and("removed", nicSearch.entity().getRemoved(),
SearchCriteria.Op.NULL);
- nicSearch.and().op("ip4Address",
nicSearch.entity().getIPv4Address(), SearchCriteria.Op.NNULL);
- nicSearch.or("ip6Address", nicSearch.entity().getIPv6Address(),
SearchCriteria.Op.NNULL);
- nicSearch.cp();
+ if (!Network.GuestType.L2.equals(network.getGuestType())) {
+ nicSearch.and().op("ip4Address",
nicSearch.entity().getIPv4Address(), SearchCriteria.Op.NNULL);
+ nicSearch.or("ip6Address",
nicSearch.entity().getIPv6Address(), SearchCriteria.Op.NNULL);
+ nicSearch.cp();
+ }
UserVmSearch = createSearchBuilder();
UserVmSearch.and("states", UserVmSearch.entity().getState(),
SearchCriteria.Op.IN);
UserVmSearch.join("nicSearch", nicSearch,
UserVmSearch.entity().getId(), nicSearch.entity().getInstanceId(),
JoinBuilder.JoinType.INNER);
UserVmSearch.done();
}
+ }
+
+ @Override
+ public List<UserVmVO> listByNetworkIdAndStates(long networkId, State...
states) {
+ NetworkVO network = networkDao.findById(networkId);
+ recreateUserVmSeach(network);
SearchCriteria<UserVmVO> sc = UserVmSearch.create();
if (states != null && states.length != 0) {
diff --git
a/plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java
b/plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java
index bf30bd01fcd..b73ddabae19 100644
---
a/plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java
+++
b/plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java
@@ -107,6 +107,7 @@ public void setUp() {
guru._ntwkOfferingSrvcDao = nosd;
guru._dcDao = dcdao;
guru._agentMgr = agentmgr;
+ ((GuestNetworkGuru)guru)._networkModel = netmodel;
final DataCenterVO dc = mock(DataCenterVO.class);
when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
@@ -163,6 +164,8 @@ public void testDesign() {
when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID,
Service.Connectivity)).thenReturn(true);
+
when(netmodel.listNetworkOfferingServices(NETWORK_ID)).thenReturn(Arrays.asList(Service.Connectivity));
+
final DeploymentPlan plan = mock(DeploymentPlan.class);
final Network network = mock(Network.class);
final Account account = mock(Account.class);
diff --git
a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java
b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java
index f1737c1bf08..3d52f8415f8 100644
---
a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java
+++
b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java
@@ -94,7 +94,7 @@ public void setUp() {
guru.niciraNvpDao = nvpdao;
guru._dcDao = dcdao;
guru.ntwkOfferingSrvcDao = nosd;
- guru.networkModel = netmodel;
+ ((GuestNetworkGuru)guru)._networkModel = netmodel;
guru.hostDao = hostdao;
guru.agentMgr = agentmgr;
guru.networkDao = netdao;
@@ -162,6 +162,8 @@ public void testDesign() {
when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID,
Service.Connectivity)).thenReturn(true);
+
when(netmodel.listNetworkOfferingServices(NETWORK_ID)).thenReturn(Arrays.asList(Service.Connectivity));
+
final DeploymentPlan plan = mock(DeploymentPlan.class);
final Network network = mock(Network.class);
final Account account = mock(Account.class);
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java
b/server/src/com/cloud/api/ApiResponseHelper.java
index 3325be1069c..e755679a355 100644
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2005,7 +2005,9 @@ public NetworkResponse createNetworkResponse(ResponseView
view, Network network)
// FIXME - either set netmask or cidr
response.setCidr(network.getCidr());
- response.setNetworkCidr((network.getNetworkCidr()));
+ if (network.getNetworkCidr() != null) {
+ response.setNetworkCidr((network.getNetworkCidr()));
+ }
// If network has reservation its entire network cidr is defined by
// getNetworkCidr()
// if no reservation is present then getCidr() will define the entire
diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java
b/server/src/com/cloud/network/IpAddressManagerImpl.java
index e34f90861c3..f0b5ee5cfe1 100644
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@ -797,7 +797,6 @@ public IPAddressVO doInTransaction(TransactionStatus
status) throws Insufficient
throw new AccountLimitException("Maximum number of
public IP addresses for account: " + owner.getAccountName() + " has been
exceeded.");
}
}
-
IPAddressVO addr = addrs.get(0);
addr.setSourceNat(sourceNat);
addr.setAllocatedTime(new Date());
@@ -1314,12 +1313,20 @@ public IPAddressVO associateIPToGuestNetwork(long ipId,
long networkId, boolean
if (zone.getNetworkType() == NetworkType.Advanced) {
// In Advance zone allow to do IP assoc only for Isolated networks
with source nat service enabled
if (network.getGuestType() == GuestType.Isolated &&
!(_networkModel.areServicesSupportedInNetwork(network.getId(),
Service.SourceNat))) {
+ if (releaseOnFailure && ipToAssoc != null) {
+ s_logger.warn("Failed to associate ip address, so
unassigning ip from the database " + ipToAssoc);
+ _ipAddressDao.unassignIpAddress(ipToAssoc.getId());
+ }
throw new InvalidParameterValueException("In zone of type " +
NetworkType.Advanced + " ip address can be associated only to the network of
guest type "
+ GuestType.Isolated + " with the " +
Service.SourceNat.getName() + " enabled");
}
// In Advance zone allow to do IP assoc only for shared networks
with source nat/static nat/lb/pf services enabled
if (network.getGuestType() == GuestType.Shared &&
!isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
+ if (releaseOnFailure && ipToAssoc != null) {
+ s_logger.warn("Failed to associate ip address, so
unassigning ip from the database " + ipToAssoc);
+ _ipAddressDao.unassignIpAddress(ipToAssoc.getId());
+ }
throw new InvalidParameterValueException("In zone of type " +
NetworkType.Advanced + " ip address can be associated with network of guest
type " + GuestType.Shared
+ "only if at " + "least one of the services " +
Service.SourceNat.getName() + "/" + Service.StaticNat.getName() + "/" +
Service.Lb.getName() + "/"
+ Service.PortForwarding.getName() + " is enabled");
@@ -1763,6 +1770,10 @@ public String acquireGuestIpAddress(Network network,
String requestedIp) {
return null;
}
+ if
(_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()
&& network.getCidr() == null) {
+ return null;
+ }
+
Set<Long> availableIps = _networkModel.getAvailableIps(network,
requestedIp);
if (availableIps == null || availableIps.isEmpty()) {
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java
b/server/src/com/cloud/network/NetworkModelImpl.java
index 2efec9a0999..9330da175b3 100644
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -29,6 +29,7 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import java.util.Collections;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
@@ -583,6 +584,9 @@ public boolean canUseForDeploy(Network network) {
if (network.getTrafficType() != TrafficType.Guest) {
return false;
}
+ if
(listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()) {
+ return true; // do not check free IPs if there is no service in
the network
+ }
boolean hasFreeIps = true;
if (network.getGuestType() == GuestType.Shared) {
if (network.getGateway() != null) {
@@ -1823,6 +1827,9 @@ public boolean isNetworkAvailableInDomain(long networkId,
long domainId) {
@Override
public Set<Long> getAvailableIps(Network network, String requestedIp) {
+ if (network.getCidr() == null) {
+ return Collections.emptySet();
+ }
String[] cidr = network.getCidr().split("/");
List<String> ips = getUsedIpsInNetwork(network);
Set<Long> usedIps = new TreeSet<Long>();
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java
b/server/src/com/cloud/network/NetworkServiceImpl.java
index 966c0e4475b..7669fd340b5 100644
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -1124,7 +1124,7 @@ public Network createGuestNetwork(CreateNetworkCmd cmd)
throws InsufficientCapac
}
}
} else {
- if (ntwkOff.getGuestType() == GuestType.Isolated) {
+ if (ntwkOff.getGuestType() == GuestType.Isolated ||
ntwkOff.getGuestType() == GuestType.L2) {
aclType = ACLType.Account;
} else if (ntwkOff.getGuestType() == GuestType.Shared) {
aclType = ACLType.Domain;
@@ -1861,9 +1861,9 @@ public boolean deleteNetwork(long networkId, boolean
forced) {
Account owner = _accountMgr.getAccount(network.getAccountId());
- // Only Admin can delete Shared networks
- if (network.getGuestType() == GuestType.Shared &&
!_accountMgr.isAdmin(caller.getId())) {
- throw new InvalidParameterValueException("Only Admins can delete
network with guest type " + GuestType.Shared);
+ // Only Admin can delete Shared and L2 networks
+ if ((network.getGuestType() == GuestType.Shared ||
network.getGuestType() == GuestType.L2) &&
!_accountMgr.isAdmin(caller.getId())) {
+ throw new InvalidParameterValueException("Only Admins can delete
network with guest type " + network.getGuestType());
}
// Perform permission check
diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
index a6bc4f0d97e..6908a105fe7 100644
--- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
@@ -91,8 +91,9 @@ public ExternalGuestNetworkGuru() {
protected boolean canHandle(NetworkOffering offering, final NetworkType
networkType, final PhysicalNetwork physicalNetwork) {
// This guru handles only Guest Isolated network that supports Source
// nat service
- if (networkType == NetworkType.Advanced &&
isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() ==
Network.GuestType.Isolated &&
- isMyIsolationMethod(physicalNetwork) && !offering.isSystemOnly()) {
+ if (networkType == NetworkType.Advanced &&
isMyTrafficType(offering.getTrafficType())
+ && (offering.getGuestType() == Network.GuestType.Isolated ||
offering.getGuestType() == GuestType.L2)
+ && isMyIsolationMethod(physicalNetwork) &&
!offering.isSystemOnly()) {
return true;
} else {
s_logger.trace("We only take care of Guest networks of type " +
GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
@@ -295,12 +296,14 @@ public void reserve(NicProfile nic, Network config,
VirtualMachineProfile vm, De
nic.setIPv4Gateway(config.getGateway());
if (nic.getIPv4Address() == null) {
- String guestIp = _ipAddrMgr.acquireGuestIpAddress(config,
null);
- if (guestIp == null) {
- throw new
InsufficientVirtualNetworkCapacityException("Unable to acquire guest IP address
for network " + config, DataCenter.class, dc.getId());
- }
+ if
(!_networkModel.listNetworkOfferingServices(config.getNetworkOfferingId()).isEmpty())
{
+ String guestIp = _ipAddrMgr.acquireGuestIpAddress(config,
null);
+ if (guestIp == null) {
+ throw new
InsufficientVirtualNetworkCapacityException("Unable to acquire guest IP address
for network " + config, DataCenter.class, dc.getId());
+ }
- nic.setIPv4Address(guestIp);
+ nic.setIPv4Address(guestIp);
+ }
} else {
long ipMask = NetUtils.ip2Long(nic.getIPv4Address()) &
~(0xffffffffffffffffl << (32 - cidrSize));
nic.setIPv4Address(NetUtils.long2Ip(cidrAddress | ipMask));
diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java
b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
index 74d774065c1..c7e6aca22b8 100644
--- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
@@ -22,6 +22,7 @@
import javax.inject.Inject;
+import com.cloud.network.Network.GuestType;
import org.apache.cloudstack.context.CallContext;
import
org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.ConfigKey;
@@ -199,7 +200,7 @@ public Network design(final NetworkOffering offering, final
DeploymentPlan plan,
if (userSpecified.getCidr() != null) {
network.setCidr(userSpecified.getCidr());
network.setGateway(userSpecified.getGateway());
- } else {
+ } else if (offering.getGuestType() == GuestType.Shared ||
!_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty()) {
final String guestNetworkCidr = dc.getGuestNetworkCidr();
if (guestNetworkCidr != null) {
final String[] cidrTuple = guestNetworkCidr.split("\\/");
@@ -369,14 +370,16 @@ public NicProfile allocate(final Network network,
NicProfile nic, final VirtualM
guestIp = network.getGateway();
} else {
guestIp = _ipAddrMgr.acquireGuestIpAddress(network,
nic.getRequestedIPv4());
- if (guestIp == null) {
+ if (guestIp == null &&
!_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty())
{
throw new
InsufficientVirtualNetworkCapacityException("Unable to acquire Guest IP" + "
address for network " + network, DataCenter.class,
dc.getId());
}
}
nic.setIPv4Address(guestIp);
-
nic.setIPv4Netmask(NetUtils.cidr2Netmask(_networkModel.getValidNetworkCidr(network)));
+ if (network.getCidr() != null) {
+
nic.setIPv4Netmask(NetUtils.cidr2Netmask(_networkModel.getValidNetworkCidr(network)));
+ }
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
diff --git a/test/integration/smoke/test_network.py
b/test/integration/smoke/test_network.py
index bb1e14b5d14..db939cf0d15 100644
--- a/test/integration/smoke/test_network.py
+++ b/test/integration/smoke/test_network.py
@@ -1271,3 +1271,225 @@ def test_network_rules_acquired_public_ip(self, value):
delay=0
)
return
+
+class TestL2Networks(cloudstackTestCase):
+
+ def setUp(self):
+ self.apiclient = self.testClient.getApiClient()
+ self.services["network"]["networkoffering"] = self.network_offering.id
+
+ self.l2_network = Network.create(
+ self.apiclient,
+ self.services["l2-network"],
+ zoneid=self.zone.id,
+ networkofferingid=self.network_offering.id
+ )
+ self.cleanup = [
+ self.l2_network]
+
+ def tearDown(self):
+ cleanup_resources(self.apiclient, self.cleanup)
+ return
+
+ @classmethod
+ def setUpClass(cls):
+ testClient = super(TestL2Networks, cls).getClsTestClient()
+ cls.apiclient = testClient.getApiClient()
+ cls.services = testClient.getParsedTestDataConfig()
+
+ # Get Zone, Domain and templates
+ cls.domain = get_domain(cls.apiclient)
+ cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
+ cls.services['mode'] = cls.zone.networktype
+ # Create Accounts & networks
+ cls.account = Account.create(
+ cls.apiclient,
+ cls.services["account"],
+ admin=True,
+ domainid=cls.domain.id
+ )
+ cls.template = get_template(
+ cls.apiclient,
+ cls.zone.id,
+ cls.services["ostype"]
+ )
+ cls.service_offering = ServiceOffering.create(
+ cls.apiclient,
+ cls.services["service_offerings"]["tiny"]
+ )
+ cls.services["network"]["zoneid"] = cls.zone.id
+
+ cls.network_offering = NetworkOffering.create(
+ cls.apiclient,
+ cls.services["l2-network_offering"],
+ )
+ # Enable Network offering
+ cls.network_offering.update(cls.apiclient, state='Enabled')
+
+ cls._cleanup = [
+ cls.account,
+ cls.network_offering,
+ cls.service_offering
+ ]
+ return
+
+ @classmethod
+ def tearDownClass(cls):
+ try:
+ # Cleanup resources used
+ cleanup_resources(cls.apiclient, cls._cleanup)
+ except Exception as e:
+ raise Exception("Warning: Exception during cleanup : %s" % e)
+ return
+
+ @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="false")
+ def test_deploy_vm_l2network(self):
+ """Creates an l2 network and verifies user is able to deploy a VM in
it"""
+
+ # Validate the following:
+ # 1. Deploys a VM
+ # 2. There are no network services available since this is L2 Network
+
+ self.virtual_machine = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ templateid=self.template.id,
+ serviceofferingid=self.service_offering.id,
+ networkids=self.l2_network.id,
+ zoneid=self.zone.id
+ )
+
+ self.cleanup.insert(0, self.virtual_machine)
+
+ list_vm = list_virtual_machines(
+ self.apiclient,
+ id = self.virtual_machine.id
+ )
+ self.assertEqual(
+ isinstance(list_vm, list),
+ True,
+ "Check if virtual machine is present"
+ )
+
+ self.assertEqual(
+ list_vm[0].nic[0].type,
+ 'L2',
+ "Check Correct Network type is available"
+ )
+
+ self.assertFalse(
+ 'gateway' in str(list_vm[0].nic[0])
+ )
+
+ self.assertFalse(
+ 'ipaddress' in str(list_vm[0].nic[0])
+ )
+
+ return
+
+ @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="false")
+ def test_delete_network_while_vm_on_it(self):
+ """It verifies the user is not able to delete network which has
running vms"""
+
+ # Validate the following:
+ # 1. Deploys a VM
+ # 2. Tries to delete network and expects exception to appear
+
+ self.virtual_machine = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ templateid=self.template.id,
+ serviceofferingid=self.service_offering.id,
+ networkids=self.l2_network.id,
+ zoneid=self.zone.id
+ )
+
+ self.cleanup.insert(0, self.virtual_machine)
+
+ list_vm = list_virtual_machines(
+ self.apiclient,
+ id = self.virtual_machine.id
+ )
+ self.assertEqual(
+ isinstance(list_vm, list),
+ True,
+ "Check if virtual machine is present"
+ )
+
+ try:
+ self.l2_network.delete(self.apiclient)
+ except Exception:
+ pass
+ else:
+ self.fail("Expected an exception to be thrown, failing")
+
+ return
+
+ @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="false")
+ def test_l2network_restart(self):
+ """This test covers a few scenarios around restarting a network"""
+
+ # Validate the following:
+ # 1. Creates a l2 network
+ # 2. Tries to restart a network with no VMs, which trows error 'not in
the right state'
+ # 3. Deploys a VM
+ # 4. Restarts the network without cleanup
+ # 5. Restarts the network with cleanup
+
+ try:
+ self.l2_network.restart(self.apiclient, cleanup=True)
+ except Exception:
+ pass
+ else:
+ self.fail("Expected an exception to be thrown, failing")
+
+ li_net = self.l2_network.list(self.apiclient)[0]
+
+ self.assertTrue(
+ li_net.state,
+ 'Allocated'
+ "Not the correct state"
+ )
+
+ self.virtual_machine = VirtualMachine.create(
+ self.apiclient,
+ self.services["virtual_machine"],
+ templateid=self.template.id,
+ serviceofferingid=self.service_offering.id,
+ networkids=self.l2_network.id,
+ zoneid=self.zone.id
+ )
+
+ self.cleanup.insert(0, self.virtual_machine)
+
+ list_vm = list_virtual_machines(
+ self.apiclient,
+ id = self.virtual_machine.id
+ )
+ self.assertEqual(
+ isinstance(list_vm, list),
+ True,
+ "Check if virtual machine is present"
+ )
+
+ self.l2_network.restart(self.apiclient, cleanup=False)
+
+ li_net = self.l2_network.list(self.apiclient)[0]
+
+ self.assertTrue(
+ li_net.state,
+ 'Implemented'
+ "Not the correct state"
+ )
+
+ self.l2_network.restart(self.apiclient, cleanup=True)
+
+ li_net = self.l2_network.list(self.apiclient)[0]
+
+ self.assertTrue(
+ li_net.state,
+ 'Implemented'
+ "Not the correct state"
+ )
+
+ return
diff --git a/tools/marvin/marvin/config/test_data.py
b/tools/marvin/marvin/config/test_data.py
index da74cb52daa..ece3e327771 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -190,6 +190,10 @@
"displaytext": "Test Network",
"acltype": "Account",
},
+ "l2-network": {
+ "name": "Test L2 Network",
+ "displaytext": "Test L2 Network"
+ },
"network2": {
"name": "Test Network Shared",
"displaytext": "Test Network Shared",
@@ -200,6 +204,14 @@
"endip": "172.16.15.41",
"acltype": "Account",
},
+ "l2-network_offering": {
+ "name": 'Test L2 - Network offering',
+ "displaytext": 'Test L2 - Network offering',
+ "guestiptype": 'L2',
+ "supportedservices": '',
+ "traffictype": 'GUEST',
+ "availability": 'Optional'
+ },
"network_offering": {
"name": 'Test Network offering',
"displaytext": 'Test Network offering',
diff --git a/ui/l10n/ar.js b/ui/l10n/ar.js
index afb4269ec68..727660eab2e 100644
--- a/ui/l10n/ar.js
+++ b/ui/l10n/ar.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Add Isolated Guest Network",
"label.add.isolated.guest.network.with.sourcenat": "Add Isolated Guest
Network with SourceNat",
"label.add.isolated.network": "Add Isolated Network",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Add LDAP account",
"label.add.list.name": "ACL List Name",
"label.add.load.balancer": "Add Load Balancer",
diff --git a/ui/l10n/ca.js b/ui/l10n/ca.js
index 3b1f04caa0f..771743f3aff 100644
--- a/ui/l10n/ca.js
+++ b/ui/l10n/ca.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Add Isolated Guest Network",
"label.add.isolated.guest.network.with.sourcenat": "Add Isolated Guest
Network with SourceNat",
"label.add.isolated.network": "Add Isolated Network",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Add LDAP account",
"label.add.list.name": "ACL List Name",
"label.add.load.balancer": "Add Load Balancer",
diff --git a/ui/l10n/de_DE.js b/ui/l10n/de_DE.js
index c0f2e0ae012..727dc2afead 100644
--- a/ui/l10n/de_DE.js
+++ b/ui/l10n/de_DE.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Isoliertes Gastnetzwerk hinzuf?gen",
"label.add.isolated.guest.network.with.sourcenat": "Isoliertes
Gastnetzwerk mit Source-NAT hinzuf?gen",
"label.add.isolated.network": "Isoliertes Netzwerk hinzuf?gen",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "LDAP-Konto hinzuf?gen",
"label.add.list.name": "ACL-Listename",
"label.add.load.balancer": "Lastverteiler hinzuf?gen",
diff --git a/ui/l10n/en.js b/ui/l10n/en.js
index 3d0c42147c7..26a7a038d4e 100644
--- a/ui/l10n/en.js
+++ b/ui/l10n/en.js
@@ -340,6 +340,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
"label.add.isolated.guest.network":"Add Isolated Guest Network",
"label.add.isolated.guest.network.with.sourcenat":"Add Isolated Guest Network
with SourceNat",
"label.add.isolated.network":"Add Isolated Network",
+"label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account":"Add LDAP account",
"label.add.list.name":"ACL List Name",
"label.add.load.balancer":"Add Load Balancer",
diff --git a/ui/l10n/es.js b/ui/l10n/es.js
index 6abfd8eaaf0..0d53b0e6aa6 100644
--- a/ui/l10n/es.js
+++ b/ui/l10n/es.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "A?adir Red Invitado Aislada",
"label.add.isolated.guest.network.with.sourcenat": "Agregar Red de
Invitado Aislada con NatOrigen",
"label.add.isolated.network": "Agregar Red Aislada",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Agregar cuenta LDAP",
"label.add.list.name": "Nombre de la Lista ACL",
"label.add.load.balancer": "A?adir balanceador de carga",
diff --git a/ui/l10n/fr_FR.js b/ui/l10n/fr_FR.js
index dd5e85a3555..ac6f17323f6 100644
--- a/ui/l10n/fr_FR.js
+++ b/ui/l10n/fr_FR.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Ajouter un r?seau d'invit? isol?",
"label.add.isolated.guest.network.with.sourcenat": "Ajouter un r?seau
d'invit? isol? avec SourceNat",
"label.add.isolated.network": "Ajouter un r?seau isol?",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Ajouter un compte LDAP",
"label.add.list.name": "Nom Liste ACL",
"label.add.load.balancer": "Ajouter un r?partiteur de charge",
diff --git a/ui/l10n/hu.js b/ui/l10n/hu.js
index 23519b951e1..db4f2188a21 100644
--- a/ui/l10n/hu.js
+++ b/ui/l10n/hu.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Izol?lt vend?g h?l?zat felv?tele",
"label.add.isolated.guest.network.with.sourcenat": "Add Isolated Guest
Network with SourceNat",
"label.add.isolated.network": "Izol?lt h?l?zat felv?tele",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "LDAP hozz?f?r?s felv?tele",
"label.add.list.name": "ACL lista n?v",
"label.add.load.balancer": "Terhel?seloszt? felv?tele",
diff --git a/ui/l10n/it_IT.js b/ui/l10n/it_IT.js
index c4501e63b38..7a8caa545de 100644
--- a/ui/l10n/it_IT.js
+++ b/ui/l10n/it_IT.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Add Isolated Guest Network",
"label.add.isolated.guest.network.with.sourcenat": "Add Isolated Guest
Network with SourceNat",
"label.add.isolated.network": "Add Isolated Network",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Aggiungi un account LDAP",
"label.add.list.name": "ACL List Name",
"label.add.load.balancer": "Aggiungere un Load Balancer",
diff --git a/ui/l10n/ja_JP.js b/ui/l10n/ja_JP.js
index a2f42f9e34b..7498c8f3e03 100644
--- a/ui/l10n/ja_JP.js
+++ b/ui/l10n/ja_JP.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "??????????????",
"label.add.isolated.guest.network.with.sourcenat":
"???????????(???NAT)???",
"label.add.isolated.network": "??????????????",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "LDAP ????????",
"label.add.list.name": "ACL ???",
"label.add.load.balancer": "??? ????????",
diff --git a/ui/l10n/ko_KR.js b/ui/l10n/ko_KR.js
index 9655052fbc7..372a728f7c4 100644
--- a/ui/l10n/ko_KR.js
+++ b/ui/l10n/ko_KR.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Add Isolated Guest Network",
"label.add.isolated.guest.network.with.sourcenat": "Add Isolated Guest
Network with SourceNat",
"label.add.isolated.network": "Add Isolated Network",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Add LDAP account",
"label.add.list.name": "ACL List Name",
"label.add.load.balancer": "???? ?? ?? ?? ??",
diff --git a/ui/l10n/nb_NO.js b/ui/l10n/nb_NO.js
index c9836eada37..d0d1d3fbf6f 100644
--- a/ui/l10n/nb_NO.js
+++ b/ui/l10n/nb_NO.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Legg til Isolert gjestenettverk",
"label.add.isolated.guest.network.with.sourcenat": "Legg til isolert
gjestenettverk med kilde-NAT",
"label.add.isolated.network": "Legg Til Isolert Nettverk",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Legg til LDAP-konto",
"label.add.list.name": "ACL listenavn",
"label.add.load.balancer": "Legg til lastbalanserer",
diff --git a/ui/l10n/nl_NL.js b/ui/l10n/nl_NL.js
index 5e438899ee5..62313e996ad 100644
--- a/ui/l10n/nl_NL.js
+++ b/ui/l10n/nl_NL.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Voeg een ge?soleerd netwerk toe",
"label.add.isolated.guest.network.with.sourcenat": "voeg en ge?soleerd
gast netwerk met bron-NAT toe",
"label.add.isolated.network": "Geisoleerd Netwerk Toevoegen",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Voeg LDAP account toe",
"label.add.list.name": "ACL lijst naam",
"label.add.load.balancer": "Voeg Load Balancer toe",
diff --git a/ui/l10n/pl.js b/ui/l10n/pl.js
index 8b1cb420559..75c3af1f1e8 100644
--- a/ui/l10n/pl.js
+++ b/ui/l10n/pl.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Add Isolated Guest Network",
"label.add.isolated.guest.network.with.sourcenat": "Add Isolated Guest
Network with SourceNat",
"label.add.isolated.network": "Add Isolated Network",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Add LDAP account",
"label.add.list.name": "ACL List Name",
"label.add.load.balancer": "Add Load Balancer",
diff --git a/ui/l10n/pt_BR.js b/ui/l10n/pt_BR.js
index fbaafcb8913..1b0be1897f4 100644
--- a/ui/l10n/pt_BR.js
+++ b/ui/l10n/pt_BR.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "Adiciona Rede Guest Isolada",
"label.add.isolated.guest.network.with.sourcenat": "Adicionar rede Guest
isolada com SourceNat",
"label.add.isolated.network": "Adiciona Rede Isolada",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "Adicionar Conta LDAP",
"label.add.list.name": "Nome de Lista ACL",
"label.add.load.balancer": "Adicionar Load Balance",
diff --git a/ui/l10n/ru_RU.js b/ui/l10n/ru_RU.js
index 649e5fe170d..62c2602f6d6 100644
--- a/ui/l10n/ru_RU.js
+++ b/ui/l10n/ru_RU.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "???????? ????????????? ???????? ????",
"label.add.isolated.guest.network.with.sourcenat": "Add Isolated Guest
Network with SourceNat",
"label.add.isolated.network": "???????? ????????????? ????",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "???????? LDAP ???????",
"label.add.list.name": "ACL List Name",
"label.add.load.balancer": "???????? ????????????? ????????",
diff --git a/ui/l10n/zh_CN.js b/ui/l10n/zh_CN.js
index c4a663c4a8c..78729d9a500 100644
--- a/ui/l10n/zh_CN.js
+++ b/ui/l10n/zh_CN.js
@@ -338,6 +338,7 @@ var dictionary = {
"label.add.isolated.guest.network": "?????????",
"label.add.isolated.guest.network.with.sourcenat": "????????????
SourceNat",
"label.add.isolated.network": "??????",
+ "label.add.l2.guest.network":"Add L2 Guest Network",
"label.add.ldap.account": "?? LDAP ??",
"label.add.list.name": "ACL ????",
"label.add.load.balancer": "???????",
diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js
index 00972b66050..cbe32813b04 100644
--- a/ui/scripts/configuration.js
+++ b/ui/scripts/configuration.js
@@ -2403,13 +2403,19 @@
//*** VPC checkbox ***
var $useVpc =
args.$form.find('.form-item[rel=\"useVpc\"]');
var $useVpcCb =
$useVpc.find("input[type=checkbox]");
+ var $supportedServices =
args.$form.find('.form-item[rel=\"supportedServices\"]');
if ($guestTypeField.val() == 'Shared')
{ //Shared network offering
$useVpc.hide();
+ $supportedServices.css('display',
'inline-block');
if ($useVpcCb.is(':checked')) {
//if useVpc is checked,
$useVpcCb.removeAttr("checked"); //remove "checked" attribute in useVpc
}
- } else { //Isolated network offering
+ } else if ($guestTypeField.val() ==
'Isolated') { //Isolated network offering
$useVpc.css('display',
'inline-block');
+ $supportedServices.css('display',
'inline-block');
+ } else if ($guestTypeField.val() ==
'L2') {
+ $useVpc.hide();
+ $supportedServices.hide();
}
var $providers =
$useVpcCb.closest('form').find('.dynamic-input
select[name!="service.Connectivity.provider"]');
var $optionsOfProviders =
$providers.find('option');
@@ -2754,6 +2760,9 @@
}, {
id: 'Shared',
description: 'Shared'
+ }, {
+ id: 'L2',
+ description: 'L2'
}]
});
@@ -2766,10 +2775,9 @@
$form.find('.form-item[rel=isPersistent]').find('input[type=checkbox]').attr("disabled",
"disabled");
- } else { //$(this).val() ==
"Isolated"
+ } else if ($(this).val() ==
"Isolated" || $(this).val() == "L2") {
$form.find('.form-item[rel=specifyVlan]').find('input[type=checkbox]').removeAttr("disabled");
//make it editable
$form.find('.form-item[rel=isPersistent]').find('input[type=checkbox]').removeAttr("disabled");
-
}
});
}
@@ -3370,6 +3378,12 @@
} else { //Isolated Network with
Non-persistent network
delete inputData.isPersistent; //if
Persistent checkbox is unchecked, do not pass isPersistent parameter to API
call since we need to keep API call's size as small as possible (p.s.
isPersistent is defaulted as false at server-side)
}
+ } else if (inputData['guestIpType'] == "L2") {
+ if (inputData['specifyVlan'] == 'on') {
//specifyVlan checkbox is checked
+ inputData['specifyVlan'] = true;
+ } else { //specifyVlan checkbox is
unchecked
+ delete inputData.specifyVlan; //if
specifyVlan checkbox is unchecked, do not pass specifyVlan parameter to API
call since we need to keep API call's size as small as possible (p.s.
specifyVlan is defaulted as false at server-side)
+ }
}
if (inputData['forvpc'] == 'on') {
diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js
index ca77c27e6b1..db7f5335148 100644
--- a/ui/scripts/instances.js
+++ b/ui/scripts/instances.js
@@ -431,6 +431,9 @@
var items =
json.listvirtualmachinesresponse.virtualmachine;
if (items) {
$.each(items, function(idx, vm) {
+ if (! vm.ipaddress) {
+ vm['ipaddress'] = "N/A";
+ }
if (vm.nic && vm.nic.length > 0 &&
vm.nic[0].ipaddress) {
items[idx].ipaddress = vm.nic[0].ipaddress;
}
diff --git a/ui/scripts/network.js b/ui/scripts/network.js
index 66ab75a42f0..9054a8537bb 100644
--- a/ui/scripts/network.js
+++ b/ui/scripts/network.js
@@ -800,6 +800,10 @@
rootAdminAddGuestNetwork: $.extend({},
addGuestNetworkDialog.def, {
isHeader: true
+ }),
+
+ rootAdminAddL2Network: $.extend({},
addL2GuestNetwork.def, {
+ isHeader: true
})
},
@@ -954,7 +958,8 @@
path: 'network.ipAddresses',
label: 'label.menu.ipaddresses',
preFilter: function(args) {
- if (args.context.networks[0].state ==
'Destroyed')
+ if (args.context.networks[0].state ==
'Destroyed' ||
+ args.context.networks[0].type == 'L2')
return false;
return true;
@@ -971,6 +976,11 @@
return 'label.edit.network.details';
}
},
+ preFilter: function(args) {
+ if (args.context.networks[0].state ==
'Destroyed')
+ return false;
+ return true;
+ },
action: function(args) {
var data = {
id: args.context.networks[0].id,
@@ -1051,8 +1061,13 @@
}
},
- 'restart': {
+ restart: {
label: 'label.restart.network',
+ preFilter: function(args) {
+ if (args.context.networks[0].state ==
'Destroyed')
+ return false;
+ return true;
+ },
createForm: {
title: 'label.restart.network',
desc: 'message.restart.network',
@@ -1108,6 +1123,11 @@
remove: {
label: 'label.action.delete.network',
+ preFilter: function(args) {
+ if (args.context.networks[0].state ==
'Destroyed')
+ return false;
+ return true;
+ },
messages: {
confirm: function(args) {
return 'message.action.delete.network';
diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js
index 655aee9fb93..c58ce056c8e 100644
--- a/ui/scripts/sharedFunctions.js
+++ b/ui/scripts/sharedFunctions.js
@@ -818,6 +818,263 @@ var addGuestNetworkDialog = {
}
}
+var addL2GuestNetwork = {
+ zoneObjs: [],
+ physicalNetworkObjs: [],
+ networkOfferingObjs: [],
+ def: {
+ label: 'label.add.l2.guest.network',
+
+ messages: {
+ notification: function(args) {
+ return 'label.add.l2.guest.network';
+ }
+ },
+
+ preFilter: function(args) {
+ if (isAdmin())
+ return true;
+ else
+ return false;
+ },
+
+ createForm: {
+ title: 'label.add.l2.guest.network',
+ fields: {
+ name: {
+ label: 'label.name',
+ validation: {
+ required: true
+ },
+ docID: 'helpGuestNetworkName'
+ },
+ displayText: {
+ label: 'label.display.text',
+ validation: {
+ required: true
+ },
+ docID: 'helpGuestNetworkDisplayText'
+ },
+ zoneId: {
+ label: 'label.zone',
+ validation: {
+ required: true
+ },
+ docID: 'helpGuestNetworkZone',
+
+ select: function(args) {
+ $.ajax({
+ url: createURL('listZones'),
+ success: function(json) {
+ var zones =
$.grep(json.listzonesresponse.zone, function(zone) {
+ return (zone.networktype == 'Advanced' &&
zone.securitygroupsenabled != true); //Isolated networks can only be created in
Advanced SG-disabled zone (but not in Basic zone nor Advanced SG-enabled zone)
+ });
+
+ args.response.success({
+ data: $.map(zones, function(zone) {
+ return {
+ id: zone.id,
+ description: zone.name
+ };
+ })
+ });
+ }
+ });
+ }
+ },
+ networkOfferingId: {
+ label: 'label.network.offering',
+ validation: {
+ required: true
+ },
+ dependsOn: 'zoneId',
+ docID: 'helpGuestNetworkNetworkOffering',
+ select: function(args) {
+ var data = {
+ zoneid: args.zoneId,
+ guestiptype: 'L2',
+ state: 'Enabled'
+ };
+
+ if ('vpc' in args.context) { //from VPC section
+ $.extend(data, {
+ forVpc: true
+ });
+ }
+ else { //from guest network section
+ var vpcs;
+ $.ajax({
+ url: createURL('listVPCs'),
+ data: {
+ listAll: true
+ },
+ async: false,
+ success: function(json) {
+ vpcs = json.listvpcsresponse.vpc;
+ }
+ });
+ if (vpcs == null || vpcs.length == 0) { //if there
is no VPC in the system
+ $.extend(data, {
+ forVpc: false
+ });
+ }
+ }
+
+ if(!isAdmin()) { //normal user is not aware of the
VLANs in the system, so normal user is not allowed to create network with
network offerings whose specifyvlan = true
+ $.extend(data, {
+ specifyvlan: false
+ });
+ }
+
+ $.ajax({
+ url: createURL('listNetworkOfferings'),
+ data: data,
+ success: function(json) {
+ networkOfferingObjs =
json.listnetworkofferingsresponse.networkoffering;
+ args.$select.change(function() {
+ var $vlan =
args.$select.closest('form').find('[rel=vlan]');
+ var networkOffering = $.grep(
+ networkOfferingObjs,
function(netoffer) {
+ return netoffer.id ==
args.$select.val();
+ }
+ )[0];
+
+ if (networkOffering.specifyvlan) {
+ $vlan.css('display', 'inline-block');
+ } else {
+ $vlan.hide();
+ }
+ });
+
+ args.response.success({
+ data: $.map(networkOfferingObjs,
function(zone) {
+ return {
+ id: zone.id,
+ description: zone.name
+ };
+ })
+ });
+ }
+ });
+ }
+ },
+
+ vlan: {
+ label: 'label.vlan',
+ validation: {
+ required: true
+ },
+ isHidden: true
+ },
+
+ domain: {
+ label: 'label.domain',
+ isHidden: function(args) {
+ if (isAdmin() || isDomainAdmin())
+ return false;
+ else
+ return true;
+ },
+ select: function(args) {
+ if (isAdmin() || isDomainAdmin()) {
+ $.ajax({
+ url: createURL("listDomains&listAll=true"),
+ success: function(json) {
+ var items = [];
+ items.push({
+ id: "",
+ description: ""
+ });
+ var domainObjs =
json.listdomainsresponse.domain;
+ $(domainObjs).each(function() {
+ items.push({
+ id: this.id,
+ description: this.path
+ });
+ });
+ items.sort(function(a, b) {
+ return
a.description.localeCompare(b.description);
+ });
+ args.response.success({
+ data: items
+ });
+ }
+ });
+ args.$select.change(function() {
+ var $form = $(this).closest('form');
+ if ($(this).val() == "") {
+
$form.find('.form-item[rel=account]').hide();
+ } else {
+
$form.find('.form-item[rel=account]').css('display', 'inline-block');
+ }
+ });
+ } else {
+ args.response.success({
+ data: null
+ });
+ }
+ }
+ },
+ account: {
+ label: 'label.account',
+ validation: {
+ required: true
+ },
+ isHidden: function(args) {
+ if (isAdmin() || isDomainAdmin())
+ return false;
+ else
+ return true;
+ }
+ }
+ }
+ },
+
+ action: function(args) {
+ var dataObj = {
+ zoneId: args.data.zoneId,
+ name: args.data.name,
+ displayText: args.data.displayText,
+ networkOfferingId: args.data.networkOfferingId
+ };
+
+ if (args.$form.find('.form-item[rel=vlan]').css('display') !=
'none') {
+ $.extend(dataObj, {
+ vlan: args.data.vlan
+ });
+ }
+
+ if (args.data.domain != null && args.data.domain.length > 0) {
+ $.extend(dataObj, {
+ domainid: args.data.domain
+ });
+ if (args.data.account != null && args.data.account.length > 0)
{
+ $.extend(dataObj, {
+ account: args.data.account
+ });
+ }
+ }
+
+ $.ajax({
+ url: createURL('createNetwork'),
+ data: dataObj,
+ success: function(json) {
+ args.response.success({
+ data: json.createnetworkresponse.network
+ });
+ },
+ error: function(json) {
+ args.response.error(parseXMLHttpResponse(json));
+ }
+ });
+ },
+ notification: {
+ poll: function(args) {
+ args.complete();
+ }
+ }
+ }
+}
function isLdapEnabled() {
var result;
----------------------------------------------------------------
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:
[email protected]
With regards,
Apache Git Services