mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
2192 lines
93 KiB
Java
Executable File
2192 lines
93 KiB
Java
Executable File
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
package com.cloud.network;
|
|
|
|
import java.math.BigInteger;
|
|
import java.security.InvalidParameterException;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.TreeSet;
|
|
|
|
import javax.ejb.Local;
|
|
import javax.inject.Inject;
|
|
import javax.naming.ConfigurationException;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
|
|
|
|
import com.cloud.api.ApiDBUtils;
|
|
import com.cloud.configuration.Config;
|
|
import com.cloud.configuration.ConfigurationManager;
|
|
import com.cloud.dc.DataCenter;
|
|
import com.cloud.dc.PodVlanMapVO;
|
|
import com.cloud.dc.Vlan;
|
|
import com.cloud.dc.Vlan.VlanType;
|
|
import com.cloud.dc.VlanVO;
|
|
import com.cloud.dc.dao.DataCenterDao;
|
|
import com.cloud.dc.dao.PodVlanMapDao;
|
|
import com.cloud.dc.dao.VlanDao;
|
|
import com.cloud.domain.DomainVO;
|
|
import com.cloud.domain.dao.DomainDao;
|
|
import com.cloud.exception.InsufficientAddressCapacityException;
|
|
import com.cloud.exception.InvalidParameterValueException;
|
|
import com.cloud.exception.PermissionDeniedException;
|
|
import com.cloud.exception.UnsupportedServiceException;
|
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
|
import com.cloud.network.IpAddress.State;
|
|
import com.cloud.network.Network.Capability;
|
|
import com.cloud.network.Network.GuestType;
|
|
import com.cloud.network.Network.Provider;
|
|
import com.cloud.network.Network.Service;
|
|
import com.cloud.network.Networks.TrafficType;
|
|
import com.cloud.network.addr.PublicIp;
|
|
import com.cloud.network.dao.FirewallRulesDao;
|
|
import com.cloud.network.dao.IPAddressDao;
|
|
import com.cloud.network.dao.IPAddressVO;
|
|
import com.cloud.network.dao.NetworkDao;
|
|
import com.cloud.network.dao.NetworkDomainDao;
|
|
import com.cloud.network.dao.NetworkDomainVO;
|
|
import com.cloud.network.dao.NetworkServiceMapDao;
|
|
import com.cloud.network.dao.NetworkServiceMapVO;
|
|
import com.cloud.network.dao.NetworkVO;
|
|
import com.cloud.network.dao.PhysicalNetworkDao;
|
|
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
|
|
import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
|
|
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
|
|
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
|
|
import com.cloud.network.dao.PhysicalNetworkVO;
|
|
import com.cloud.network.dao.UserIpv6AddressDao;
|
|
import com.cloud.network.element.IpDeployer;
|
|
import com.cloud.network.element.IpDeployingRequester;
|
|
import com.cloud.network.element.NetworkElement;
|
|
import com.cloud.network.element.UserDataServiceProvider;
|
|
import com.cloud.network.rules.FirewallRule.Purpose;
|
|
import com.cloud.network.rules.FirewallRuleVO;
|
|
import com.cloud.network.rules.dao.PortForwardingRulesDao;
|
|
import com.cloud.network.vpc.dao.PrivateIpDao;
|
|
import com.cloud.offering.NetworkOffering;
|
|
import com.cloud.offering.NetworkOffering.Detail;
|
|
import com.cloud.offerings.NetworkOfferingServiceMapVO;
|
|
import com.cloud.offerings.NetworkOfferingVO;
|
|
import com.cloud.offerings.dao.NetworkOfferingDao;
|
|
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
|
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
|
import com.cloud.projects.dao.ProjectAccountDao;
|
|
import com.cloud.server.ConfigurationServer;
|
|
import com.cloud.user.Account;
|
|
import com.cloud.user.AccountVO;
|
|
import com.cloud.user.DomainManager;
|
|
import com.cloud.user.dao.AccountDao;
|
|
import com.cloud.utils.component.AdapterBase;
|
|
import com.cloud.utils.component.ManagerBase;
|
|
import com.cloud.utils.db.DB;
|
|
import com.cloud.utils.db.EntityManager;
|
|
import com.cloud.utils.db.JoinBuilder;
|
|
import com.cloud.utils.db.JoinBuilder.JoinType;
|
|
import com.cloud.utils.db.SearchBuilder;
|
|
import com.cloud.utils.db.SearchCriteria;
|
|
import com.cloud.utils.db.SearchCriteria.Op;
|
|
import com.cloud.utils.exception.CloudRuntimeException;
|
|
import com.cloud.utils.net.NetUtils;
|
|
import com.cloud.vm.Nic;
|
|
import com.cloud.vm.NicProfile;
|
|
import com.cloud.vm.NicVO;
|
|
import com.cloud.vm.VMInstanceVO;
|
|
import com.cloud.vm.VirtualMachine;
|
|
import com.cloud.vm.VirtualMachine.Type;
|
|
import com.cloud.vm.dao.NicDao;
|
|
import com.cloud.vm.dao.NicSecondaryIpDao;
|
|
import com.cloud.vm.dao.VMInstanceDao;
|
|
|
|
@Local(value = {NetworkModel.class})
|
|
public class NetworkModelImpl extends ManagerBase implements NetworkModel {
|
|
static final Logger s_logger = Logger.getLogger(NetworkModelImpl.class);
|
|
@Inject
|
|
EntityManager _entityMgr;
|
|
@Inject
|
|
DataCenterDao _dcDao = null;
|
|
@Inject
|
|
VlanDao _vlanDao = null;
|
|
@Inject
|
|
IPAddressDao _ipAddressDao = null;
|
|
@Inject
|
|
AccountDao _accountDao = null;
|
|
@Inject
|
|
DomainDao _domainDao = null;
|
|
@Inject
|
|
ConfigurationDao _configDao;
|
|
|
|
@Inject
|
|
ConfigurationManager _configMgr;
|
|
|
|
@Inject
|
|
NetworkOfferingDao _networkOfferingDao = null;
|
|
@Inject
|
|
NetworkDao _networksDao = null;
|
|
@Inject
|
|
NicDao _nicDao = null;
|
|
|
|
@Inject
|
|
PodVlanMapDao _podVlanMapDao;
|
|
@Inject
|
|
ConfigurationServer _configServer;
|
|
|
|
List<NetworkElement> _networkElements;
|
|
|
|
public List<NetworkElement> getNetworkElements() {
|
|
return _networkElements;
|
|
}
|
|
|
|
public void setNetworkElements(List<NetworkElement> _networkElements) {
|
|
this._networkElements = _networkElements;
|
|
}
|
|
|
|
@Inject
|
|
NetworkDomainDao _networkDomainDao;
|
|
@Inject
|
|
VMInstanceDao _vmDao;
|
|
|
|
@Inject
|
|
FirewallRulesDao _firewallDao;
|
|
@Inject
|
|
DomainManager _domainMgr;
|
|
|
|
@Inject
|
|
NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
|
|
@Inject
|
|
PhysicalNetworkDao _physicalNetworkDao;
|
|
@Inject
|
|
PhysicalNetworkServiceProviderDao _pNSPDao;
|
|
@Inject
|
|
PortForwardingRulesDao _portForwardingRulesDao;
|
|
@Inject
|
|
PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
|
|
@Inject
|
|
NetworkServiceMapDao _ntwkSrvcDao;
|
|
@Inject
|
|
PrivateIpDao _privateIpDao;
|
|
@Inject
|
|
UserIpv6AddressDao _ipv6Dao;
|
|
@Inject
|
|
NicSecondaryIpDao _nicSecondaryIpDao;
|
|
@Inject
|
|
ApplicationLoadBalancerRuleDao _appLbRuleDao;
|
|
@Inject
|
|
private ProjectAccountDao _projectAccountDao;
|
|
@Inject
|
|
NetworkOfferingDetailsDao _ntwkOffDetailsDao;
|
|
|
|
private final HashMap<String, NetworkOfferingVO> _systemNetworks = new HashMap<String, NetworkOfferingVO>(5);
|
|
static Long _privateOfferingId = null;
|
|
|
|
SearchBuilder<IPAddressVO> IpAddressSearch;
|
|
SearchBuilder<NicVO> NicForTrafficTypeSearch;
|
|
|
|
private boolean _allowSubdomainNetworkAccess;
|
|
|
|
private Map<String, String> _configs;
|
|
|
|
protected boolean _executeInSequenceNtwkElmtCmd;
|
|
|
|
HashMap<Long, Long> _lastNetworkIdsToFree = new HashMap<Long, Long>();
|
|
|
|
static HashMap<Service, List<Provider>> s_serviceToImplementedProvidersMap = new HashMap<Service, List<Provider>>();
|
|
static HashMap<String, String> s_providerToNetworkElementMap = new HashMap<String, String>();
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public NetworkModelImpl() {
|
|
super();
|
|
}
|
|
|
|
@Override
|
|
public NetworkElement getElementImplementingProvider(String providerName) {
|
|
String elementName = s_providerToNetworkElementMap.get(providerName);
|
|
NetworkElement element = AdapterBase.getAdapterByName(_networkElements, elementName);
|
|
return element;
|
|
}
|
|
|
|
@Override
|
|
public List<Service> getElementServices(Provider provider) {
|
|
NetworkElement element = getElementImplementingProvider(provider.getName());
|
|
if (element == null) {
|
|
throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
|
|
}
|
|
return new ArrayList<Service>(element.getCapabilities().keySet());
|
|
}
|
|
|
|
@Override
|
|
public boolean canElementEnableIndividualServices(Provider provider) {
|
|
NetworkElement element = getElementImplementingProvider(provider.getName());
|
|
if (element == null) {
|
|
throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
|
|
}
|
|
return element.canEnableIndividualServices();
|
|
}
|
|
|
|
Set<Purpose> getPublicIpPurposeInRules(PublicIpAddress ip, boolean includeRevoked, boolean includingFirewall) {
|
|
Set<Purpose> result = new HashSet<Purpose>();
|
|
List<FirewallRuleVO> rules = null;
|
|
if (includeRevoked) {
|
|
rules = _firewallDao.listByIp(ip.getId());
|
|
} else {
|
|
rules = _firewallDao.listByIpAndNotRevoked(ip.getId());
|
|
}
|
|
|
|
if (rules == null || rules.isEmpty()) {
|
|
return null;
|
|
}
|
|
|
|
for (FirewallRuleVO rule : rules) {
|
|
if (rule.getPurpose() != Purpose.Firewall || includingFirewall) {
|
|
result.add(rule.getPurpose());
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean postApplyRules, boolean includingFirewall) {
|
|
Map<PublicIpAddress, Set<Service>> ipToServices = new HashMap<PublicIpAddress, Set<Service>>();
|
|
|
|
if (publicIps != null && !publicIps.isEmpty()) {
|
|
Set<Long> networkSNAT = new HashSet<Long>();
|
|
for (PublicIpAddress ip : publicIps) {
|
|
Set<Service> services = ipToServices.get(ip);
|
|
if (services == null) {
|
|
services = new HashSet<Service>();
|
|
}
|
|
if (ip.isSourceNat()) {
|
|
if (!networkSNAT.contains(ip.getAssociatedWithNetworkId())) {
|
|
services.add(Service.SourceNat);
|
|
networkSNAT.add(ip.getAssociatedWithNetworkId());
|
|
} else {
|
|
CloudRuntimeException ex = new CloudRuntimeException("Multiple generic soure NAT IPs provided for network");
|
|
// see the IPAddressVO.java class.
|
|
IPAddressVO ipAddr = ApiDBUtils.findIpAddressById(ip.getAssociatedWithNetworkId());
|
|
String ipAddrUuid = ip.getAssociatedWithNetworkId().toString();
|
|
if (ipAddr != null) {
|
|
ipAddrUuid = ipAddr.getUuid();
|
|
}
|
|
ex.addProxyObject(ipAddrUuid, "networkId");
|
|
throw ex;
|
|
}
|
|
}
|
|
ipToServices.put(ip, services);
|
|
|
|
// if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service
|
|
// provider
|
|
if (ip.getState() == State.Allocating) {
|
|
continue;
|
|
}
|
|
|
|
// check if any active rules are applied on the public IP
|
|
Set<Purpose> purposes = getPublicIpPurposeInRules(ip, false, includingFirewall);
|
|
// Firewall rules didn't cover static NAT
|
|
if (ip.isOneToOneNat() && ip.getAssociatedWithVmId() != null) {
|
|
if (purposes == null) {
|
|
purposes = new HashSet<Purpose>();
|
|
}
|
|
purposes.add(Purpose.StaticNat);
|
|
}
|
|
if (purposes == null || purposes.isEmpty()) {
|
|
// since no active rules are there check if any rules are applied on the public IP but are in
|
|
// revoking state
|
|
|
|
purposes = getPublicIpPurposeInRules(ip, true, includingFirewall);
|
|
if (ip.isOneToOneNat()) {
|
|
if (purposes == null) {
|
|
purposes = new HashSet<Purpose>();
|
|
}
|
|
purposes.add(Purpose.StaticNat);
|
|
}
|
|
if (purposes == null || purposes.isEmpty()) {
|
|
// IP is not being used for any purpose so skip IPAssoc to network service provider
|
|
continue;
|
|
} else {
|
|
if (postApplyRules) {
|
|
// no active rules/revoked rules are associated with this public IP, so remove the
|
|
// association with the provider
|
|
if (ip.isSourceNat()) {
|
|
s_logger.debug("Not releasing ip " + ip.getAddress().addr() + " as it is in use for SourceNat");
|
|
} else {
|
|
ip.setState(State.Releasing);
|
|
}
|
|
} else {
|
|
if (ip.getState() == State.Releasing) {
|
|
// rules are not revoked yet, so don't let the network service provider revoke the IP
|
|
// association
|
|
// mark IP is allocated so that IP association will not be removed from the provider
|
|
ip.setState(State.Allocated);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (purposes.contains(Purpose.StaticNat)) {
|
|
services.add(Service.StaticNat);
|
|
}
|
|
if (purposes.contains(Purpose.LoadBalancing)) {
|
|
services.add(Service.Lb);
|
|
}
|
|
if (purposes.contains(Purpose.PortForwarding)) {
|
|
services.add(Service.PortForwarding);
|
|
}
|
|
if (purposes.contains(Purpose.Vpn)) {
|
|
services.add(Service.Vpn);
|
|
}
|
|
if (purposes.contains(Purpose.Firewall)) {
|
|
services.add(Service.Firewall);
|
|
}
|
|
if (services.isEmpty()) {
|
|
continue;
|
|
}
|
|
ipToServices.put(ip, services);
|
|
}
|
|
}
|
|
return ipToServices;
|
|
}
|
|
|
|
public boolean canIpUsedForNonConserveService(PublicIp ip, Service service) {
|
|
// If it's non-conserve mode, then the new ip should not be used by any other services
|
|
List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
|
|
ipList.add(ip);
|
|
Map<PublicIpAddress, Set<Service>> ipToServices = getIpToServices(ipList, false, false);
|
|
Set<Service> services = ipToServices.get(ip);
|
|
// Not used currently, safe
|
|
if (services == null || services.isEmpty()) {
|
|
return true;
|
|
}
|
|
// Since it's non-conserve mode, only one service should used for IP
|
|
if (services.size() != 1) {
|
|
throw new InvalidParameterException("There are multiple services used ip " + ip.getAddress() + ".");
|
|
}
|
|
if (service != null && !((Service)services.toArray()[0] == service || service.equals(Service.Firewall))) {
|
|
throw new InvalidParameterException("The IP " + ip.getAddress() + " is already used as " + ((Service)services.toArray()[0]).getName() + " rather than " +
|
|
service.getName());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Map<Service, Set<Provider>> getServiceProvidersMap(long networkId) {
|
|
Map<Service, Set<Provider>> map = new HashMap<Service, Set<Provider>>();
|
|
List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
|
|
for (NetworkServiceMapVO nsm : nsms) {
|
|
Set<Provider> providers = map.get(Service.getService(nsm.getService()));
|
|
if (providers == null) {
|
|
providers = new HashSet<Provider>();
|
|
}
|
|
providers.add(Provider.getProvider(nsm.getProvider()));
|
|
map.put(Service.getService(nsm.getService()), providers);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
public boolean canIpUsedForService(PublicIp publicIp, Service service, Long networkId) {
|
|
List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
|
|
ipList.add(publicIp);
|
|
Map<PublicIpAddress, Set<Service>> ipToServices = getIpToServices(ipList, false, true);
|
|
Set<Service> services = ipToServices.get(publicIp);
|
|
if (services == null || services.isEmpty()) {
|
|
return true;
|
|
}
|
|
|
|
if (networkId == null) {
|
|
networkId = publicIp.getAssociatedWithNetworkId();
|
|
}
|
|
|
|
// We only support one provider for one service now
|
|
Map<Service, Set<Provider>> serviceToProviders = getServiceProvidersMap(networkId);
|
|
Set<Provider> oldProviders = serviceToProviders.get(services.toArray()[0]);
|
|
Provider oldProvider = (Provider)oldProviders.toArray()[0];
|
|
// Since IP already has service to bind with, the oldProvider can't be null
|
|
Set<Provider> newProviders = serviceToProviders.get(service);
|
|
if (newProviders == null || newProviders.isEmpty()) {
|
|
throw new InvalidParameterException("There is no new provider for IP " + publicIp.getAddress() + " of service " + service.getName() + "!");
|
|
}
|
|
Provider newProvider = (Provider)newProviders.toArray()[0];
|
|
Network network = _networksDao.findById(networkId);
|
|
NetworkElement oldElement = getElementImplementingProvider(oldProvider.getName());
|
|
NetworkElement newElement = getElementImplementingProvider(newProvider.getName());
|
|
if (oldElement instanceof IpDeployingRequester && newElement instanceof IpDeployingRequester) {
|
|
IpDeployer oldIpDeployer = ((IpDeployingRequester)oldElement).getIpDeployer(network);
|
|
IpDeployer newIpDeployer = ((IpDeployingRequester)newElement).getIpDeployer(network);
|
|
if (!oldIpDeployer.getProvider().getName().equals(newIpDeployer.getProvider().getName())) {
|
|
throw new InvalidParameterException("There would be multiple providers for IP " + publicIp.getAddress() + "!");
|
|
}
|
|
} else {
|
|
throw new InvalidParameterException("Ip cannot be applied for new provider!");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Map<Provider, Set<Service>> getProviderServicesMap(long networkId) {
|
|
Map<Provider, Set<Service>> map = new HashMap<Provider, Set<Service>>();
|
|
List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
|
|
for (NetworkServiceMapVO nsm : nsms) {
|
|
Set<Service> services = map.get(Provider.getProvider(nsm.getProvider()));
|
|
if (services == null) {
|
|
services = new HashSet<Service>();
|
|
}
|
|
services.add(Service.getService(nsm.getService()));
|
|
map.put(Provider.getProvider(nsm.getProvider()), services);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
@Override
|
|
public Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices) {
|
|
NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
|
if (!offering.isConserveMode()) {
|
|
for (PublicIpAddress ip : ipToServices.keySet()) {
|
|
Set<Service> services = new HashSet<Service>();
|
|
services.addAll(ipToServices.get(ip));
|
|
if (services != null && services.contains(Service.Firewall)) {
|
|
services.remove(Service.Firewall);
|
|
}
|
|
if (services != null && services.size() > 1) {
|
|
throw new CloudRuntimeException("Ip " + ip.getAddress() + " is used by multiple services!");
|
|
}
|
|
}
|
|
}
|
|
Map<Service, Set<PublicIpAddress>> serviceToIps = new HashMap<Service, Set<PublicIpAddress>>();
|
|
for (PublicIpAddress ip : ipToServices.keySet()) {
|
|
for (Service service : ipToServices.get(ip)) {
|
|
Set<PublicIpAddress> ips = serviceToIps.get(service);
|
|
if (ips == null) {
|
|
ips = new HashSet<PublicIpAddress>();
|
|
}
|
|
ips.add(ip);
|
|
serviceToIps.put(service, ips);
|
|
}
|
|
}
|
|
// TODO Check different provider for same IP
|
|
Map<Provider, Set<Service>> providerToServices = getProviderServicesMap(network.getId());
|
|
Map<Provider, ArrayList<PublicIpAddress>> providerToIpList = new HashMap<Provider, ArrayList<PublicIpAddress>>();
|
|
for (Provider provider : providerToServices.keySet()) {
|
|
if (!(getElementImplementingProvider(provider.getName()) instanceof IpDeployingRequester)) {
|
|
continue;
|
|
}
|
|
Set<Service> services = providerToServices.get(provider);
|
|
ArrayList<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
|
|
Set<PublicIpAddress> ipSet = new HashSet<PublicIpAddress>();
|
|
for (Service service : services) {
|
|
Set<PublicIpAddress> serviceIps = serviceToIps.get(service);
|
|
if (serviceIps == null || serviceIps.isEmpty()) {
|
|
continue;
|
|
}
|
|
ipSet.addAll(serviceIps);
|
|
}
|
|
Set<PublicIpAddress> sourceNatIps = serviceToIps.get(Service.SourceNat);
|
|
if (sourceNatIps != null && !sourceNatIps.isEmpty()) {
|
|
ipList.addAll(0, sourceNatIps);
|
|
ipSet.removeAll(sourceNatIps);
|
|
}
|
|
ipList.addAll(ipSet);
|
|
providerToIpList.put(provider, ipList);
|
|
}
|
|
return providerToIpList;
|
|
}
|
|
|
|
@Override
|
|
public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) {
|
|
SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
|
|
sc.setParameters("accountId", accountId);
|
|
sc.setParameters("associatedWithNetworkId", associatedNetworkId);
|
|
|
|
if (sourceNat != null) {
|
|
sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
|
|
}
|
|
sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
|
|
|
|
return _ipAddressDao.search(sc, null);
|
|
}
|
|
|
|
@Override
|
|
public List<IPAddressVO> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) {
|
|
SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
|
|
sc.setParameters("accountId", accountId);
|
|
sc.setParameters("dataCenterId", dcId);
|
|
|
|
if (sourceNat != null) {
|
|
sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
|
|
}
|
|
sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
|
|
|
|
return _ipAddressDao.search(sc, null);
|
|
}
|
|
|
|
@Override
|
|
public List<? extends Nic> getNics(long vmId) {
|
|
return _nicDao.listByVmId(vmId);
|
|
}
|
|
|
|
@Override
|
|
public String getNextAvailableMacAddressInNetwork(long networkId) throws InsufficientAddressCapacityException {
|
|
String mac = _networksDao.getNextAvailableMacAddress(networkId);
|
|
if (mac == null) {
|
|
throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId);
|
|
}
|
|
return mac;
|
|
}
|
|
|
|
@Override
|
|
@DB
|
|
public Network getNetwork(long id) {
|
|
return _networksDao.findById(id);
|
|
}
|
|
|
|
@Override
|
|
public boolean canUseForDeploy(Network network) {
|
|
if (network.getTrafficType() != TrafficType.Guest) {
|
|
return false;
|
|
}
|
|
boolean hasFreeIps = true;
|
|
if (network.getGuestType() == GuestType.Shared) {
|
|
if (network.getGateway() != null) {
|
|
hasFreeIps = _ipAddressDao.countFreeIPsInNetwork(network.getId()) > 0;
|
|
}
|
|
if (!hasFreeIps) {
|
|
return false;
|
|
}
|
|
if (network.getIp6Gateway() != null) {
|
|
hasFreeIps = isIP6AddressAvailableInNetwork(network.getId());
|
|
}
|
|
} else {
|
|
hasFreeIps = (getAvailableIps(network, null)).size() > 0;
|
|
}
|
|
|
|
return hasFreeIps;
|
|
}
|
|
|
|
@Override
|
|
public boolean isIP6AddressAvailableInNetwork(long networkId) {
|
|
Network network = _networksDao.findById(networkId);
|
|
if (network == null) {
|
|
return false;
|
|
}
|
|
if (network.getIp6Gateway() == null) {
|
|
return false;
|
|
}
|
|
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
|
|
for (Vlan vlan : vlans) {
|
|
if (isIP6AddressAvailableInVlan(vlan.getId())) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isIP6AddressAvailableInVlan(long vlanId) {
|
|
VlanVO vlan = _vlanDao.findById(vlanId);
|
|
if (vlan.getIp6Range() == null) {
|
|
return false;
|
|
}
|
|
long existedCount = _ipv6Dao.countExistedIpsInVlan(vlanId);
|
|
BigInteger existedInt = BigInteger.valueOf(existedCount);
|
|
BigInteger rangeInt = NetUtils.countIp6InRange(vlan.getIp6Range());
|
|
return (existedInt.compareTo(rangeInt) < 0);
|
|
}
|
|
|
|
@Override
|
|
public Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId) {
|
|
|
|
Map<Service, Map<Capability, String>> networkCapabilities = new HashMap<Service, Map<Capability, String>>();
|
|
|
|
// list all services of this networkOffering
|
|
List<NetworkServiceMapVO> servicesMap = _ntwkSrvcDao.getServicesInNetwork(networkId);
|
|
for (NetworkServiceMapVO instance : servicesMap) {
|
|
Service service = Service.getService(instance.getService());
|
|
NetworkElement element = getElementImplementingProvider(instance.getProvider());
|
|
if (element != null) {
|
|
Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
|
|
if (elementCapabilities != null) {
|
|
networkCapabilities.put(service, elementCapabilities.get(service));
|
|
}
|
|
}
|
|
}
|
|
|
|
return networkCapabilities;
|
|
}
|
|
|
|
@Override
|
|
public Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service) {
|
|
|
|
if (!areServicesSupportedInNetwork(networkId, service)) {
|
|
// TBD: networkId to uuid. No VO object being passed. So we will need to call
|
|
// addProxyObject with hardcoded tablename. Or we should probably look up the correct dao proxy object.
|
|
throw new UnsupportedServiceException("Service " + service.getName() + " is not supported in the network id=" + networkId);
|
|
}
|
|
|
|
Map<Capability, String> serviceCapabilities = new HashMap<Capability, String>();
|
|
|
|
// get the Provider for this Service for this offering
|
|
String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(networkId, service);
|
|
|
|
NetworkElement element = getElementImplementingProvider(provider);
|
|
if (element != null) {
|
|
Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
|
|
;
|
|
|
|
if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
|
|
throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
|
|
" implementing Provider=" + provider);
|
|
}
|
|
serviceCapabilities = elementCapabilities.get(service);
|
|
}
|
|
|
|
return serviceCapabilities;
|
|
}
|
|
|
|
@Override
|
|
public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
|
|
|
|
if (!areServicesSupportedByNetworkOffering(offering.getId(), service)) {
|
|
// TBD: We should be sending networkOfferingId and not the offering object itself.
|
|
throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the network offering " + offering);
|
|
}
|
|
|
|
Map<Capability, String> serviceCapabilities = new HashMap<Capability, String>();
|
|
|
|
// get the Provider for this Service for this offering
|
|
List<String> providers = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service);
|
|
if (providers.isEmpty()) {
|
|
// TBD: We should be sending networkOfferingId and not the offering object itself.
|
|
throw new InvalidParameterValueException("Service " + service.getName() + " is not supported by the network offering " + offering);
|
|
}
|
|
|
|
// FIXME - in post 3.0 we are going to support multiple providers for the same service per network offering, so
|
|
// we have to calculate capabilities for all of them
|
|
String provider = providers.get(0);
|
|
|
|
// FIXME we return the capabilities of the first provider of the service - what if we have multiple providers
|
|
// for same Service?
|
|
NetworkElement element = getElementImplementingProvider(provider);
|
|
if (element != null) {
|
|
Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
|
|
;
|
|
|
|
if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
|
|
// TBD: We should be sending providerId and not the offering object itself.
|
|
throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
|
|
" implementing Provider=" + provider);
|
|
}
|
|
serviceCapabilities = elementCapabilities.get(service);
|
|
}
|
|
|
|
return serviceCapabilities;
|
|
}
|
|
|
|
@Override
|
|
public NetworkVO getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
|
|
// find system public network offering
|
|
Long networkOfferingId = null;
|
|
List<NetworkOfferingVO> offerings = _networkOfferingDao.listSystemNetworkOfferings();
|
|
for (NetworkOfferingVO offering : offerings) {
|
|
if (offering.getTrafficType() == trafficType) {
|
|
networkOfferingId = offering.getId();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (networkOfferingId == null) {
|
|
throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType);
|
|
}
|
|
|
|
List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId);
|
|
if (networks == null || networks.isEmpty()) {
|
|
// TBD: send uuid instead of zoneId. Hardcode tablename in call to addProxyObject().
|
|
throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId);
|
|
}
|
|
return networks.get(0);
|
|
}
|
|
|
|
@Override
|
|
public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) {
|
|
List<NetworkVO> networks = _networksDao.listByZoneSecurityGroup(zoneId);
|
|
if (networks == null || networks.isEmpty()) {
|
|
return null;
|
|
}
|
|
|
|
if (networks.size() > 1) {
|
|
s_logger.debug("There are multiple network with security group enabled? select one of them...");
|
|
}
|
|
return networks.get(0);
|
|
}
|
|
|
|
@Override
|
|
public PublicIpAddress getPublicIpAddress(long ipAddressId) {
|
|
IPAddressVO addr = _ipAddressDao.findById(ipAddressId);
|
|
if (addr == null) {
|
|
return null;
|
|
}
|
|
|
|
return PublicIp.createFromAddrAndVlan(addr, _vlanDao.findById(addr.getVlanId()));
|
|
}
|
|
|
|
@Override
|
|
public List<VlanVO> listPodVlans(long podId) {
|
|
List<VlanVO> vlans = _vlanDao.listVlansForPodByType(podId, VlanType.DirectAttached);
|
|
return vlans;
|
|
}
|
|
|
|
@Override
|
|
public List<NetworkVO> listNetworksUsedByVm(long vmId, boolean isSystem) {
|
|
List<NetworkVO> networks = new ArrayList<NetworkVO>();
|
|
|
|
List<NicVO> nics = _nicDao.listByVmId(vmId);
|
|
if (nics != null) {
|
|
for (Nic nic : nics) {
|
|
NetworkVO network = _networksDao.findByIdIncludingRemoved(nic.getNetworkId());
|
|
|
|
if (isNetworkSystem(network) == isSystem) {
|
|
networks.add(network);
|
|
}
|
|
}
|
|
}
|
|
|
|
return networks;
|
|
}
|
|
|
|
@Override
|
|
public Nic getNicInNetwork(long vmId, long networkId) {
|
|
return _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
|
|
}
|
|
|
|
@Override
|
|
public String getIpInNetwork(long vmId, long networkId) {
|
|
Nic guestNic = getNicInNetwork(vmId, networkId);
|
|
assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with " + "ipAddress or ip4 address is null";
|
|
return guestNic.getIp4Address();
|
|
}
|
|
|
|
@Override
|
|
public String getIpInNetworkIncludingRemoved(long vmId, long networkId) {
|
|
Nic guestNic = getNicInNetworkIncludingRemoved(vmId, networkId);
|
|
assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with " + "ipAddress or ip4 address is null";
|
|
return guestNic.getIp4Address();
|
|
}
|
|
|
|
@Override
|
|
public List<NicVO> getNicsForTraffic(long vmId, TrafficType type) {
|
|
SearchCriteria<NicVO> sc = NicForTrafficTypeSearch.create();
|
|
sc.setParameters("instance", vmId);
|
|
sc.setJoinParameters("network", "traffictype", type);
|
|
|
|
return _nicDao.search(sc, null);
|
|
}
|
|
|
|
@Override
|
|
public IpAddress getIp(long ipAddressId) {
|
|
return _ipAddressDao.findById(ipAddressId);
|
|
}
|
|
|
|
@Override
|
|
public Network getDefaultNetworkForVm(long vmId) {
|
|
Nic defaultNic = getDefaultNic(vmId);
|
|
if (defaultNic == null) {
|
|
return null;
|
|
} else {
|
|
return _networksDao.findById(defaultNic.getNetworkId());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Nic getDefaultNic(long vmId) {
|
|
List<NicVO> nics = _nicDao.listByVmId(vmId);
|
|
Nic defaultNic = null;
|
|
if (nics != null) {
|
|
for (Nic nic : nics) {
|
|
if (nic.isDefaultNic()) {
|
|
defaultNic = nic;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
s_logger.debug("Unable to find default network for the vm; vm doesn't have any nics");
|
|
return null;
|
|
}
|
|
|
|
if (defaultNic == null) {
|
|
s_logger.debug("Unable to find default network for the vm; vm doesn't have default nic");
|
|
}
|
|
|
|
return defaultNic;
|
|
|
|
}
|
|
|
|
@Override
|
|
public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
|
|
String userDataProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
|
|
|
|
if (userDataProvider == null) {
|
|
s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
|
|
return null;
|
|
}
|
|
|
|
return (UserDataServiceProvider)getElementImplementingProvider(userDataProvider);
|
|
}
|
|
|
|
@Override
|
|
public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
|
|
return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services));
|
|
}
|
|
|
|
@Override
|
|
public boolean areServicesSupportedInNetwork(long networkId, Service... services) {
|
|
return (_ntwkSrvcDao.areServicesSupportedInNetwork(networkId, services));
|
|
}
|
|
|
|
@Override
|
|
public String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId) {
|
|
|
|
List<NetworkVO> virtualNetworks = _networksDao.listByZoneAndGuestType(accountId, dataCenterId, Network.GuestType.Isolated, false);
|
|
|
|
if (virtualNetworks.isEmpty()) {
|
|
s_logger.trace("Unable to find default Virtual network account id=" + accountId);
|
|
return null;
|
|
}
|
|
|
|
NetworkVO virtualNetwork = virtualNetworks.get(0);
|
|
|
|
NicVO networkElementNic = _nicDao.findByNetworkIdAndType(virtualNetwork.getId(), Type.DomainRouter);
|
|
|
|
if (networkElementNic != null) {
|
|
return networkElementNic.getIp4Address();
|
|
} else {
|
|
s_logger.warn("Unable to set find network element for the network id=" + virtualNetwork.getId());
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, Network.GuestType type) {
|
|
List<NetworkVO> accountNetworks = new ArrayList<NetworkVO>();
|
|
List<NetworkVO> zoneNetworks = _networksDao.listByZone(zoneId);
|
|
|
|
for (NetworkVO network : zoneNetworks) {
|
|
if (!isNetworkSystem(network)) {
|
|
if (network.getGuestType() == Network.GuestType.Shared || !_networksDao.listBy(accountId, network.getId()).isEmpty()) {
|
|
if (type == null || type == network.getGuestType()) {
|
|
accountNetworks.add(network);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return accountNetworks;
|
|
}
|
|
|
|
@Override
|
|
public List<NetworkVO> listAllNetworksInAllZonesByType(Network.GuestType type) {
|
|
List<NetworkVO> networks = new ArrayList<NetworkVO>();
|
|
for (NetworkVO network : _networksDao.listAll()) {
|
|
if (!isNetworkSystem(network)) {
|
|
networks.add(network);
|
|
}
|
|
}
|
|
return networks;
|
|
}
|
|
|
|
@Override
|
|
public Long getDedicatedNetworkDomain(long networkId) {
|
|
NetworkDomainVO networkMaps = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
|
|
if (networkMaps != null) {
|
|
return networkMaps.getDomainId();
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Integer getNetworkRate(long networkId, Long vmId) {
|
|
VMInstanceVO vm = null;
|
|
if (vmId != null) {
|
|
vm = _vmDao.findById(vmId);
|
|
}
|
|
Network network = getNetwork(networkId);
|
|
NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
|
|
|
|
// For default userVm Default network and domR guest/public network, get rate information from the service
|
|
// offering; for other situations get information
|
|
// from the network offering
|
|
boolean isUserVmsDefaultNetwork = false;
|
|
boolean isDomRGuestOrPublicNetwork = false;
|
|
boolean isSystemVmNetwork = false;
|
|
if (vm != null) {
|
|
Nic nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
|
|
if (vm.getType() == Type.User && nic != null && nic.isDefaultNic()) {
|
|
isUserVmsDefaultNetwork = true;
|
|
} else if (vm.getType() == Type.DomainRouter && ntwkOff != null &&
|
|
(ntwkOff.getTrafficType() == TrafficType.Public || ntwkOff.getTrafficType() == TrafficType.Guest)) {
|
|
isDomRGuestOrPublicNetwork = true;
|
|
} else if (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm) {
|
|
isSystemVmNetwork = true;
|
|
}
|
|
}
|
|
if (isUserVmsDefaultNetwork || isDomRGuestOrPublicNetwork) {
|
|
return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), network.getDataCenterId());
|
|
} else if (isSystemVmNetwork) {
|
|
return -1;
|
|
} else {
|
|
return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId(), network.getDataCenterId());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getAccountNetworkDomain(long accountId, long zoneId) {
|
|
String networkDomain = _accountDao.findById(accountId).getNetworkDomain();
|
|
|
|
if (networkDomain == null) {
|
|
// get domain level network domain
|
|
return getDomainNetworkDomain(_accountDao.findById(accountId).getDomainId(), zoneId);
|
|
}
|
|
|
|
return networkDomain;
|
|
}
|
|
|
|
@Override
|
|
public String getStartIpAddress(long networkId) {
|
|
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
|
|
if (vlans.isEmpty()) {
|
|
return null;
|
|
}
|
|
|
|
String startIP = vlans.get(0).getIpRange().split("-")[0];
|
|
|
|
for (VlanVO vlan : vlans) {
|
|
String startIP1 = vlan.getIpRange().split("-")[0];
|
|
long startIPLong = NetUtils.ip2Long(startIP);
|
|
long startIPLong1 = NetUtils.ip2Long(startIP1);
|
|
|
|
if (startIPLong1 < startIPLong) {
|
|
startIP = startIP1;
|
|
}
|
|
}
|
|
|
|
return startIP;
|
|
}
|
|
|
|
@Override
|
|
public Long getPodIdForVlan(long vlanDbId) {
|
|
PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(vlanDbId);
|
|
if (podVlanMaps == null) {
|
|
return null;
|
|
} else {
|
|
return podVlanMaps.getPodId();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId) {
|
|
Map<Service, Set<Provider>> serviceProviderMap = new HashMap<Service, Set<Provider>>();
|
|
List<NetworkOfferingServiceMapVO> map = _ntwkOfferingSrvcDao.listByNetworkOfferingId(networkOfferingId);
|
|
|
|
for (NetworkOfferingServiceMapVO instance : map) {
|
|
String service = instance.getService();
|
|
Set<Provider> providers;
|
|
providers = serviceProviderMap.get(service);
|
|
if (providers == null) {
|
|
providers = new HashSet<Provider>();
|
|
}
|
|
providers.add(Provider.getProvider(instance.getProvider()));
|
|
serviceProviderMap.put(Service.getService(service), providers);
|
|
}
|
|
|
|
return serviceProviderMap;
|
|
}
|
|
|
|
@Override
|
|
public boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider) {
|
|
return _ntwkSrvcDao.canProviderSupportServiceInNetwork(networkId, service, provider);
|
|
}
|
|
|
|
@Override
|
|
public List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName) {
|
|
Network.Service service = null;
|
|
if (serviceName != null) {
|
|
service = Network.Service.getService(serviceName);
|
|
if (service == null) {
|
|
throw new InvalidParameterValueException("Invalid Network Service=" + serviceName);
|
|
}
|
|
}
|
|
|
|
Set<Provider> supportedProviders = new HashSet<Provider>();
|
|
|
|
if (service != null) {
|
|
List<Provider> providers = s_serviceToImplementedProvidersMap.get(service);
|
|
if (providers != null && !providers.isEmpty()) {
|
|
supportedProviders.addAll(providers);
|
|
}
|
|
} else {
|
|
for (List<Provider> pList : s_serviceToImplementedProvidersMap.values()) {
|
|
supportedProviders.addAll(pList);
|
|
}
|
|
}
|
|
|
|
return new ArrayList<Provider>(supportedProviders);
|
|
}
|
|
|
|
@Override
|
|
public Provider getDefaultUniqueProviderForService(String serviceName) {
|
|
List<? extends Provider> providers = listSupportedNetworkServiceProviders(serviceName);
|
|
if (providers.isEmpty()) {
|
|
throw new CloudRuntimeException("No providers supporting service " + serviceName + " found in cloudStack");
|
|
}
|
|
if (providers.size() > 1) {
|
|
throw new CloudRuntimeException("More than 1 provider supporting service " + serviceName + " found in cloudStack");
|
|
}
|
|
|
|
return providers.get(0);
|
|
}
|
|
|
|
@Override
|
|
public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
|
|
List<PhysicalNetworkVO> pNtwks = new ArrayList<PhysicalNetworkVO>();
|
|
if (trafficType != null) {
|
|
pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
|
|
} else {
|
|
pNtwks = _physicalNetworkDao.listByZone(zoneId);
|
|
}
|
|
|
|
if (pNtwks.isEmpty()) {
|
|
throw new InvalidParameterValueException("Unable to find physical network in zone id=" + zoneId);
|
|
}
|
|
|
|
if (pNtwks.size() > 1) {
|
|
if (tag == null) {
|
|
throw new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId +
|
|
" and no tags are specified in order to make a choice");
|
|
}
|
|
|
|
Long pNtwkId = null;
|
|
for (PhysicalNetwork pNtwk : pNtwks) {
|
|
if (pNtwk.getTags().contains(tag)) {
|
|
s_logger.debug("Found physical network id=" + pNtwk.getId() + " based on requested tags " + tag);
|
|
pNtwkId = pNtwk.getId();
|
|
break;
|
|
}
|
|
}
|
|
if (pNtwkId == null) {
|
|
throw new InvalidParameterValueException("Unable to find physical network which match the tags " + tag);
|
|
}
|
|
return pNtwkId;
|
|
} else {
|
|
return pNtwks.get(0).getId();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public List<Long> listNetworkOfferingsForUpgrade(long networkId) {
|
|
List<Long> offeringsToReturn = new ArrayList<Long>();
|
|
NetworkOffering originalOffering = _entityMgr.findById(NetworkOffering.class, getNetwork(networkId).getNetworkOfferingId());
|
|
|
|
boolean securityGroupSupportedByOriginalOff = areServicesSupportedByNetworkOffering(originalOffering.getId(), Service.SecurityGroup);
|
|
|
|
// security group supported property should be the same
|
|
|
|
List<Long> offerings = _networkOfferingDao.getOfferingIdsToUpgradeFrom(originalOffering);
|
|
|
|
for (Long offeringId : offerings) {
|
|
if (areServicesSupportedByNetworkOffering(offeringId, Service.SecurityGroup) == securityGroupSupportedByOriginalOff) {
|
|
offeringsToReturn.add(offeringId);
|
|
}
|
|
}
|
|
|
|
return offeringsToReturn;
|
|
}
|
|
|
|
@Override
|
|
public boolean isSecurityGroupSupportedInNetwork(Network network) {
|
|
if (network.getTrafficType() != TrafficType.Guest) {
|
|
s_logger.trace("Security group can be enabled for Guest networks only; and network " + network + " has a diff traffic type");
|
|
return false;
|
|
}
|
|
|
|
Long physicalNetworkId = network.getPhysicalNetworkId();
|
|
|
|
// physical network id can be null in Guest Network in Basic zone, so locate the physical network
|
|
if (physicalNetworkId == null) {
|
|
physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), null, null);
|
|
}
|
|
|
|
return isServiceEnabledInNetwork(physicalNetworkId, network.getId(), Service.SecurityGroup);
|
|
}
|
|
|
|
@Override
|
|
public PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
|
|
|
|
List<PhysicalNetworkVO> networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
|
|
DataCenter dc = ApiDBUtils.findZoneById(zoneId);
|
|
String dcUuid = String.valueOf(zoneId);
|
|
if (dc != null) {
|
|
dcUuid = dc.getUuid();
|
|
}
|
|
|
|
if (networkList.isEmpty()) {
|
|
InvalidParameterValueException ex =
|
|
new InvalidParameterValueException("Unable to find the default physical network with traffic=" + trafficType + " in the specified zone id");
|
|
ex.addProxyObject(dcUuid, "zoneId");
|
|
throw ex;
|
|
}
|
|
|
|
if (networkList.size() > 1) {
|
|
InvalidParameterValueException ex =
|
|
new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId + " with traffic type=" + trafficType);
|
|
ex.addProxyObject(dcUuid, "zoneId");
|
|
throw ex;
|
|
}
|
|
|
|
return networkList.get(0);
|
|
}
|
|
|
|
@Override
|
|
public String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType) {
|
|
try {
|
|
PhysicalNetwork mgmtPhyNetwork = getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Management);
|
|
PhysicalNetworkTrafficTypeVO mgmtTraffic = _pNTrafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management);
|
|
if (mgmtTraffic != null) {
|
|
String label = null;
|
|
switch (hypervisorType) {
|
|
case XenServer:
|
|
label = mgmtTraffic.getXenNetworkLabel();
|
|
break;
|
|
case KVM:
|
|
label = mgmtTraffic.getKvmNetworkLabel();
|
|
break;
|
|
case VMware:
|
|
label = mgmtTraffic.getVmwareNetworkLabel();
|
|
break;
|
|
case Hyperv:
|
|
label = mgmtTraffic.getHypervNetworkLabel();
|
|
break;
|
|
}
|
|
return label;
|
|
}
|
|
} catch (Exception ex) {
|
|
if (s_logger.isDebugEnabled()) {
|
|
s_logger.debug("Failed to retrive the default label for management traffic:" + "zone: " + zoneId + " hypervisor: " + hypervisorType + " due to:" +
|
|
ex.getMessage());
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType) {
|
|
try {
|
|
PhysicalNetwork storagePhyNetwork = getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage);
|
|
PhysicalNetworkTrafficTypeVO storageTraffic = _pNTrafficTypeDao.findBy(storagePhyNetwork.getId(), TrafficType.Storage);
|
|
if (storageTraffic != null) {
|
|
String label = null;
|
|
switch (hypervisorType) {
|
|
case XenServer:
|
|
label = storageTraffic.getXenNetworkLabel();
|
|
break;
|
|
case KVM:
|
|
label = storageTraffic.getKvmNetworkLabel();
|
|
break;
|
|
case VMware:
|
|
label = storageTraffic.getVmwareNetworkLabel();
|
|
break;
|
|
case Hyperv:
|
|
label = storageTraffic.getHypervNetworkLabel();
|
|
break;
|
|
}
|
|
return label;
|
|
}
|
|
} catch (Exception ex) {
|
|
if (s_logger.isDebugEnabled()) {
|
|
s_logger.debug("Failed to retrive the default label for storage traffic:" + "zone: " + zoneId + " hypervisor: " + hypervisorType + " due to:" +
|
|
ex.getMessage());
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) {
|
|
List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
|
|
List<PhysicalNetworkVO> physicalNtwkList = _physicalNetworkDao.listByZone(dcId);
|
|
for (PhysicalNetworkVO pNtwk : physicalNtwkList) {
|
|
String publicName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Public, hypervisorType);
|
|
String privateName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Management, hypervisorType);
|
|
String guestName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Guest, hypervisorType);
|
|
String storageName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Storage, hypervisorType);
|
|
// String controlName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Control, hypervisorType);
|
|
PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo();
|
|
info.setPhysicalNetworkId(pNtwk.getId());
|
|
info.setGuestNetworkName(guestName);
|
|
info.setPrivateNetworkName(privateName);
|
|
info.setPublicNetworkName(publicName);
|
|
info.setStorageNetworkName(storageName);
|
|
PhysicalNetworkTrafficTypeVO mgmtTraffic = _pNTrafficTypeDao.findBy(pNtwk.getId(), TrafficType.Management);
|
|
if (mgmtTraffic != null) {
|
|
String vlan = mgmtTraffic.getVlan();
|
|
info.setMgmtVlan(vlan);
|
|
}
|
|
networkInfoList.add(info);
|
|
}
|
|
return networkInfoList;
|
|
}
|
|
|
|
@Override
|
|
public boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName) {
|
|
PhysicalNetworkServiceProviderVO ntwkSvcProvider = _pNSPDao.findByServiceProvider(physicalNetowrkId, providerName);
|
|
if (ntwkSvcProvider == null) {
|
|
s_logger.warn("Unable to find provider " + providerName + " in physical network id=" + physicalNetowrkId);
|
|
return false;
|
|
}
|
|
return isProviderEnabled(ntwkSvcProvider);
|
|
}
|
|
|
|
@Override
|
|
public boolean isProviderEnabledInZone(long zoneId, String provider) {
|
|
//the provider has to be enabled at least in one network in the zone
|
|
for (PhysicalNetwork pNtwk : _physicalNetworkDao.listByZone(zoneId)) {
|
|
if (isProviderEnabledInPhysicalNetwork(pNtwk.getId(), provider)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public String getNetworkTag(HypervisorType hType, Network network) {
|
|
// no network tag for control traffic type
|
|
TrafficType effectiveTrafficType = network.getTrafficType();
|
|
if (hType == HypervisorType.VMware && effectiveTrafficType == TrafficType.Control)
|
|
effectiveTrafficType = TrafficType.Management;
|
|
|
|
if (effectiveTrafficType == TrafficType.Control) {
|
|
return null;
|
|
}
|
|
|
|
Long physicalNetworkId = null;
|
|
if (effectiveTrafficType != TrafficType.Guest) {
|
|
physicalNetworkId = getNonGuestNetworkPhysicalNetworkId(network, effectiveTrafficType);
|
|
} else {
|
|
NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
|
|
physicalNetworkId = network.getPhysicalNetworkId();
|
|
if (physicalNetworkId == null) {
|
|
physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), offering.getTags(), offering.getTrafficType());
|
|
}
|
|
}
|
|
|
|
if (physicalNetworkId == null) {
|
|
assert (false) : "Can't get the physical network";
|
|
s_logger.warn("Can't get the physical network");
|
|
return null;
|
|
}
|
|
|
|
return _pNTrafficTypeDao.getNetworkTag(physicalNetworkId, effectiveTrafficType, hType);
|
|
}
|
|
|
|
@Override
|
|
public NetworkVO getExclusiveGuestNetwork(long zoneId) {
|
|
List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, zoneId, GuestType.Shared, TrafficType.Guest);
|
|
if (networks == null || networks.isEmpty()) {
|
|
throw new InvalidParameterValueException("Unable to find network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared + " in zone " +
|
|
zoneId);
|
|
}
|
|
|
|
if (networks.size() > 1) {
|
|
throw new InvalidParameterValueException("Found more than 1 network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared +
|
|
" in zone " + zoneId);
|
|
|
|
}
|
|
|
|
return networks.get(0);
|
|
}
|
|
|
|
@Override
|
|
public boolean isNetworkSystem(Network network) {
|
|
NetworkOffering no = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
|
|
if (no.isSystemOnly()) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Long getPhysicalNetworkId(Network network) {
|
|
if (network.getTrafficType() != TrafficType.Guest) {
|
|
return getNonGuestNetworkPhysicalNetworkId(network);
|
|
}
|
|
|
|
Long physicalNetworkId = network.getPhysicalNetworkId();
|
|
NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
|
|
if (physicalNetworkId == null) {
|
|
physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), offering.getTags(), offering.getTrafficType());
|
|
}
|
|
return physicalNetworkId;
|
|
}
|
|
|
|
@Override
|
|
public boolean getAllowSubdomainAccessGlobal() {
|
|
return _allowSubdomainNetworkAccess;
|
|
}
|
|
|
|
@Override
|
|
public boolean isProviderForNetwork(Provider provider, long networkId) {
|
|
if (_ntwkSrvcDao.isProviderForNetwork(networkId, provider) != null) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId) {
|
|
if (_ntwkOfferingSrvcDao.isProviderForNetworkOffering(networkOfferingId, provider)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void canProviderSupportServices(Map<Provider, Set<Service>> providersMap) {
|
|
for (Provider provider : providersMap.keySet()) {
|
|
// check if services can be turned off
|
|
NetworkElement element = getElementImplementingProvider(provider.getName());
|
|
if (element == null) {
|
|
throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
|
|
}
|
|
|
|
Set<Service> enabledServices = new HashSet<Service>();
|
|
enabledServices.addAll(providersMap.get(provider));
|
|
|
|
if (enabledServices != null && !enabledServices.isEmpty()) {
|
|
if (!element.canEnableIndividualServices()) {
|
|
Set<Service> requiredServices = new HashSet<Service>();
|
|
requiredServices.addAll(element.getCapabilities().keySet());
|
|
|
|
if (requiredServices.contains(Network.Service.Gateway)) {
|
|
requiredServices.remove(Network.Service.Gateway);
|
|
}
|
|
|
|
if (requiredServices.contains(Network.Service.Firewall)) {
|
|
requiredServices.remove(Network.Service.Firewall);
|
|
}
|
|
|
|
if (enabledServices.contains(Network.Service.Firewall)) {
|
|
enabledServices.remove(Network.Service.Firewall);
|
|
}
|
|
|
|
// exclude gateway service
|
|
if (enabledServices.size() != requiredServices.size()) {
|
|
StringBuilder servicesSet = new StringBuilder();
|
|
|
|
for (Service requiredService : requiredServices) {
|
|
// skip gateway service as we don't allow setting it via API
|
|
if (requiredService == Service.Gateway) {
|
|
continue;
|
|
}
|
|
servicesSet.append(requiredService.getName() + ", ");
|
|
}
|
|
servicesSet.delete(servicesSet.toString().length() - 2, servicesSet.toString().length());
|
|
|
|
throw new InvalidParameterValueException("Cannot enable subset of Services, Please specify the complete list of Services: " +
|
|
servicesSet.toString() + " for Service Provider " + provider.getName());
|
|
}
|
|
}
|
|
List<String> serviceList = new ArrayList<String>();
|
|
for (Service service : enabledServices) {
|
|
// check if the service is provided by this Provider
|
|
if (!element.getCapabilities().containsKey(service)) {
|
|
throw new UnsupportedServiceException(provider.getName() + " Provider cannot provide service " + service.getName());
|
|
}
|
|
serviceList.add(service.getName());
|
|
}
|
|
if (!element.verifyServicesCombination(enabledServices)) {
|
|
throw new UnsupportedServiceException("Provider " + provider.getName() + " doesn't support services combination: " + serviceList);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean canAddDefaultSecurityGroup() {
|
|
String defaultAdding = _configDao.getValue(Config.SecurityGroupDefaultAdding.key());
|
|
return (defaultAdding != null && defaultAdding.equalsIgnoreCase("true"));
|
|
}
|
|
|
|
@Override
|
|
public List<Service> listNetworkOfferingServices(long networkOfferingId) {
|
|
List<Service> services = new ArrayList<Service>();
|
|
List<String> servicesStr = _ntwkOfferingSrvcDao.listServicesForNetworkOffering(networkOfferingId);
|
|
for (String serviceStr : servicesStr) {
|
|
services.add(Service.getService(serviceStr));
|
|
}
|
|
|
|
return services;
|
|
}
|
|
|
|
@Override
|
|
public boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services) {
|
|
long physicalNtwkId = findPhysicalNetworkId(zoneId, offering.getTags(), offering.getTrafficType());
|
|
boolean result = true;
|
|
List<String> checkedProvider = new ArrayList<String>();
|
|
for (Service service : services) {
|
|
// get all the providers, and check if each provider is enabled
|
|
List<String> providerNames = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service);
|
|
for (String providerName : providerNames) {
|
|
if (!checkedProvider.contains(providerName)) {
|
|
result = result && isProviderEnabledInPhysicalNetwork(physicalNtwkId, providerName);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public boolean checkIpForService(IpAddress userIp, Service service, Long networkId) {
|
|
if (networkId == null) {
|
|
networkId = userIp.getAssociatedWithNetworkId();
|
|
}
|
|
|
|
NetworkVO network = _networksDao.findById(networkId);
|
|
NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
|
if (offering.getGuestType() != GuestType.Isolated) {
|
|
return true;
|
|
}
|
|
IPAddressVO ipVO = _ipAddressDao.findById(userIp.getId());
|
|
PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipVO, _vlanDao.findById(userIp.getVlanId()));
|
|
if (!canIpUsedForService(publicIp, service, networkId)) {
|
|
return false;
|
|
}
|
|
if (!offering.isConserveMode()) {
|
|
return canIpUsedForNonConserveService(publicIp, service);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue) {
|
|
for (Provider provider : providers) {
|
|
NetworkElement element = getElementImplementingProvider(provider.getName());
|
|
if (element != null) {
|
|
Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
|
|
if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
|
|
throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
|
|
" implementing Provider=" + provider.getName());
|
|
}
|
|
Map<Capability, String> serviceCapabilities = elementCapabilities.get(service);
|
|
if (serviceCapabilities == null || serviceCapabilities.isEmpty()) {
|
|
throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capabilites for element=" + element.getName() +
|
|
" implementing Provider=" + provider.getName());
|
|
}
|
|
|
|
String value = serviceCapabilities.get(cap);
|
|
if (value == null || value.isEmpty()) {
|
|
throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capability " + cap.getName() + " for element=" +
|
|
element.getName() + " implementing Provider=" + provider.getName());
|
|
}
|
|
|
|
if (!value.toLowerCase().contains(capValue.toLowerCase())) {
|
|
throw new UnsupportedServiceException("Service " + service.getName() + " doesn't support value " + capValue + " for capability " + cap.getName() +
|
|
" for element=" + element.getName() + " implementing Provider=" + provider.getName());
|
|
}
|
|
} else {
|
|
throw new UnsupportedServiceException("Unable to find network element for provider " + provider.getName());
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void checkNetworkPermissions(Account owner, Network network) {
|
|
// Perform account permission check
|
|
if (network.getGuestType() != Network.GuestType.Shared || (network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Account)) {
|
|
AccountVO networkOwner = _accountDao.findById(network.getAccountId());
|
|
if (networkOwner == null)
|
|
throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
|
|
", network does not have an owner");
|
|
if (owner.getType() != Account.ACCOUNT_TYPE_PROJECT && networkOwner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
|
if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), network.getAccountId())) {
|
|
throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
|
|
", permission denied");
|
|
}
|
|
} else {
|
|
List<NetworkVO> networkMap = _networksDao.listBy(owner.getId(), network.getId());
|
|
if (networkMap == null || networkMap.isEmpty()) {
|
|
throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
|
|
", permission denied");
|
|
}
|
|
}
|
|
|
|
} else {
|
|
if (!isNetworkAvailableInDomain(network.getId(), owner.getDomainId())) {
|
|
throw new PermissionDeniedException("Shared network id=" + ((network != null) ? ((NetworkVO)network).getUuid() : "") + " is not available in domain id=" +
|
|
owner.getDomainId());
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getDefaultPublicTrafficLabel(long dcId, HypervisorType hypervisorType) {
|
|
try {
|
|
PhysicalNetwork publicPhyNetwork = getOnePhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public);
|
|
PhysicalNetworkTrafficTypeVO publicTraffic = _pNTrafficTypeDao.findBy(publicPhyNetwork.getId(), TrafficType.Public);
|
|
if (publicTraffic != null) {
|
|
String label = null;
|
|
switch (hypervisorType) {
|
|
case XenServer:
|
|
label = publicTraffic.getXenNetworkLabel();
|
|
break;
|
|
case KVM:
|
|
label = publicTraffic.getKvmNetworkLabel();
|
|
break;
|
|
case VMware:
|
|
label = publicTraffic.getVmwareNetworkLabel();
|
|
break;
|
|
case Hyperv:
|
|
label = publicTraffic.getHypervNetworkLabel();
|
|
break;
|
|
}
|
|
return label;
|
|
}
|
|
} catch (Exception ex) {
|
|
if (s_logger.isDebugEnabled()) {
|
|
s_logger.debug("Failed to retrieve the default label for public traffic." + "zone: " + dcId + " hypervisor: " + hypervisorType + " due to: " +
|
|
ex.getMessage());
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public String getDefaultGuestTrafficLabel(long dcId, HypervisorType hypervisorType) {
|
|
try {
|
|
PhysicalNetwork guestPhyNetwork = getOnePhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Guest);
|
|
PhysicalNetworkTrafficTypeVO guestTraffic = _pNTrafficTypeDao.findBy(guestPhyNetwork.getId(), TrafficType.Guest);
|
|
if (guestTraffic != null) {
|
|
String label = null;
|
|
switch (hypervisorType) {
|
|
case XenServer:
|
|
label = guestTraffic.getXenNetworkLabel();
|
|
break;
|
|
case KVM:
|
|
label = guestTraffic.getKvmNetworkLabel();
|
|
break;
|
|
case VMware:
|
|
label = guestTraffic.getVmwareNetworkLabel();
|
|
break;
|
|
case Hyperv:
|
|
label = guestTraffic.getHypervNetworkLabel();
|
|
break;
|
|
|
|
}
|
|
return label;
|
|
}
|
|
} catch (Exception ex) {
|
|
if (s_logger.isDebugEnabled()) {
|
|
s_logger.debug("Failed to retrive the default label for management traffic:" + "zone: " + dcId + " hypervisor: " + hypervisorType + " due to:" +
|
|
ex.getMessage());
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public List<? extends Network> listNetworksByVpc(long vpcId) {
|
|
return _networksDao.listByVpc(vpcId);
|
|
}
|
|
|
|
@Override
|
|
public List<Provider> getNtwkOffDistinctProviders(long ntkwOffId) {
|
|
List<String> providerNames = _ntwkOfferingSrvcDao.getDistinctProviders(ntkwOffId);
|
|
List<Provider> providers = new ArrayList<Provider>();
|
|
for (String providerName : providerNames) {
|
|
providers.add(Network.Provider.getProvider(providerName));
|
|
}
|
|
|
|
return providers;
|
|
}
|
|
|
|
@Override
|
|
public boolean isVmPartOfNetwork(long vmId, long ntwkId) {
|
|
if (_nicDao.findNonReleasedByInstanceIdAndNetworkId(ntwkId, vmId) != null) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) {
|
|
|
|
List<? extends PhysicalNetwork> pNtwks = _physicalNetworkDao.listByZone(zoneId);
|
|
|
|
Iterator<? extends PhysicalNetwork> it = pNtwks.iterator();
|
|
while (it.hasNext()) {
|
|
PhysicalNetwork pNtwk = it.next();
|
|
if (!_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), trafficType)) {
|
|
it.remove();
|
|
}
|
|
}
|
|
return pNtwks;
|
|
}
|
|
|
|
@Override
|
|
public boolean isPrivateGateway(Nic guestNic) {
|
|
Network network = getNetwork(guestNic.getNetworkId());
|
|
if (network.getTrafficType() != TrafficType.Guest || network.getNetworkOfferingId() != _privateOfferingId.longValue()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public List<NetworkOfferingVO> getSystemAccountNetworkOfferings(String... offeringNames) {
|
|
List<NetworkOfferingVO> offerings = new ArrayList<NetworkOfferingVO>(offeringNames.length);
|
|
for (String offeringName : offeringNames) {
|
|
NetworkOfferingVO network = _systemNetworks.get(offeringName);
|
|
if (network == null) {
|
|
throw new CloudRuntimeException("Unable to find system network profile for " + offeringName);
|
|
}
|
|
offerings.add(network);
|
|
}
|
|
return offerings;
|
|
}
|
|
|
|
@Override
|
|
public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
|
|
Long networkDomainId = null;
|
|
Network network = getNetwork(networkId);
|
|
if (network.getGuestType() != Network.GuestType.Shared) {
|
|
s_logger.trace("Network id=" + networkId + " is not shared");
|
|
return false;
|
|
}
|
|
|
|
NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
|
|
if (networkDomainMap == null) {
|
|
s_logger.trace("Network id=" + networkId + " is shared, but not domain specific");
|
|
return true;
|
|
} else {
|
|
networkDomainId = networkDomainMap.getDomainId();
|
|
}
|
|
|
|
if (domainId == networkDomainId.longValue()) {
|
|
return true;
|
|
}
|
|
|
|
if (networkDomainMap.subdomainAccess) {
|
|
Set<Long> parentDomains = _domainMgr.getDomainParentIds(domainId);
|
|
|
|
if (parentDomains.contains(networkDomainId)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Set<Long> getAvailableIps(Network network, String requestedIp) {
|
|
String[] cidr = network.getCidr().split("/");
|
|
List<String> ips = getUsedIpsInNetwork(network);
|
|
Set<Long> usedIps = new TreeSet<Long>();
|
|
|
|
for (String ip : ips) {
|
|
if (requestedIp != null && requestedIp.equals(ip)) {
|
|
s_logger.warn("Requested ip address " + requestedIp + " is already in use in network" + network);
|
|
return null;
|
|
}
|
|
|
|
usedIps.add(NetUtils.ip2Long(ip));
|
|
}
|
|
|
|
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps);
|
|
|
|
String gateway = network.getGateway();
|
|
if ((gateway != null) && (allPossibleIps.contains(NetUtils.ip2Long(gateway))))
|
|
allPossibleIps.remove(NetUtils.ip2Long(gateway));
|
|
|
|
return allPossibleIps;
|
|
}
|
|
|
|
@Override
|
|
public List<String> getUsedIpsInNetwork(Network network) {
|
|
//Get all ips used by vms nics
|
|
List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
|
|
//Get all secondary ips for nics
|
|
List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(network.getId());
|
|
ips.addAll(secondaryIps);
|
|
//Get ips used by load balancers
|
|
List<String> lbIps = _appLbRuleDao.listLbIpsBySourceIpNetworkId(network.getId());
|
|
ips.addAll(lbIps);
|
|
return ips;
|
|
}
|
|
|
|
@Override
|
|
public String getDomainNetworkDomain(long domainId, long zoneId) {
|
|
String networkDomain = null;
|
|
Long searchDomainId = domainId;
|
|
while (searchDomainId != null) {
|
|
DomainVO domain = _domainDao.findById(searchDomainId);
|
|
if (domain.getNetworkDomain() != null) {
|
|
networkDomain = domain.getNetworkDomain();
|
|
break;
|
|
}
|
|
searchDomainId = domain.getParent();
|
|
}
|
|
if (networkDomain == null) {
|
|
return getZoneNetworkDomain(zoneId);
|
|
}
|
|
return networkDomain;
|
|
}
|
|
|
|
boolean isProviderEnabled(PhysicalNetworkServiceProvider provider) {
|
|
if (provider == null || provider.getState() != PhysicalNetworkServiceProvider.State.Enabled) { // TODO: check
|
|
// for other states: Shutdown?
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
boolean isServiceEnabledInNetwork(long physicalNetworkId, long networkId, Service service) {
|
|
// check if the service is supported in the network
|
|
if (!areServicesSupportedInNetwork(networkId, service)) {
|
|
s_logger.debug("Service " + service.getName() + " is not supported in the network id=" + networkId);
|
|
return false;
|
|
}
|
|
|
|
// get provider for the service and check if all of them are supported
|
|
String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(networkId, service);
|
|
if (!isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) {
|
|
s_logger.debug("Provider " + provider + " is not enabled in physical network id=" + physicalNetworkId);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
|
|
return _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkId, vmId);
|
|
}
|
|
|
|
String getZoneNetworkDomain(long zoneId) {
|
|
return _dcDao.findById(zoneId).getDomain();
|
|
}
|
|
|
|
PhysicalNetwork getOnePhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
|
|
List<PhysicalNetworkVO> networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
|
|
|
|
if (networkList.isEmpty()) {
|
|
throw new InvalidParameterValueException("Unable to find the default physical network with traffic=" + trafficType + " in zone id=" + zoneId + ". ");
|
|
}
|
|
|
|
if (networkList.size() > 1) {
|
|
s_logger.info("More than one physical networks exist in zone id=" + zoneId + " with traffic type=" + trafficType + ". ");
|
|
}
|
|
|
|
return networkList.get(0);
|
|
}
|
|
|
|
protected Long getNonGuestNetworkPhysicalNetworkId(Network network, TrafficType trafficType) {
|
|
// VMware control network is management network
|
|
// we need to retrieve traffic label information through physical network
|
|
Long physicalNetworkId = network.getPhysicalNetworkId();
|
|
|
|
if (physicalNetworkId == null) {
|
|
List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZone(network.getDataCenterId());
|
|
if (pNtwks.size() == 1) {
|
|
physicalNetworkId = pNtwks.get(0).getId();
|
|
} else {
|
|
// locate physicalNetwork with supported traffic type
|
|
// We can make this assumptions based on the fact that Public/Management/Control traffic types are
|
|
// supported only in one physical network in the zone in 3.0
|
|
for (PhysicalNetworkVO pNtwk : pNtwks) {
|
|
if (_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), trafficType)) {
|
|
physicalNetworkId = pNtwk.getId();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return physicalNetworkId;
|
|
}
|
|
|
|
protected Long getNonGuestNetworkPhysicalNetworkId(Network network) {
|
|
// no physical network for control traffic type
|
|
|
|
// have to remove this sanity check as VMware control network is management network
|
|
// we need to retrieve traffic label information through physical network
|
|
/*
|
|
if (network.getTrafficType() == TrafficType.Control) {
|
|
return null;
|
|
}
|
|
*/
|
|
Long physicalNetworkId = network.getPhysicalNetworkId();
|
|
|
|
if (physicalNetworkId == null) {
|
|
List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZone(network.getDataCenterId());
|
|
if (pNtwks.size() == 1) {
|
|
physicalNetworkId = pNtwks.get(0).getId();
|
|
} else {
|
|
// locate physicalNetwork with supported traffic type
|
|
// We can make this assumptions based on the fact that Public/Management/Control traffic types are
|
|
// supported only in one physical network in the zone in 3.0
|
|
for (PhysicalNetworkVO pNtwk : pNtwks) {
|
|
if (_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), network.getTrafficType())) {
|
|
physicalNetworkId = pNtwk.getId();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return physicalNetworkId;
|
|
}
|
|
|
|
@Override
|
|
public NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri) {
|
|
NicVO nic = null;
|
|
if (broadcastUri != null) {
|
|
nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(networkId, vm.getId(), broadcastUri);
|
|
} else {
|
|
nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vm.getId());
|
|
}
|
|
if (nic == null) {
|
|
return null;
|
|
}
|
|
NetworkVO network = _networksDao.findById(networkId);
|
|
Integer networkRate = getNetworkRate(network.getId(), vm.getId());
|
|
|
|
// NetworkGuru guru = _networkGurus.get(network.getGuruName());
|
|
NicProfile profile =
|
|
new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(
|
|
vm.getHypervisorType(), network));
|
|
// guru.updateNicProfile(profile, network);
|
|
|
|
return profile;
|
|
}
|
|
|
|
@Override
|
|
public boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId) {
|
|
List<Provider> networkProviders = getNetworkProviders(networkId);
|
|
for (Provider provider : networkProviders) {
|
|
if (provider.isExternal()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private List<Provider> getNetworkProviders(long networkId) {
|
|
List<String> providerNames = _ntwkSrvcDao.getDistinctProviders(networkId);
|
|
Map<String, Provider> providers = new HashMap<String, Provider>();
|
|
for (String providerName : providerNames) {
|
|
if (!providers.containsKey(providerName)) {
|
|
providers.put(providerName, Network.Provider.getProvider(providerName));
|
|
}
|
|
}
|
|
|
|
return new ArrayList<Provider>(providers.values());
|
|
}
|
|
|
|
@Override
|
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
|
_configs = _configDao.getConfiguration("Network", params);
|
|
_allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key()));
|
|
_executeInSequenceNtwkElmtCmd = Boolean.valueOf(_configs.get(Config.ExecuteInSequenceNetworkElementCommands.key()));
|
|
|
|
NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPublicNetwork, TrafficType.Public, true);
|
|
publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering);
|
|
_systemNetworks.put(NetworkOffering.SystemPublicNetwork, publicNetworkOffering);
|
|
NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemManagementNetwork, TrafficType.Management, false);
|
|
managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering);
|
|
_systemNetworks.put(NetworkOffering.SystemManagementNetwork, managementNetworkOffering);
|
|
NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemControlNetwork, TrafficType.Control, false);
|
|
controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering);
|
|
_systemNetworks.put(NetworkOffering.SystemControlNetwork, controlNetworkOffering);
|
|
NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemStorageNetwork, TrafficType.Storage, true);
|
|
storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering);
|
|
_systemNetworks.put(NetworkOffering.SystemStorageNetwork, storageNetworkOffering);
|
|
NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated);
|
|
privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering);
|
|
_systemNetworks.put(NetworkOffering.SystemPrivateGatewayNetworkOffering, privateGatewayNetworkOffering);
|
|
_privateOfferingId = privateGatewayNetworkOffering.getId();
|
|
|
|
IpAddressSearch = _ipAddressDao.createSearchBuilder();
|
|
IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ);
|
|
IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ);
|
|
IpAddressSearch.and("vpcId", IpAddressSearch.entity().getVpcId(), Op.EQ);
|
|
IpAddressSearch.and("associatedWithNetworkId", IpAddressSearch.entity().getAssociatedWithNetworkId(), Op.EQ);
|
|
SearchBuilder<VlanVO> virtualNetworkVlanSB = _vlanDao.createSearchBuilder();
|
|
virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ);
|
|
IpAddressSearch.join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(),
|
|
JoinBuilder.JoinType.INNER);
|
|
IpAddressSearch.done();
|
|
|
|
NicForTrafficTypeSearch = _nicDao.createSearchBuilder();
|
|
SearchBuilder<NetworkVO> networkSearch = _networksDao.createSearchBuilder();
|
|
NicForTrafficTypeSearch.join("network", networkSearch, networkSearch.entity().getId(), NicForTrafficTypeSearch.entity().getNetworkId(), JoinType.INNER);
|
|
NicForTrafficTypeSearch.and("instance", NicForTrafficTypeSearch.entity().getInstanceId(), Op.EQ);
|
|
networkSearch.and("traffictype", networkSearch.entity().getTrafficType(), Op.EQ);
|
|
NicForTrafficTypeSearch.done();
|
|
|
|
s_logger.info("Network Model is configured.");
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean start() {
|
|
// populate s_serviceToImplementedProvidersMap & s_providerToNetworkElementMap with current _networkElements
|
|
// Need to do this in start() since _networkElements are not completely configured until then.
|
|
for (NetworkElement element : _networkElements) {
|
|
Map<Service, Map<Capability, String>> capabilities = element.getCapabilities();
|
|
Provider implementedProvider = element.getProvider();
|
|
if (implementedProvider != null) {
|
|
if (s_providerToNetworkElementMap.containsKey(implementedProvider.getName())) {
|
|
s_logger.error("Cannot start NetworkModel: Provider <-> NetworkElement must be a one-to-one map, " + "multiple NetworkElements found for Provider: " +
|
|
implementedProvider.getName());
|
|
continue;
|
|
}
|
|
s_logger.info("Add provider <-> element map entry. " + implementedProvider.getName() + "-" + element.getName() + "-" + element.getClass().getSimpleName());
|
|
s_providerToNetworkElementMap.put(implementedProvider.getName(), element.getName());
|
|
}
|
|
if (capabilities != null && implementedProvider != null) {
|
|
for (Service service : capabilities.keySet()) {
|
|
if (s_serviceToImplementedProvidersMap.containsKey(service)) {
|
|
List<Provider> providers = s_serviceToImplementedProvidersMap.get(service);
|
|
providers.add(implementedProvider);
|
|
} else {
|
|
List<Provider> providers = new ArrayList<Provider>();
|
|
providers.add(implementedProvider);
|
|
s_serviceToImplementedProvidersMap.put(service, providers);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
s_logger.info("Started Network Model");
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean stop() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork) {
|
|
List<? extends IpAddress> addrs = listPublicIpsAssignedToGuestNtwk(owner.getId(), guestNetwork.getId(), true);
|
|
|
|
IPAddressVO sourceNatIp = null;
|
|
if (addrs.isEmpty()) {
|
|
return null;
|
|
} else {
|
|
for (IpAddress addr : addrs) {
|
|
if (addr.isSourceNat()) {
|
|
sourceNatIp = _ipAddressDao.findById(addr.getId());
|
|
return PublicIp.createFromAddrAndVlan(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public boolean isNetworkInlineMode(Network network) {
|
|
NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
|
return offering.isInline();
|
|
}
|
|
|
|
@Override
|
|
public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException {
|
|
if (!NetUtils.isValidIpv6(startIPv6)) {
|
|
throw new InvalidParameterValueException("Invalid format for the startIPv6 parameter");
|
|
}
|
|
if (!NetUtils.isValidIpv6(endIPv6)) {
|
|
throw new InvalidParameterValueException("Invalid format for the endIPv6 parameter");
|
|
}
|
|
|
|
if (!(ip6Gateway != null && ip6Cidr != null)) {
|
|
throw new InvalidParameterValueException("ip6Gateway and ip6Cidr should be defined when startIPv6/endIPv6 are passed in");
|
|
}
|
|
|
|
if (!NetUtils.isValidIpv6(ip6Gateway)) {
|
|
throw new InvalidParameterValueException("Invalid ip6Gateway");
|
|
}
|
|
if (!NetUtils.isValidIp6Cidr(ip6Cidr)) {
|
|
throw new InvalidParameterValueException("Invalid ip6cidr");
|
|
}
|
|
if (!NetUtils.isIp6InNetwork(startIPv6, ip6Cidr)) {
|
|
throw new InvalidParameterValueException("startIPv6 is not in ip6cidr indicated network!");
|
|
}
|
|
if (!NetUtils.isIp6InNetwork(endIPv6, ip6Cidr)) {
|
|
throw new InvalidParameterValueException("endIPv6 is not in ip6cidr indicated network!");
|
|
}
|
|
if (!NetUtils.isIp6InNetwork(ip6Gateway, ip6Cidr)) {
|
|
throw new InvalidParameterValueException("ip6Gateway is not in ip6cidr indicated network!");
|
|
}
|
|
|
|
int cidrSize = NetUtils.getIp6CidrSize(ip6Cidr);
|
|
// we only support cidr == 64
|
|
if (cidrSize != 64) {
|
|
throw new InvalidParameterValueException("The cidr size of IPv6 network must be 64 bits!");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void checkRequestedIpAddresses(long networkId, String ip4, String ip6) throws InvalidParameterValueException {
|
|
if (ip4 != null) {
|
|
if (!NetUtils.isValidIp(ip4)) {
|
|
throw new InvalidParameterValueException("Invalid specified IPv4 address " + ip4);
|
|
}
|
|
//Other checks for ipv4 are done in assignPublicIpAddress()
|
|
}
|
|
if (ip6 != null) {
|
|
if (!NetUtils.isValidIpv6(ip6)) {
|
|
throw new InvalidParameterValueException("Invalid specified IPv6 address " + ip6);
|
|
}
|
|
if (_ipv6Dao.findByNetworkIdAndIp(networkId, ip6) != null) {
|
|
throw new InvalidParameterValueException("The requested IP is already taken!");
|
|
}
|
|
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
|
|
if (vlans == null) {
|
|
throw new CloudRuntimeException("Cannot find related vlan attached to network " + networkId);
|
|
}
|
|
Vlan ipVlan = null;
|
|
for (Vlan vlan : vlans) {
|
|
if (NetUtils.isIp6InRange(ip6, vlan.getIp6Range())) {
|
|
ipVlan = vlan;
|
|
break;
|
|
}
|
|
}
|
|
if (ipVlan == null) {
|
|
throw new InvalidParameterValueException("Requested IPv6 is not in the predefined range!");
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getStartIpv6Address(long networkId) {
|
|
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
|
|
if (vlans == null) {
|
|
return null;
|
|
}
|
|
String startIpv6 = null;
|
|
// Get the start ip of first create vlan(not the lowest, because if you add a lower vlan, lowest vlan would change)
|
|
for (Vlan vlan : vlans) {
|
|
if (vlan.getIp6Range() != null) {
|
|
startIpv6 = vlan.getIp6Range().split("-")[0];
|
|
break;
|
|
}
|
|
}
|
|
return startIpv6;
|
|
}
|
|
|
|
@Override
|
|
public NicVO getPlaceholderNicForRouter(Network network, Long podId) {
|
|
List<NicVO> nics = _nicDao.listPlaceholderNicsByNetworkIdAndVmType(network.getId(), VirtualMachine.Type.DomainRouter);
|
|
for (NicVO nic : nics) {
|
|
if (nic.getReserver() == null && (nic.getIp4Address() != null || nic.getIp6Address() != null)) {
|
|
if (podId == null) {
|
|
return nic;
|
|
} else {
|
|
//return nic only when its ip address belong to the pod range (for the Basic zone case)
|
|
List<? extends Vlan> vlans = _vlanDao.listVlansForPod(podId);
|
|
for (Vlan vlan : vlans) {
|
|
if (nic.getIp4Address() != null) {
|
|
IpAddress ip = _ipAddressDao.findByIpAndNetworkId(network.getId(), nic.getIp4Address());
|
|
if (ip != null && ip.getVlanId() == vlan.getId()) {
|
|
return nic;
|
|
}
|
|
} else {
|
|
UserIpv6AddressVO ipv6 = _ipv6Dao.findByNetworkIdAndIp(network.getId(), nic.getIp6Address());
|
|
if (ipv6 != null && ipv6.getVlanId() == vlan.getId()) {
|
|
return nic;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public IpAddress getPublicIpAddress(String ipAddress, long zoneId) {
|
|
List<? extends Network> networks = _networksDao.listByZoneAndTrafficType(zoneId, TrafficType.Public);
|
|
if (networks.isEmpty() || networks.size() > 1) {
|
|
throw new CloudRuntimeException("Can't find public network in the zone specified");
|
|
}
|
|
|
|
return _ipAddressDao.findByIpAndSourceNetworkId(networks.get(0).getId(), ipAddress);
|
|
}
|
|
|
|
@Override
|
|
public Map<Detail, String> getNtwkOffDetails(long offId) {
|
|
return _ntwkOffDetailsDao.getNtwkOffDetails(offId);
|
|
}
|
|
|
|
@Override
|
|
public Networks.IsolationType[] listNetworkIsolationMethods() {
|
|
return Networks.IsolationType.values();
|
|
}
|
|
|
|
@Override
|
|
public boolean getExecuteInSeqNtwkElmtCmd() {
|
|
return _executeInSequenceNtwkElmtCmd;
|
|
}
|
|
|
|
@Override
|
|
public boolean isNetworkReadyForGc(long networkId) {
|
|
Network network = getNetwork(networkId);
|
|
List<Long> networkIds = _networksDao.findNetworksToGarbageCollect();
|
|
List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(networkId);
|
|
if (!networkIds.contains(networkId)) {
|
|
return false;
|
|
}
|
|
|
|
// add an exception for networks that use external networking devices and has secondary guest IP's allocated.
|
|
// On network GC, when network goes through implement phase a new vlan is allocated, based on the acquired VLAN
|
|
// id cidr of the network is decided in case of external networking case. While NIC uses reservation strategy 'Start'
|
|
// which ensures that new primary ip is allocated for the NiC from the new CIDR. Secondary IP's have hardcoded IP's in
|
|
// network rules. So prevent network GC.
|
|
if (secondaryIps != null && !secondaryIps.isEmpty() && networkIsConfiguredForExternalNetworking(network.getDataCenterId(), networkId)) {
|
|
return false;
|
|
}
|
|
|
|
//if the network has vms in Starting state (nics for those might not be allocated yet as Starting state also used when vm is being Created)
|
|
//don't GC
|
|
if (_nicDao.countNicsForStartingVms(networkId) > 0) {
|
|
s_logger.debug("Network id=" + networkId + " is not ready for GC as it has vms that are Starting at the moment");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|