mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-10102: New network type L2 (#2281)
This feature allows CloudStack administrators to create layer 2 networks on CloudStack. As these networks are purely layer 2, they don't require IP addresses or Virtual Router, only VLAN is necessary (provided by administrator or assigned by CloudStack). Also, network services should be handled externally, e.g. DNS, DHCP, as they are not provided by L2 networks. As a consequence, a new Guest Network type is created within CloudStack: L2 Description: Network offerings and networks support new guest type: L2. L2 Network offering creation allows administrator to select Specify VLAN or let CloudStack assign it dynamically. L2 Network creation allows administrator to specify VLAN tag (if network offerings allows it) or simply create network. VM deployments on L2 networks: VMs should not IP addresses or any network service No Virtual Router deployed on network If Specify VLAN = true for network offering, network gets implemented using a dynamically assigned VLAN UI changes A new button is added on Networks tab, available for admins, to allow L2 networks creation
This commit is contained in:
parent
8acb0908c4
commit
13c325aad4
@ -38,7 +38,7 @@ import com.cloud.utils.fsm.StateObject;
|
||||
public interface Network extends ControlledEntity, StateObject<Network.State>, InternalIdentity, Identity, Serializable, Displayable {
|
||||
|
||||
public enum GuestType {
|
||||
Shared, Isolated
|
||||
Shared, Isolated, L2
|
||||
}
|
||||
|
||||
public String updatingInSequence ="updatingInSequence";
|
||||
|
||||
@ -2207,8 +2207,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
+ 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 class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
// 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 class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
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);
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@ import java.util.Set;
|
||||
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 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
|
||||
// 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 class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
|
||||
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) {
|
||||
|
||||
@ -107,6 +107,7 @@ public class BrocadeVcsGuestNetworkGuruTest {
|
||||
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 class BrocadeVcsGuestNetworkGuruTest {
|
||||
|
||||
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);
|
||||
|
||||
@ -94,7 +94,7 @@ public class NiciraNvpGuestNetworkGuruTest {
|
||||
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 class NiciraNvpGuestNetworkGuruTest {
|
||||
|
||||
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);
|
||||
|
||||
@ -2013,7 +2013,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
|
||||
// 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
|
||||
|
||||
@ -799,7 +799,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
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());
|
||||
@ -1317,12 +1316,20 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
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");
|
||||
@ -1766,6 +1773,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
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()) {
|
||||
|
||||
@ -29,6 +29,7 @@ import java.util.List;
|
||||
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 class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
||||
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 class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
||||
|
||||
@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>();
|
||||
|
||||
@ -1124,7 +1124,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
}
|
||||
}
|
||||
} 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 class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
|
||||
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
|
||||
|
||||
@ -91,8 +91,9 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
|
||||
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 class ExternalGuestNetworkGuru extends GuestNetworkGuru {
|
||||
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));
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.Random;
|
||||
|
||||
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 abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
|
||||
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 abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
|
||||
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());
|
||||
|
||||
@ -1271,3 +1271,225 @@ class TestRouterRules(cloudstackTestCase):
|
||||
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
|
||||
|
||||
@ -190,6 +190,10 @@ test_data = {
|
||||
"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 @@ test_data = {
|
||||
"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',
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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": "ロード バランサーの追加",
|
||||
|
||||
@ -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": "네트워크 로드 공유 장치 추가",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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": "Добавить балансировщик нагрузки",
|
||||
|
||||
@ -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": "添加负载平衡器",
|
||||
|
||||
@ -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') {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user