| // 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.security.MessageDigest; |
| import java.security.NoSuchAlgorithmException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| 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.inject.Inject; |
| import javax.naming.ConfigurationException; |
| |
| import org.apache.cloudstack.acl.ControlledEntity.ACLType; |
| import org.apache.cloudstack.context.CallContext; |
| import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; |
| import org.apache.cloudstack.framework.config.ConfigKey; |
| import org.apache.cloudstack.framework.config.Configurable; |
| import org.apache.cloudstack.framework.config.dao.ConfigurationDao; |
| import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; |
| import org.apache.cloudstack.network.NetworkPermissionVO; |
| import org.apache.cloudstack.network.dao.NetworkPermissionDao; |
| import org.apache.commons.collections.CollectionUtils; |
| import org.apache.commons.lang3.StringUtils; |
| |
| import com.cloud.api.ApiDBUtils; |
| import com.cloud.configuration.Config; |
| import com.cloud.configuration.ConfigurationManager; |
| import com.cloud.dc.DataCenter; |
| import com.cloud.dc.DataCenterVO; |
| 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.Domain; |
| 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.IpAddresses; |
| 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.NetworkAccountDao; |
| import com.cloud.network.dao.NetworkAccountVO; |
| 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.TungstenGuestNetworkIpAddressDao; |
| 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.router.VirtualRouter; |
| 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.Vpc; |
| import com.cloud.network.vpc.VpcGatewayVO; |
| import com.cloud.network.vpc.dao.PrivateIpDao; |
| import com.cloud.network.vpc.dao.VpcDao; |
| import com.cloud.network.vpc.dao.VpcGatewayDao; |
| 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.Project; |
| import com.cloud.projects.ProjectAccount; |
| import com.cloud.projects.dao.ProjectAccountDao; |
| import com.cloud.projects.dao.ProjectDao; |
| import com.cloud.user.Account; |
| import com.cloud.user.AccountManager; |
| import com.cloud.user.AccountVO; |
| import com.cloud.user.DomainManager; |
| import com.cloud.user.User; |
| import com.cloud.user.dao.AccountDao; |
| import com.cloud.utils.Pair; |
| 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.VirtualMachineManager; |
| import com.cloud.vm.dao.NicDao; |
| import com.cloud.vm.dao.NicSecondaryIpDao; |
| import com.cloud.vm.dao.VMInstanceDao; |
| |
| public class NetworkModelImpl extends ManagerBase implements NetworkModel, Configurable { |
| public static final String UNABLE_TO_USE_NETWORK = "Unable to use network with id= %s, permission denied"; |
| @Inject |
| EntityManager _entityMgr; |
| @Inject |
| DataCenterDao _dcDao = null; |
| @Inject |
| VlanDao _vlanDao = null; |
| @Inject |
| IPAddressDao _ipAddressDao = null; |
| @Inject |
| AccountDao _accountDao = null; |
| @Inject |
| DomainDao _domainDao = null; |
| @Inject |
| AccountManager _accountMgr; |
| @Inject |
| ConfigurationDao _configDao; |
| @Inject |
| ConfigurationManager _configMgr; |
| @Inject |
| NetworkOfferingDao _networkOfferingDao = null; |
| @Inject |
| NetworkDao _networksDao = null; |
| @Inject |
| NicDao _nicDao = null; |
| @Inject |
| PodVlanMapDao _podVlanMapDao; |
| @Inject |
| VpcGatewayDao _vpcGatewayDao; |
| @Inject |
| ProjectDao projectDao; |
| @Inject |
| NetworkPermissionDao _networkPermissionDao; |
| @Inject |
| VpcDao vpcDao; |
| |
| private List<NetworkElement> networkElements; |
| |
| public List<NetworkElement> getNetworkElements() { |
| return networkElements; |
| } |
| |
| public void setNetworkElements(List<NetworkElement> networkElements) { |
| this.networkElements = networkElements; |
| } |
| |
| @Inject |
| NetworkAccountDao _networkAccountDao; |
| @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; |
| @Inject |
| private NetworkService _networkService; |
| @Inject |
| TungstenGuestNetworkIpAddressDao tungstenGuestNetworkIpAddressDao; |
| |
| private final HashMap<String, NetworkOfferingVO> _systemNetworks = new HashMap<String, NetworkOfferingVO>(5); |
| |
| 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 source 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()) { |
| 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); |
| // 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]; |
| Set<Provider> oldProviders = serviceToProviders.get(services.toArray()[0]); |
| Provider oldProvider = (Provider)oldProviders.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); |
| // FIXME: I ignored this check |
| } 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() && !offering.isForNsx()) { |
| 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> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat) { |
| SearchCriteria<IPAddressVO> sc = IpAddressSearch.create(); |
| 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 { |
| NetworkVO network = _networksDao.findById(networkId); |
| Integer zoneIdentifier = MACIdentifier.value(); |
| if (zoneIdentifier.intValue() == 0) { |
| zoneIdentifier = Long.valueOf(network.getDataCenterId()).intValue(); |
| } |
| String mac; |
| do { |
| mac = _networksDao.getNextAvailableMacAddress(networkId, zoneIdentifier); |
| if (mac == null) { |
| throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId); |
| } |
| } while(! isMACUnique(mac)); |
| return mac; |
| } |
| |
| private boolean isMACUnique(String mac) { |
| return (_nicDao.findByMacAddress(mac) == null); |
| } |
| |
| @Override |
| @DB |
| public Network getNetwork(long id) { |
| return _networksDao.findById(id); |
| } |
| |
| @Override |
| public boolean canUseForDeploy(Network network) { |
| if (network.getTrafficType() != TrafficType.Guest) { |
| return false; |
| } |
| if (network.getGuestType() == GuestType.L2 || 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) { |
| hasFreeIps = _ipAddressDao.countFreeIPsInNetwork(network.getId()) > 0; |
| } |
| if (!hasFreeIps) { |
| return false; |
| } |
| } else { |
| if (network.getCidr() == null) { |
| logger.debug("Network - " + network.getId() + " has NULL CIDR."); |
| return false; |
| } |
| hasFreeIps = (getAvailableIps(network, null)).size() > 0; |
| } |
| |
| return hasFreeIps; |
| } |
| |
| @Override |
| public boolean areThereIPv6AddressAvailableInNetwork(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 getNetworkWithSGWithFreeIPs(Long zoneId) { |
| List<NetworkVO> networks = _networksDao.listByZoneSecurityGroup(zoneId); |
| if (networks == null || networks.isEmpty()) { |
| return null; |
| } |
| NetworkVO ret_network = null; |
| for (NetworkVO nw : networks) { |
| List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(nw.getId()); |
| for (VlanVO vlan : vlans) { |
| if (_ipAddressDao.countFreeIpsInVlan(vlan.getId()) > 0) { |
| ret_network = nw; |
| break; |
| } |
| } |
| if (ret_network != null) { |
| break; |
| } |
| } |
| if (ret_network == null) { |
| logger.debug("Can not find network with security group enabled with free IPs"); |
| } |
| return ret_network; |
| } |
| |
| @Override |
| public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) { |
| List<NetworkVO> networks = _networksDao.listByZoneSecurityGroup(zoneId); |
| if (networks == null || networks.isEmpty()) { |
| return null; |
| } |
| |
| if (networks.size() > 1) { |
| 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.getIPv4Address() != null) : "Vm doesn't belong to network associated with " + "ipAddress or ip4 address is null"; |
| return guestNic.getIPv4Address(); |
| } |
| |
| @Override |
| public String getIpInNetworkIncludingRemoved(long vmId, long networkId) { |
| Nic guestNic = getNicInNetworkIncludingRemoved(vmId, networkId); |
| assert (guestNic != null && guestNic.getIPv4Address() != null) : "Vm doesn't belong to network associated with " + "ipAddress or ip4 address is null"; |
| return guestNic.getIPv4Address(); |
| } |
| |
| @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 { |
| logger.debug("Unable to find default network for the vm; vm doesn't have any nics"); |
| return null; |
| } |
| |
| if (defaultNic == null) { |
| 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) { |
| logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName()); |
| return null; |
| } |
| |
| return (UserDataServiceProvider)getElementImplementingProvider(userDataProvider); |
| } |
| |
| @Override |
| public boolean isSharedNetworkWithoutServices (long networkId) { |
| |
| Network network = _networksDao.findById(networkId); |
| |
| if (network != null && network.getGuestType() != GuestType.Shared) { |
| return false; |
| } |
| |
| List<Service> services = listNetworkOfferingServices(network.getNetworkOfferingId()); |
| |
| if (services == null || services.isEmpty()) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| |
| @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, GuestType.Isolated, false); |
| |
| if (virtualNetworks.isEmpty()) { |
| 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.getIPv4Address(); |
| } else { |
| 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, GuestType type) { |
| List<NetworkVO> accountNetworks = new ArrayList<NetworkVO>(); |
| List<NetworkVO> zoneNetworks = _networksDao.listByZone(zoneId); |
| |
| for (NetworkVO network : zoneNetworks) { |
| if (!isNetworkSystem(network)) { |
| if (network.getGuestType() == GuestType.Shared || !_networksDao.listBy(accountId, network.getId()).isEmpty()) { |
| if (type == null || type == network.getGuestType()) { |
| accountNetworks.add(network); |
| } |
| } |
| } |
| } |
| return accountNetworks; |
| } |
| |
| @Override |
| public List<NetworkVO> listAllNetworksInAllZonesByType(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); |
| } |
| final Network network = getNetwork(networkId); |
| final NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId()); |
| |
| // For user VM: For default nic use network rate from the service/compute offering, |
| // or on NULL from vm.network.throttling.rate global setting |
| // For router: Get network rate for guest and public networks from the guest network offering |
| // or on NULL from network.throttling.rate |
| // For others: Use network rate from their network offering, |
| // or on NULL from network.throttling.rate setting at zone > global level |
| // http://docs.cloudstack.apache.org/en/latest/adminguide/service_offerings.html#network-throttling |
| if (vm != null) { |
| switch (vm.getType()) { |
| case User: |
| final Nic nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId); |
| if (nic != null && nic.isDefaultNic()) { |
| return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), network.getDataCenterId()); |
| } |
| break; |
| case DomainRouter: |
| if (TrafficType.Guest.equals(network.getTrafficType())) { |
| final Nic routerNic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId); |
| if (routerNic != null) { |
| return _configMgr.getNetworkOfferingNetworkRate(network.getNetworkOfferingId(), network.getDataCenterId()); |
| } |
| } else if (TrafficType.Public.equals(network.getTrafficType())) { |
| List<NicVO> routerNics = _nicDao.listByVmId(vmId); |
| for (final Nic routerNic : routerNics) { |
| final NetworkVO nw = _networksDao.findById(routerNic.getNetworkId()); |
| if (TrafficType.Guest.equals(nw.getTrafficType())) { |
| return _configMgr.getNetworkOfferingNetworkRate(nw.getNetworkOfferingId(), network.getDataCenterId()); |
| } |
| } |
| } |
| break; |
| case ConsoleProxy: |
| case SecondaryStorageVm: |
| return -1; |
| } |
| } |
| if (ntwkOff != null) { |
| return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId(), network.getDataCenterId()); |
| } |
| final Integer networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(network.getDataCenterId()); |
| if (networkRate != null && networkRate > 0) { |
| return networkRate; |
| } |
| return -1; |
| } |
| |
| @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.getService(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) { |
| return getPhysicalNetworkId(zoneId, pNtwks, tag); |
| } else { |
| return pNtwks.get(0).getId(); |
| } |
| } |
| |
| private Long getPhysicalNetworkId(long zoneId, List<PhysicalNetworkVO> pNtwks, String tag) { |
| Long pNtwkId = null; |
| for (PhysicalNetwork pNtwk : pNtwks) { |
| if (tag == null && pNtwk.getTags().isEmpty()) { |
| logger.debug("Found physical network id=" + pNtwk.getId() + " with null tag"); |
| if (pNtwkId != null) { |
| throw new CloudRuntimeException("There is more than 1 physical network with empty tag in the zone id=" + zoneId); |
| } |
| pNtwkId = pNtwk.getId(); |
| } else if (tag != null && pNtwk.getTags().contains(tag)) { |
| 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; |
| } |
| |
| @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) { |
| 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; |
| if (hypervisorType.equals(HypervisorType.XenServer)) { |
| label = mgmtTraffic.getXenNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.KVM)) { |
| label = mgmtTraffic.getKvmNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.VMware)) { |
| label = mgmtTraffic.getVmwareNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.Hyperv)) { |
| label = mgmtTraffic.getHypervNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.Ovm3)) { |
| label = mgmtTraffic.getOvm3NetworkLabel(); |
| } |
| return label; |
| } |
| } catch (Exception ex) { |
| if (logger.isDebugEnabled()) { |
| 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; |
| if (hypervisorType.equals(HypervisorType.XenServer)) { |
| label = storageTraffic.getXenNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.KVM)) { |
| label = storageTraffic.getKvmNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.VMware)) { |
| label = storageTraffic.getVmwareNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.Hyperv)) { |
| label = storageTraffic.getHypervNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.Ovm3)) { |
| label = storageTraffic.getOvm3NetworkLabel(); |
| } |
| return label; |
| } |
| } catch (Exception ex) { |
| if (logger.isDebugEnabled()) { |
| 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) { |
| 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"; |
| 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); |
| } |
| checkedProvider.add(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() && !offering.isForNsx()) { |
| return canIpUsedForNonConserveService(publicIp, service); |
| } |
| return true; |
| } |
| |
| @Override |
| public boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap) { |
| 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()); |
| } |
| |
| if (serviceCapabilities.containsKey(cap)) { |
| return true; |
| } |
| } else { |
| throw new UnsupportedServiceException("Unable to find network element for provider " + provider.getName()); |
| } |
| } |
| return false; |
| } |
| |
| @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 capabilities 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 final void checkNetworkPermissions(Account caller, Network network) { |
| if (_accountMgr.isRootAdmin(caller.getAccountId()) && Boolean.TRUE.equals(AdminIsAllowedToDeployAnywhere.value())) { |
| if (logger.isDebugEnabled()) { |
| logger.debug("root admin is permitted to do stuff on every network"); |
| } |
| } else { |
| if (network == null) { |
| throw new CloudRuntimeException("cannot check permissions on (Network) <null>"); |
| } |
| logger.info(String.format("Checking permission for account %s (%s) on network %s (%s)", caller.getAccountName(), caller.getUuid(), network.getName(), network.getUuid())); |
| if (network.getGuestType() != GuestType.Shared || network.getAclType() == ACLType.Account) { |
| checkAccountNetworkPermissions(caller, network); |
| |
| } else { |
| checkDomainNetworkPermissions(caller, network); |
| } |
| } |
| } |
| |
| private void checkAccountNetworkPermissions(Account caller, Network network) { |
| AccountVO networkOwner = _accountDao.findById(network.getAccountId()); |
| if (networkOwner == null) |
| throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO) network).getUuid() + |
| ", network does not have an owner"); |
| if (!Account.Type.PROJECT.equals(caller.getType()) && Account.Type.PROJECT.equals(networkOwner.getType())) { |
| checkProjectNetworkPermissions(caller, networkOwner, network); |
| } else { |
| List<NetworkVO> networkMap = _networksDao.listBy(caller.getId(), network.getId()); |
| NetworkPermissionVO networkPermission = _networkPermissionDao.findByNetworkAndAccount(network.getId(), caller.getId()); |
| if (CollectionUtils.isEmpty(networkMap) && networkPermission == null) { |
| throw new PermissionDeniedException(String.format(UNABLE_TO_USE_NETWORK, ((NetworkVO) network).getUuid())); |
| } |
| } |
| } |
| |
| private void checkDomainNetworkPermissions(Account caller, Network network) { |
| if (!isNetworkAvailableInDomain(network.getId(), caller.getDomainId())) { |
| DomainVO callerDomain = _domainDao.findById(caller.getDomainId()); |
| if (callerDomain == null) { |
| throw new CloudRuntimeException("cannot check permission on account " + caller.getAccountName() + " whose domain does not exist"); |
| } |
| throw new PermissionDeniedException("Shared network id=" + ((NetworkVO) network).getUuid() + " is not available in domain id=" + |
| callerDomain.getUuid()); |
| } |
| } |
| |
| private void checkProjectNetworkPermissions(Account owner, Account networkOwner, Network network){ |
| User user = CallContext.current().getCallingUser(); |
| Project project = projectDao.findByProjectAccountId(networkOwner.getId()); |
| if (project == null) { |
| throw new CloudRuntimeException("Unable to find project to which the network belongs to"); |
| } |
| ProjectAccount projectAccountUser = _projectAccountDao.findByProjectIdUserId(project.getId(), user.getAccountId(), user.getId()); |
| if (projectAccountUser != null) { |
| if (!_projectAccountDao.canUserAccessProjectAccount(user.getAccountId(), user.getId(), networkOwner.getId())) { |
| throw new PermissionDeniedException(String.format(UNABLE_TO_USE_NETWORK, ((NetworkVO)network).getUuid())); |
| } |
| } else { |
| if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), networkOwner.getId())) { |
| throw new PermissionDeniedException(String.format(UNABLE_TO_USE_NETWORK, ((NetworkVO) network).getUuid())); |
| } |
| } |
| } |
| |
| @Override |
| public void checkNetworkOperatePermissions(Account owner, Network network) { |
| if (network == null) { |
| throw new CloudRuntimeException("cannot check permissions on (Network) <null>"); |
| } |
| if (owner.getType() == Account.Type.ADMIN) { |
| return; |
| } |
| if (network.getGuestType() == GuestType.Shared) { |
| checkSharedNetworkOperatePermissions(owner, network); |
| } else { |
| checkNonSharedNetworkOperatePermissions(owner, network); |
| } |
| } |
| |
| @Override |
| public void checkRouterPermissions(Account owner, VirtualRouter router) { |
| Account account = _accountMgr.getAccount(router.getAccountId()); |
| try { |
| _accountMgr.checkAccess(owner, null, true, account); |
| return; |
| } catch (PermissionDeniedException ex) { |
| logger.info("Account " + owner + " do not have permission on router owner " + account); |
| } |
| List<NicVO> routerNics = _nicDao.listByVmId(router.getId()); |
| for (final Nic routerNic : routerNics) { |
| final NetworkVO network = _networksDao.findById(routerNic.getNetworkId()); |
| if (TrafficType.Guest.equals(network.getTrafficType())) { |
| checkNetworkOperatePermissions(owner, network); |
| } |
| } |
| } |
| |
| private void checkNonSharedNetworkOperatePermissions(Account owner, Network network) { |
| // check on isolated/L2 networks |
| Account networkOwner = _accountDao.findByIdIncludingRemoved(network.getAccountId()); |
| if (owner.getType() == Account.Type.DOMAIN_ADMIN) { |
| if (!_domainDao.isChildDomain(owner.getDomainId(), networkOwner.getDomainId())) { |
| throw new PermissionDeniedException(String.format("network %s cannot be operated by domain admin %s", network, owner)); |
| } |
| } else if (owner.getType() == Account.Type.NORMAL) { |
| if (owner.getType() != Account.Type.PROJECT && networkOwner.getType() == Account.Type.PROJECT) { |
| checkProjectNetworkPermissions(owner, networkOwner, network); |
| } else if (networkOwner.getAccountId() != owner.getAccountId()) { |
| throw new PermissionDeniedException(String.format("network %s cannot be operated by normal user %s", network, owner)); |
| } |
| } else { |
| throw new PermissionDeniedException(String.format("network %s cannot be operated by this account %s", network, owner)); |
| } |
| } |
| |
| private void checkSharedNetworkOperatePermissions(Account owner, Network network) { |
| NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); |
| if (networkOffering.isSpecifyVlan() && owner.getType() != Account.Type.ADMIN) { |
| throw new PermissionDeniedException(String.format("Shared network %s with specifyvlan=true can only be operated by root admin", network)); |
| } |
| if (owner.getType() == Account.Type.DOMAIN_ADMIN) { |
| if (network.getAclType() == ACLType.Domain) { |
| // Allow domain admins to operate shared network for their domain. |
| Long networkDomainId = getDomainIdForSharedNetwork(network); |
| if (!_domainDao.isChildDomain(owner.getDomainId(), networkDomainId)) { |
| throw new PermissionDeniedException(String.format("Shared network %s belongs to another domain cannot be operated by domain admin %s", network, owner)); |
| } |
| } else if (network.getAclType() == ACLType.Account) { |
| // Allow domain admins to operate shared network for an account in their domain. |
| Long networkAccountId = getAccountIdForSharedNetwork(network); |
| if (!_domainDao.isChildDomain(owner.getDomainId(), _accountDao.findByIdIncludingRemoved(networkAccountId).getDomainId())) { |
| throw new PermissionDeniedException(String.format("Shared network %s belongs to an account in another domain cannot be operated by domain admin %s", network, owner)); |
| } |
| } |
| } else if (owner.getType() == Account.Type.NORMAL) { |
| // Allow normal users to operate shared network for themselves. |
| if (network.getAclType() == ACLType.Account) { |
| // Allow domain admin to operate shared network for an account in its domain. |
| Long networkAccountId = getAccountIdForSharedNetwork(network); |
| Account networkOwner = _accountDao.findByIdIncludingRemoved(networkAccountId); |
| if (owner.getType() != Account.Type.PROJECT && networkOwner.getType() == Account.Type.PROJECT) { |
| checkProjectNetworkPermissions(owner, networkOwner, network); |
| } else if (networkOwner.getAccountId() != owner.getAccountId()) { |
| throw new PermissionDeniedException(String.format("Shared network %s belongs to another account cannot be operated by normal user %s", network, owner)); |
| } |
| } else { |
| throw new PermissionDeniedException(String.format("Shared network %s belongs to domain cannot be operated by normal user %s", network, owner)); |
| } |
| } else if (owner.getType() != Account.Type.ADMIN) { |
| throw new PermissionDeniedException(String.format("Shared network %s cannot be operated by account %s with type = %d", network, owner, owner.getType())); |
| } |
| } |
| |
| private Long getAccountIdForSharedNetwork(Network network) { |
| NetworkAccountVO networkAccountMap = _networkAccountDao.getAccountNetworkMapByNetworkId(network.getId()); |
| if (networkAccountMap == null) { |
| throw new CloudRuntimeException(String.format("Cannot find account info for Shared network %s with aclType=Account", network)); |
| } |
| return networkAccountMap.getAccountId(); |
| } |
| |
| private Long getDomainIdForSharedNetwork(Network network) { |
| NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(network.getId()); |
| if (networkDomainMap == null) { |
| throw new CloudRuntimeException(String.format("Cannot find domain info for Shared network %s with aclType=Domain", network)); |
| } |
| return networkDomainMap.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; |
| if (hypervisorType.equals(HypervisorType.XenServer)) { |
| label = publicTraffic.getXenNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.KVM)) { |
| label = publicTraffic.getKvmNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.VMware)) { |
| label = publicTraffic.getVmwareNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.Hyperv)) { |
| label = publicTraffic.getHypervNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.Ovm3)) { |
| label = publicTraffic.getOvm3NetworkLabel(); |
| } |
| return label; |
| } |
| } catch (Exception ex) { |
| if (logger.isDebugEnabled()) { |
| 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; |
| if (hypervisorType.equals(HypervisorType.XenServer)) { |
| label = guestTraffic.getXenNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.KVM)) { |
| label = guestTraffic.getKvmNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.VMware)) { |
| label = guestTraffic.getVmwareNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.Hyperv)) { |
| label = guestTraffic.getHypervNetworkLabel(); |
| } else if (hypervisorType.equals(HypervisorType.Ovm3)) { |
| label = guestTraffic.getOvm3NetworkLabel(); |
| } |
| return label; |
| } |
| } catch (Exception ex) { |
| if (logger.isDebugEnabled()) { |
| logger.debug("Failed to retrive the default label for guest 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(long ntwkId) { |
| final VpcGatewayVO gateway = _vpcGatewayDao.getVpcGatewayByNetworkId(ntwkId); |
| if (gateway == null) { |
| 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() != GuestType.Shared) { |
| logger.trace("Network id=" + networkId + " is not shared"); |
| return false; |
| } |
| |
| NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId); |
| if (networkDomainMap == null) { |
| 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) { |
| if (network.getCidr() == null) { |
| return Collections.emptySet(); |
| } |
| 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)) { |
| 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, -1); |
| |
| 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); |
| //Get ips used by tungsten |
| List<String> tfIps = tungstenGuestNetworkIpAddressDao.listGuestIpAddressByNetworkId(network.getId()); |
| ips.addAll(tfIps); |
| 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)) { |
| 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)) { |
| 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) { |
| 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)); |
| if (network.getTrafficType() == TrafficType.Public && network.getPublicMtu() != null) { |
| profile.setMtu(network.getPublicMtu()); |
| } |
| if (network.getTrafficType() == TrafficType.Guest && network.getPrivateMtu() != null) { |
| profile.setMtu(network.getPrivateMtu()); |
| } |
| // 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, true); |
| privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering); |
| _systemNetworks.put(NetworkOffering.SystemPrivateGatewayNetworkOffering, privateGatewayNetworkOffering); |
| NetworkOfferingVO privateGatewayNetworkOfferingWithoutVlan = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOfferingWithoutVlan, GuestType.Isolated, false); |
| privateGatewayNetworkOfferingWithoutVlan = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOfferingWithoutVlan); |
| _systemNetworks.put(NetworkOffering.SystemPrivateGatewayNetworkOfferingWithoutVlan, privateGatewayNetworkOfferingWithoutVlan); |
| |
| 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(); |
| |
| 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())) { |
| logger.error("Cannot start NetworkModel: Provider <-> NetworkElement must be a one-to-one map, " + "multiple NetworkElements found for Provider: " + |
| implementedProvider.getName()); |
| continue; |
| } |
| 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); |
| } |
| } |
| } |
| } |
| |
| //After network elements are configured correctly, verify ConfigDrive entries on enabled zones |
| verifyDisabledConfigDriveEntriesOnEnabledZones(); |
| |
| logger.info("Started Network Model"); |
| return true; |
| } |
| |
| /** |
| * Verifies ConfigDrive entries on a zone and adds disabled ConfigDrive provider if missing. |
| */ |
| protected void addDisabledConfigDriveEntriesOnZone(DataCenterVO zone) { |
| if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) { |
| List<PhysicalNetworkVO> physicalNetworks = _physicalNetworkDao.listByZoneAndTrafficType( |
| zone.getId(), TrafficType.Guest); |
| for (PhysicalNetworkVO physicalNetworkVO : physicalNetworks) { |
| PhysicalNetworkServiceProviderVO provider = _pNSPDao.findByServiceProvider( |
| physicalNetworkVO.getId(), Provider.ConfigDrive.getName()); |
| if (provider == null) { |
| _networkService.addProviderToPhysicalNetwork( |
| physicalNetworkVO.getId(), Provider.ConfigDrive.getName(), null, null); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Verifies ConfigDrive entries on enabled zones, adds disabled ConfigDrive provider if missing. |
| */ |
| protected void verifyDisabledConfigDriveEntriesOnEnabledZones() { |
| List<DataCenterVO> zones = _dcDao.listEnabledZones(); |
| if (CollectionUtils.isNotEmpty(zones)) { |
| for (DataCenterVO zone : zones) { |
| addDisabledConfigDriveEntriesOnZone(zone); |
| } |
| } |
| } |
| |
| @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 (StringUtils.isAnyBlank(ip6Gateway, ip6Cidr)) { |
| throw new InvalidParameterValueException("ip6Gateway and ip6Cidr should be defined for an IPv6 network work properly"); |
| } |
| |
| if (!NetUtils.isValidIp6(ip6Gateway)) { |
| throw new InvalidParameterValueException("Invalid ip6Gateway"); |
| } |
| if (!NetUtils.isValidIp6Cidr(ip6Cidr)) { |
| throw new InvalidParameterValueException("Invalid ip6cidr"); |
| } |
| |
| if (!NetUtils.isIp6InNetwork(ip6Gateway, ip6Cidr)) { |
| throw new InvalidParameterValueException("ip6Gateway is not in ip6cidr indicated network!"); |
| } |
| |
| if (StringUtils.isNotBlank(startIPv6)) { |
| if (!NetUtils.isValidIp6(startIPv6)) { |
| throw new InvalidParameterValueException("Invalid format for the startIPv6 parameter"); |
| } |
| if (!NetUtils.isIp6InNetwork(startIPv6, ip6Cidr)) { |
| throw new InvalidParameterValueException("startIPv6 is not in ip6cidr indicated network!"); |
| } |
| } |
| |
| if (StringUtils.isNotBlank(endIPv6)) { |
| if (!NetUtils.isValidIp6(endIPv6)) { |
| throw new InvalidParameterValueException("Invalid format for the endIPv6 parameter"); |
| } |
| if (!NetUtils.isIp6InNetwork(endIPv6, ip6Cidr)) { |
| throw new InvalidParameterValueException("endIPv6 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, IpAddresses ips) throws InvalidParameterValueException { |
| String ip4 = ips.getIp4Address(); |
| String ip6 = ips.getIp6Address(); |
| String mac = ips.getMacAddress(); |
| if (ip4 != null) { |
| if (!NetUtils.isValidIp4(ip4)) { |
| throw new InvalidParameterValueException("Invalid specified IPv4 address " + ip4); |
| } |
| //Other checks for ipv4 are done in assignPublicIpAddress() |
| } |
| if (ip6 != null) { |
| if (!NetUtils.isValidIp6(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!"); |
| } |
| } |
| if (mac != null) { |
| if(!NetUtils.isValidMac(mac)) { |
| throw new InvalidParameterValueException("Invalid specified MAC address " + mac); |
| } |
| if (_nicDao.findByNetworkIdAndMacAddress(networkId, mac) != null) { |
| throw new InvalidParameterValueException("The requested Mac address is already taken! " + mac); |
| } |
| |
| } |
| } |
| |
| @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); |
| List<? extends Vlan> vlans = new ArrayList<VlanVO>(); |
| if (podId != null) { |
| vlans = _vlanDao.listVlansForPod(podId); |
| } |
| for (NicVO nic : nics) { |
| if (nic.getReserver() == null && (nic.getIPv4Address() != null || nic.getIPv6Address() != null)) { |
| if (podId == null) { |
| return nic; |
| } else { |
| IpAddress ip = null; |
| UserIpv6AddressVO ipv6 = null; |
| |
| if (nic.getIPv4Address() != null) { |
| ip = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), nic.getIPv4Address()); |
| } else { |
| ipv6 = _ipv6Dao.findByNetworkIdAndIp(network.getId(), nic.getIPv6Address()); |
| } |
| |
| if (vlans.isEmpty()) { |
| return nic; |
| } |
| //return nic only when its ip address belong to the pod range (for the Basic zone case) |
| for (Vlan vlan : vlans) { |
| if (ip != null && ip.getVlanId() == vlan.getId()) { |
| return nic; |
| } else 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 user vms in Starting/Stopping/Migrating/Running state, or VRs in Starting/Stopping/Migrating state, don't GC |
| // The active nics count (nics_count in op_networks table) might be wrong due to some reasons, should check the state of vms as well. |
| // (nics for Starting VMs might not be allocated yet as Starting state also used when vm is being Created) |
| if (_nicDao.countNicsForNonStoppedVms(networkId) > 0 || _nicDao.countNicsForNonStoppedRunningVrs(networkId) > 0) { |
| logger.debug("Network id=" + networkId + " is not ready for GC as it has vms that are not Stopped at the moment"); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| @Override |
| public boolean getNetworkEgressDefaultPolicy(Long networkId) { |
| NetworkVO network = _networksDao.findById(networkId); |
| |
| if (network != null) { |
| NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); |
| return offering.isEgressDefaultPolicy(); |
| } else { |
| InvalidParameterValueException ex = new InvalidParameterValueException("network with network id does not exist"); |
| throw ex; |
| } |
| } |
| |
| @Override |
| public List<String[]> generateVmData(String userData, String userDataDetails, String serviceOffering, long datacenterId, |
| String vmName, String vmHostName, long vmId, String vmUuid, |
| String guestIpAddress, String publicKey, String password, Boolean isWindows, String hostname) { |
| |
| DataCenterVO dcVo = _dcDao.findById(datacenterId); |
| final String zoneName = dcVo.getName(); |
| |
| IPAddressVO publicIp = _ipAddressDao.findByAssociatedVmId(vmId); |
| VirtualMachine vm = _vmDao.findById(vmId); |
| if (vm == null) { |
| throw new CloudRuntimeException(String.format("Cannot generate VM instance data, no VM exists by ID: %d", vmId)); |
| } |
| |
| final List<String[]> vmData = new ArrayList<String[]>(); |
| |
| if (userData != null) { |
| vmData.add(new String[]{USERDATA_DIR, USERDATA_FILE, userData}); |
| } |
| vmData.add(new String[]{METATDATA_DIR, SERVICE_OFFERING_FILE, com.cloud.utils.StringUtils.unicodeEscape(serviceOffering)}); |
| vmData.add(new String[]{METATDATA_DIR, AVAILABILITY_ZONE_FILE, com.cloud.utils.StringUtils.unicodeEscape(zoneName)}); |
| vmData.add(new String[]{METATDATA_DIR, LOCAL_HOSTNAME_FILE, com.cloud.utils.StringUtils.unicodeEscape(vmHostName)}); |
| vmData.add(new String[]{METATDATA_DIR, LOCAL_IPV4_FILE, guestIpAddress}); |
| |
| addUserDataDetailsToCommand(vmData, userDataDetails); |
| |
| String publicIpAddress = guestIpAddress; |
| String publicHostName = com.cloud.utils.StringUtils.unicodeEscape(vmHostName); |
| |
| if (dcVo.getNetworkType() != DataCenter.NetworkType.Basic) { |
| if (publicIp != null) { |
| publicIpAddress = publicIp.getAddress().addr(); |
| publicHostName = publicIp.getAddress().addr(); |
| } else { |
| publicHostName = null; |
| } |
| } |
| vmData.add(new String[]{METATDATA_DIR, PUBLIC_IPV4_FILE, publicIpAddress}); |
| vmData.add(new String[]{METATDATA_DIR, PUBLIC_HOSTNAME_FILE, publicHostName}); |
| |
| if (vmUuid == null) { |
| vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmName}); |
| vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, String.valueOf(vmId)}); |
| } else { |
| vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmUuid}); |
| vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, vmUuid}); |
| } |
| |
| vmData.add(new String[]{METATDATA_DIR, PUBLIC_KEYS_FILE, publicKey}); |
| |
| String cloudIdentifier = _configDao.getValue("cloud.identifier"); |
| if (cloudIdentifier == null) { |
| cloudIdentifier = ""; |
| } else { |
| cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}"; |
| } |
| vmData.add(new String[]{METATDATA_DIR, CLOUD_IDENTIFIER_FILE, cloudIdentifier}); |
| |
| if (password != null && !password.isEmpty() && !password.equals("saved_password")) { |
| |
| // Here we are calculating MD5 checksum to reduce the over head of calculating MD5 checksum |
| // in windows VM in password reset script. |
| |
| if (isWindows) { |
| MessageDigest md5 = null; |
| try { |
| md5 = MessageDigest.getInstance("MD5"); |
| } catch (NoSuchAlgorithmException e) { |
| logger.error("Unexpected exception " + e.getMessage(), e); |
| throw new CloudRuntimeException("Unable to get MD5 MessageDigest", e); |
| } |
| md5.reset(); |
| md5.update(password.getBytes(com.cloud.utils.StringUtils.getPreferredCharset())); |
| byte[] digest = md5.digest(); |
| BigInteger bigInt = new BigInteger(1, digest); |
| String hashtext = bigInt.toString(16); |
| |
| vmData.add(new String[]{PASSWORD_DIR, PASSWORD_CHECKSUM_FILE, hashtext}); |
| } |
| |
| vmData.add(new String[]{PASSWORD_DIR, PASSWORD_FILE, password}); |
| } |
| vmData.add(new String[]{METATDATA_DIR, HYPERVISOR_HOST_NAME_FILE, hostname}); |
| |
| Domain domain = _domainDao.findById(vm.getDomainId()); |
| if (domain != null && VirtualMachineManager.AllowExposeDomainInMetadata.valueIn(domain.getId())) { |
| logger.debug("Adding domain info to cloud metadata"); |
| vmData.add(new String[]{METATDATA_DIR, CLOUD_DOMAIN_FILE, domain.getName()}); |
| vmData.add(new String[]{METATDATA_DIR, CLOUD_DOMAIN_ID_FILE, domain.getUuid()}); |
| } |
| |
| String customCloudName = VirtualMachineManager.MetadataCustomCloudName.valueIn(datacenterId); |
| if (org.apache.commons.lang3.StringUtils.isNotBlank(customCloudName)) { |
| vmData.add(new String[]{METATDATA_DIR, CLOUD_NAME_FILE, customCloudName}); |
| } |
| |
| return vmData; |
| } |
| |
| protected void addUserDataDetailsToCommand(List<String[]> vmData, String userDataDetails) { |
| if(userDataDetails != null && !userDataDetails.isEmpty()) { |
| userDataDetails = userDataDetails.substring(1, userDataDetails.length()-1); |
| String[] keyValuePairs = userDataDetails.split(","); |
| for(String pair : keyValuePairs) |
| { |
| final Pair<String, String> keyValue = com.cloud.utils.StringUtils.getKeyValuePairWithSeparator(pair, "="); |
| vmData.add(new String[]{METATDATA_DIR, keyValue.first(), com.cloud.utils.StringUtils.unicodeEscape(keyValue.second())}); |
| } |
| } |
| } |
| |
| @Override |
| public String getConfigComponentName() { |
| return NetworkModel.class.getSimpleName(); |
| } |
| |
| @Override |
| public ConfigKey<?>[] getConfigKeys() { |
| return new ConfigKey<?>[] {MACIdentifier, AdminIsAllowedToDeployAnywhere}; |
| } |
| |
| @Override |
| public String getValidNetworkCidr(Network guestNetwork) { |
| String networkCidr = guestNetwork.getNetworkCidr(); |
| return networkCidr == null ? guestNetwork.getCidr() : networkCidr; |
| } |
| |
| @Override |
| public Pair<String, String> getNetworkIp4Dns(final Network network, final DataCenter zone) { |
| if (StringUtils.isNotBlank(network.getDns1())) { |
| return new Pair<>(network.getDns1(), network.getDns2()); |
| } |
| if (network.getVpcId() != null) { |
| Vpc vpc = vpcDao.findById(network.getVpcId()); |
| if (vpc != null && StringUtils.isNotBlank(vpc.getIp4Dns1())) { |
| return new Pair<>(vpc.getIp4Dns1(), vpc.getIp4Dns2()); |
| } |
| } |
| return new Pair<>(zone.getDns1(), zone.getDns2()); |
| } |
| |
| @Override |
| public Pair<String, String> getNetworkIp6Dns(final Network network, final DataCenter zone) { |
| if (StringUtils.isNotBlank(network.getIp6Dns1())) { |
| return new Pair<>(network.getIp6Dns1(), network.getIp6Dns2()); |
| } |
| if (network.getVpcId() != null) { |
| Vpc vpc = vpcDao.findById(network.getVpcId()); |
| if (vpc != null && StringUtils.isNotBlank(vpc.getIp6Dns1())) { |
| return new Pair<>(vpc.getIp6Dns1(), vpc.getIp6Dns2()); |
| } |
| } |
| return new Pair<>(zone.getIp6Dns1(), zone.getIp6Dns2()); |
| } |
| |
| @Override |
| public void verifyIp4DnsPair(String ip4Dns1, String ip4Dns2) { |
| if (StringUtils.isEmpty(ip4Dns1) && StringUtils.isNotEmpty(ip4Dns2)) { |
| throw new InvalidParameterValueException("Second IPv4 DNS can be specified only with the first IPv4 DNS"); |
| } |
| if (StringUtils.isNotEmpty(ip4Dns1) && !NetUtils.isValidIp4(ip4Dns1)) { |
| throw new InvalidParameterValueException("Invalid IPv4 for DNS1"); |
| } |
| if (StringUtils.isNotEmpty(ip4Dns2) && !NetUtils.isValidIp4(ip4Dns2)) { |
| throw new InvalidParameterValueException("Invalid IPv4 for DNS2"); |
| } |
| } |
| |
| @Override |
| public void verifyIp6DnsPair(String ip6Dns1, String ip6Dns2) { |
| if (StringUtils.isEmpty(ip6Dns1) && StringUtils.isNotEmpty(ip6Dns2)) { |
| throw new InvalidParameterValueException("Second IPv6 DNS can be specified only with the first IPv6 DNS"); |
| } |
| if (StringUtils.isNotEmpty(ip6Dns1) && !NetUtils.isValidIp6(ip6Dns1)) { |
| throw new InvalidParameterValueException("Invalid IPv6 for IPv6 DNS1"); |
| } |
| if (StringUtils.isNotEmpty(ip6Dns2) && !NetUtils.isValidIp6(ip6Dns2)) { |
| throw new InvalidParameterValueException("Invalid IPv6 for IPv6 DNS2"); |
| } |
| } |
| } |