You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ah...@apache.org on 2013/09/07 00:38:37 UTC
[07/36] Moved NetworkManagerImpl to NetworkOrchestrator
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e5bb63f/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
new file mode 100755
index 0000000..1914521
--- /dev/null
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -0,0 +1,3155 @@
+// 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 org.apache.cloudstack.engine.orchestration;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.lf5.viewer.configure.ConfigurationManager;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.context.ServerContexts;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DataCenterVnetVO;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterVnetDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.domain.Domain;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.UnsupportedServiceException;
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddress.State;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Event;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkMigrationResponder;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.AccountGuestVlanMapDao;
+import com.cloud.network.dao.AccountGuestVlanMapVO;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerDao;
+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.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.UserIpv6AddressDao;
+import com.cloud.network.element.DhcpServiceProvider;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.LoadBalancingServiceProvider;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.rules.PortForwardingRuleVO;
+import com.cloud.network.rules.StaticNatRule;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.network.vpn.RemoteAccessVpnService;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Availability;
+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.user.Account;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicIpAlias;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicIpAliasDao;
+import com.cloud.vm.dao.NicIpAliasVO;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+/**
+ * NetworkManagerImpl implements NetworkManager.
+ */
+@Local(value = { NetworkOrchestrationService.class})
+public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestrationService, Listener {
+ static final Logger s_logger = Logger.getLogger(NetworkOrchestrator.class);
+
+ @Inject
+ EntityManager _entityMgr = null;
+ @Inject
+ DataCenterDao _dcDao = null;
+ @Inject
+ VlanDao _vlanDao = null;
+ @Inject
+ IPAddressDao _ipAddressDao = null;
+ @Inject
+ AccountDao _accountDao = null;
+ @Inject
+ ConfigurationDao _configDao;
+ @Inject
+ UserVmDao _userVmDao = null;
+ @Inject
+ AlertManager _alertMgr;
+ @Inject
+ AccountManager _accountMgr;
+ @Inject
+ ConfigurationManager _configMgr;
+ @Inject
+ NetworkOfferingDao _networkOfferingDao = null;
+ @Inject
+ NetworkDao _networksDao = null;
+ @Inject
+ NicDao _nicDao = null;
+ @Inject
+ RulesManager _rulesMgr;
+ @Inject
+ LoadBalancingRulesManager _lbMgr;
+ @Inject
+ RemoteAccessVpnService _vpnMgr;
+ @Inject
+ PodVlanMapDao _podVlanMapDao;
+ @Inject
+ NetworkOfferingDetailsDao _ntwkOffDetailsDao;
+ @Inject
+ ConfigurationServer _configServer;
+ @Inject
+ AccountGuestVlanMapDao _accountGuestVlanMapDao;
+ @Inject
+ DataCenterVnetDao _datacenterVnetDao;
+ @Inject
+ NetworkAccountDao _networkAccountDao;
+ @Inject
+ protected NicIpAliasDao _nicIpAliasDao;
+ @Inject
+ protected IPAddressDao _publicIpAddressDao;
+ @Inject
+ protected IpAddressManager _ipAddrMgr;
+
+ List<NetworkGuru> _networkGurus;
+ public List<NetworkGuru> getNetworkGurus() {
+ return _networkGurus;
+ }
+ public void setNetworkGurus(List<NetworkGuru> _networkGurus) {
+ this._networkGurus = _networkGurus;
+ }
+
+ List<NetworkElement> _networkElements;
+ public List<NetworkElement> getNetworkElements() {
+ return _networkElements;
+ }
+ public void setNetworkElements(List<NetworkElement> _networkElements) {
+ this._networkElements = _networkElements;
+ }
+
+ @Inject NetworkDomainDao _networkDomainDao;
+
+ List<IpDeployer> _ipDeployers;
+ public List<IpDeployer> getIpDeployers() {
+ return _ipDeployers;
+ }
+ public void setIpDeployers(List<IpDeployer> _ipDeployers) {
+ this._ipDeployers = _ipDeployers;
+ }
+
+ List<DhcpServiceProvider> _dhcpProviders;
+ public List<DhcpServiceProvider> getDhcpProviders() {
+ return _dhcpProviders;
+ }
+ public void setDhcpProviders(List<DhcpServiceProvider> _dhcpProviders) {
+ this._dhcpProviders = _dhcpProviders;
+ }
+
+ @Inject
+ VMInstanceDao _vmDao;
+ @Inject
+ FirewallManager _firewallMgr;
+ @Inject
+ FirewallRulesDao _firewallDao;
+ @Inject
+ ResourceLimitService _resourceLimitMgr;
+
+ @Inject
+ NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+ @Inject
+ PhysicalNetworkDao _physicalNetworkDao;
+ @Inject
+ PhysicalNetworkServiceProviderDao _pNSPDao;
+ @Inject
+ PortForwardingRulesDao _portForwardingRulesDao;
+ @Inject
+ LoadBalancerDao _lbDao;
+ @Inject
+ PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ NetworkServiceMapDao _ntwkSrvcDao;
+ @Inject
+ VpcManager _vpcMgr;
+ @Inject
+ PrivateIpDao _privateIpDao;
+ @Inject
+ NetworkACLManager _networkACLMgr;
+ @Inject
+ UsageEventDao _usageEventDao;
+ @Inject
+ NetworkModel _networkModel;
+ @Inject
+ NicSecondaryIpDao _nicSecondaryIpDao;
+ @Inject
+ UserIpv6AddressDao _ipv6Dao;
+ @Inject
+ Ipv6AddressManager _ipv6Mgr;
+ @Inject
+ PortableIpDao _portableIpDao;
+
+ protected StateMachine2<Network.State, Network.Event, Network> _stateMachine;
+ ScheduledExecutorService _executor;
+
+ SearchBuilder<IPAddressVO> AssignIpAddressSearch;
+ SearchBuilder<IPAddressVO> AssignIpAddressFromPodVlanSearch;
+
+ int _networkGcWait;
+ int _networkGcInterval;
+ int _networkLockTimeout;
+
+ private Map<String, String> _configs;
+
+ HashMap<Long, Long> _lastNetworkIdsToFree = new HashMap<Long, Long>();
+
+
+
+
+ @Override
+ @DB
+ public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+ _configs = _configDao.getConfiguration("AgentManager", params);
+ _networkGcWait = NumbersUtil.parseInt(_configs.get(Config.NetworkGcWait.key()), 600);
+ _networkGcInterval = NumbersUtil.parseInt(_configs.get(Config.NetworkGcInterval.key()), 600);
+
+ _configs = _configDao.getConfiguration("Network", params);
+
+ _networkLockTimeout = NumbersUtil.parseInt(_configs.get(Config.NetworkLockTimeout.key()), 600);
+
+ // populate providers
+ Map<Network.Service, Set<Network.Provider>> defaultSharedNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+ Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
+
+ defaultProviders.add(Network.Provider.VirtualRouter);
+ defaultSharedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+ defaultSharedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+ defaultSharedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+
+ Map<Network.Service, Set<Network.Provider>> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders;
+ defaultIsolatedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+ defaultIsolatedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+ defaultIsolatedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+ defaultIsolatedNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
+ defaultIsolatedNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
+ defaultIsolatedNetworkOfferingProviders.put(Service.Lb, defaultProviders);
+ defaultIsolatedNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
+ defaultIsolatedNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
+ defaultIsolatedNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
+
+ Map<Network.Service, Set<Network.Provider>> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+ defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+ defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+ defaultSharedSGEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+ Set<Provider> sgProviders = new HashSet<Provider>();
+ sgProviders.add(Provider.SecurityGroupProvider);
+ defaultSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, sgProviders);
+
+ Map<Network.Service, Set<Network.Provider>> defaultIsolatedSourceNatEnabledNetworkOfferingProviders =
+ new HashMap<Network.Service, Set<Network.Provider>>();
+ defaultProviders.clear();
+ defaultProviders.add(Network.Provider.VirtualRouter);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Lb, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.SourceNat, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
+ defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
+
+
+ Map<Network.Service, Set<Network.Provider>> defaultVPCOffProviders =
+ new HashMap<Network.Service, Set<Network.Provider>>();
+ defaultProviders.clear();
+ defaultProviders.add(Network.Provider.VirtualRouter);
+ defaultVPCOffProviders.put(Service.Dhcp, defaultProviders);
+ defaultVPCOffProviders.put(Service.Dns, defaultProviders);
+ defaultVPCOffProviders.put(Service.UserData, defaultProviders);
+ defaultVPCOffProviders.put(Service.NetworkACL, defaultProviders);
+ defaultVPCOffProviders.put(Service.Gateway, defaultProviders);
+ defaultVPCOffProviders.put(Service.Lb, defaultProviders);
+ defaultVPCOffProviders.put(Service.SourceNat, defaultProviders);
+ defaultVPCOffProviders.put(Service.StaticNat, defaultProviders);
+ defaultVPCOffProviders.put(Service.PortForwarding, defaultProviders);
+ defaultVPCOffProviders.put(Service.Vpn, defaultProviders);
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ NetworkOfferingVO offering = null;
+ //#1 - quick cloud network offering
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
+ offering =
+ _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices,
+ "Offering for QuickCloud with no services", TrafficType.Guest, null, true,
+ Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true,
+ Network.GuestType.Shared, false, null, true, null, true, false, null, false, null);
+ offering.setState(NetworkOffering.State.Enabled);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+ //#2 - SG enabled network offering
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
+ offering =
+ _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService,
+ "Offering for Shared Security group enabled networks", TrafficType.Guest, null, true,
+ Availability.Optional, null, defaultSharedNetworkOfferingProviders, true,
+ Network.GuestType.Shared, false, null, true, null, true, false, null, false, null);
+ offering.setState(NetworkOffering.State.Enabled);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+ //#3 - shared network offering with no SG service
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) {
+ offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, null,
+ defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false, null);
+ offering.setState(NetworkOffering.State.Enabled);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+
+ //#4 - default isolated offering with Source nat service
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) {
+ offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
+ "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest,
+ null, false, Availability.Required, null, defaultIsolatedSourceNatEnabledNetworkOfferingProviders,
+ true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null);
+
+ offering.setState(NetworkOffering.State.Enabled);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+ //#5 - default vpc offering with LB service
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) {
+ offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
+ "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest,
+ null, false, Availability.Optional, null, defaultVPCOffProviders,
+ true, Network.GuestType.Isolated, false, null, false, null, false, false, null,false, null);
+ offering.setState(NetworkOffering.State.Enabled);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+ //#6 - default vpc offering with no LB service
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB) == null) {
+ //remove LB service
+ defaultVPCOffProviders.remove(Service.Lb);
+ offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
+ "Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest,
+ null, false, Availability.Optional, null, defaultVPCOffProviders,
+ true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null);
+ offering.setState(NetworkOffering.State.Enabled);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+ //#7 - isolated offering with source nat disabled
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) {
+ offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering,
+ "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, true,
+ Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated,
+ false, null, true, null, true, false, null, false, null);
+ offering.setState(NetworkOffering.State.Enabled);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+ //#8 - network offering with internal lb service
+ Map<Network.Service, Set<Network.Provider>> internalLbOffProviders =
+ new HashMap<Network.Service, Set<Network.Provider>>();
+ Set<Network.Provider> defaultVpcProvider = new HashSet<Network.Provider>();
+ defaultVpcProvider.add(Network.Provider.VPCVirtualRouter);
+
+ Set<Network.Provider> defaultInternalLbProvider = new HashSet<Network.Provider>();
+ defaultInternalLbProvider.add(Network.Provider.InternalLbVm);
+
+ internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider);
+ internalLbOffProviders.put(Service.Dns, defaultVpcProvider);
+ internalLbOffProviders.put(Service.UserData, defaultVpcProvider);
+ internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider);
+ internalLbOffProviders.put(Service.Gateway, defaultVpcProvider);
+ internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider);
+ internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider);
+
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) {
+ offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB,
+ "Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest,
+ null, false, Availability.Optional, null, internalLbOffProviders,
+ true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null);
+ offering.setState(NetworkOffering.State.Enabled);
+ offering.setInternalLb(true);
+ offering.setPublicLb(false);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+ Map<Network.Service, Set<Network.Provider>> netscalerServiceProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+ Set<Network.Provider> vrProvider = new HashSet<Network.Provider>();
+ vrProvider.add(Provider.VirtualRouter);
+ Set<Network.Provider> sgProvider = new HashSet<Network.Provider>();
+ sgProvider.add(Provider.SecurityGroupProvider);
+ Set<Network.Provider> nsProvider = new HashSet<Network.Provider>();
+ nsProvider.add(Provider.Netscaler);
+ netscalerServiceProviders.put(Service.Dhcp, vrProvider);
+ netscalerServiceProviders.put(Service.Dns, vrProvider);
+ netscalerServiceProviders.put(Service.UserData, vrProvider);
+ netscalerServiceProviders.put(Service.SecurityGroup, sgProvider);
+ netscalerServiceProviders.put(Service.StaticNat, nsProvider);
+ netscalerServiceProviders.put(Service.Lb, nsProvider);
+
+ Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
+ Map<Capability, String> elb = new HashMap<Capability, String>();
+ elb.put(Capability.ElasticLb, "true");
+ Map<Capability, String> eip = new HashMap<Capability, String>();
+ eip.put(Capability.ElasticIp, "true");
+ serviceCapabilityMap.put(Service.Lb, elb);
+ serviceCapabilityMap.put(Service.StaticNat, eip);
+
+ if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) {
+ offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true,
+ Availability.Optional, null, netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null);
+ offering.setState(NetworkOffering.State.Enabled);
+ offering.setDedicatedLB(false);
+ _networkOfferingDao.update(offering.getId(), offering);
+ }
+
+ txn.commit();
+
+
+ AssignIpAddressSearch = _ipAddressDao.createSearchBuilder();
+ AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ);
+ AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
+ AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.IN);
+ SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
+ vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
+ vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ);
+ AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER);
+ AssignIpAddressSearch.done();
+
+ AssignIpAddressFromPodVlanSearch = _ipAddressDao.createSearchBuilder();
+ AssignIpAddressFromPodVlanSearch.and("dc", AssignIpAddressFromPodVlanSearch.entity().getDataCenterId(), Op.EQ);
+ AssignIpAddressFromPodVlanSearch.and("allocated", AssignIpAddressFromPodVlanSearch.entity().getAllocatedTime(), Op.NULL);
+ AssignIpAddressFromPodVlanSearch.and("vlanId", AssignIpAddressFromPodVlanSearch.entity().getVlanId(), Op.IN);
+
+ SearchBuilder<VlanVO> podVlanSearch = _vlanDao.createSearchBuilder();
+ podVlanSearch.and("type", podVlanSearch.entity().getVlanType(), Op.EQ);
+ podVlanSearch.and("networkId", podVlanSearch.entity().getNetworkId(), Op.EQ);
+ SearchBuilder<PodVlanMapVO> podVlanMapSB = _podVlanMapDao.createSearchBuilder();
+ podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ);
+ AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER);
+ AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER);
+
+
+ AssignIpAddressFromPodVlanSearch.done();
+
+ _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Network-Scavenger"));
+
+ _agentMgr.registerForHostEvents(this, true, false, true);
+
+ Network.State.getStateMachine().registerListener(new NetworkStateListener(_usageEventDao, _networksDao));
+
+ s_logger.info("Network Manager is configured.");
+
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ _executor.scheduleWithFixedDelay(new NetworkGarbageCollector(), _networkGcInterval, _networkGcInterval, TimeUnit.SECONDS);
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ protected NetworkOrchestrator() {
+ setStateMachine();
+ }
+
+ @Override
+ public List<? extends Network> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name,
+ String displayText, boolean isDefault)
+ throws ConcurrentOperationException {
+ return setupNetwork(owner, offering, null, plan, name, displayText, false, null, null, null, null, true);
+ }
+
+ @Override
+ @DB
+ public List<? extends Network> setupNetwork(Account owner, NetworkOffering offering, Network predefined, DeploymentPlan
+ plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId,
+ ACLType aclType, Boolean subdomainAccess, Long vpcId, Boolean isDisplayNetworkEnabled) throws ConcurrentOperationException {
+
+ Account locked = _accountDao.acquireInLockTable(owner.getId());
+ if (locked == null) {
+ throw new ConcurrentOperationException("Unable to acquire lock on " + owner);
+ }
+
+ try {
+ if (predefined == null
+ || (offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null &&
+ !(predefined.getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch))) {
+ List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
+ if (configs.size() > 0) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Found existing network configuration for offering " + offering + ": " + configs.get(0));
+ }
+
+ if (errorIfAlreadySetup) {
+ InvalidParameterValueException ex = new InvalidParameterValueException("Found existing network configuration (with specified id) for offering (with specified id)");
+ ex.addProxyObject(offering.getUuid(), "offeringId");
+ ex.addProxyObject(configs.get(0).getUuid(), "networkConfigId");
+ throw ex;
+ } else {
+ return configs;
+ }
+ }
+ }
+
+ List<NetworkVO> networks = new ArrayList<NetworkVO>();
+
+ long related = -1;
+
+ for (NetworkGuru guru : _networkGurus) {
+ Network network = guru.design(offering, plan, predefined, owner);
+ if (network == null) {
+ continue;
+ }
+
+ if (network.getId() != -1) {
+ if (network instanceof NetworkVO) {
+ networks.add((NetworkVO) network);
+ } else {
+ networks.add(_networksDao.findById(network.getId()));
+ }
+ continue;
+ }
+
+ long id = _networksDao.getNextInSequence(Long.class, "id");
+ if (related == -1) {
+ related = id;
+ }
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(),
+ related, name, displayText, predefined.getNetworkDomain(), offering.getGuestType(),
+ plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges(), vpcId);
+ vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled);
+ networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated,
+ finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId())));
+
+ if (domainId != null && aclType == ACLType.Domain) {
+ if (subdomainAccess == null ) {
+ subdomainAccess = true;
+ }
+ _networksDao.addDomainToNetwork(id, domainId, subdomainAccess);
+ }
+
+ txn.commit();
+ }
+
+ if (networks.size() < 1) {
+ // see networkOfferingVO.java
+ CloudRuntimeException ex = new CloudRuntimeException("Unable to convert network offering with specified id to network profile");
+ ex.addProxyObject(offering.getUuid(), "offeringId");
+ throw ex;
+ }
+
+ return networks;
+ } finally {
+ s_logger.debug("Releasing lock for " + locked);
+ _accountDao.releaseFromLockTable(locked.getId());
+ }
+ }
+
+
+
+ @Override
+ @DB
+ public void allocate(VirtualMachineProfile vm, LinkedHashMap<? extends Network, ? extends NicProfile> networks)
+ throws InsufficientCapacityException, ConcurrentOperationException {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ int deviceId = 0;
+
+ boolean[] deviceIds = new boolean[networks.size()];
+ Arrays.fill(deviceIds, false);
+
+ List<NicProfile> nics = new ArrayList<NicProfile>(networks.size());
+ NicProfile defaultNic = null;
+
+ for (Map.Entry<? extends Network, ? extends NicProfile> network : networks.entrySet()) {
+ Network config = network.getKey();
+ NicProfile requested = network.getValue();
+
+ Boolean isDefaultNic = false;
+ if (vm != null && (requested != null && requested.isDefaultNic())) {
+ isDefaultNic = true;
+ }
+
+ while (deviceIds[deviceId] && deviceId < deviceIds.length) {
+ deviceId++;
+ }
+
+ Pair<NicProfile,Integer> vmNicPair = allocateNic(requested, config, isDefaultNic,
+ deviceId, vm);
+
+ NicProfile vmNic = vmNicPair.first();
+ if (vmNic == null) {
+ continue;
+ }
+
+ deviceId = vmNicPair.second();
+
+ int devId = vmNic.getDeviceId();
+ if (devId > deviceIds.length) {
+ throw new IllegalArgumentException("Device id for nic is too large: " + vmNic);
+ }
+ if (deviceIds[devId]) {
+ throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic);
+ }
+
+ deviceIds[devId] = true;
+
+ if (vmNic.isDefaultNic()) {
+ if (defaultNic != null) {
+ throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " +
+ defaultNic + "; nic 2 = " + vmNic);
+ }
+ defaultNic = vmNic;
+ }
+
+ nics.add(vmNic);
+ vm.addNic(vmNic);
+
+ }
+
+ if (nics.size() != networks.size()) {
+ s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested networks " + networks.size());
+ throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + networks.size());
+ }
+
+ if (nics.size() == 1) {
+ nics.get(0).setDefaultNic(true);
+ }
+
+ txn.commit();
+ }
+
+
+ @DB
+ @Override
+ public Pair<NicProfile,Integer> allocateNic(NicProfile requested, Network network, Boolean isDefaultNic,
+ int deviceId, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException,
+ InsufficientAddressCapacityException, ConcurrentOperationException{
+
+ NetworkVO ntwkVO = _networksDao.findById(network.getId());
+ s_logger.debug("Allocating nic for vm " + vm.getVirtualMachine() + " in network " + network + " with requested profile " + requested);
+ NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, ntwkVO.getGuruName());
+
+ if (requested != null && requested.getMode() == null) {
+ requested.setMode(network.getMode());
+ }
+ NicProfile profile = guru.allocate(network, requested, vm);
+ if (isDefaultNic != null) {
+ profile.setDefaultNic(isDefaultNic);
+ }
+
+ if (profile == null) {
+ return null;
+ }
+
+ if (requested != null && requested.getMode() == null) {
+ profile.setMode(requested.getMode());
+ } else {
+ profile.setMode(network.getMode());
+ }
+
+ NicVO vo = new NicVO(guru.getName(), vm.getId(), network.getId(), vm.getType());
+
+ deviceId = applyProfileToNic(vo, profile, deviceId);
+
+ vo = _nicDao.persist(vo);
+
+ Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
+ NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate,
+ _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(),
+ network));
+
+ return new Pair<NicProfile,Integer>(vmNic, Integer.valueOf(deviceId));
+ }
+
+ protected Integer applyProfileToNic(NicVO vo, NicProfile profile, Integer deviceId) {
+ if (profile.getDeviceId() != null) {
+ vo.setDeviceId(profile.getDeviceId());
+ } else if (deviceId != null) {
+ vo.setDeviceId(deviceId++);
+ }
+
+ if (profile.getReservationStrategy() != null) {
+ vo.setReservationStrategy(profile.getReservationStrategy());
+ }
+
+ vo.setDefaultNic(profile.isDefaultNic());
+
+ vo.setIp4Address(profile.getIp4Address());
+ vo.setAddressFormat(profile.getFormat());
+
+ if (profile.getMacAddress() != null) {
+ vo.setMacAddress(profile.getMacAddress());
+ }
+
+ vo.setMode(profile.getMode());
+ vo.setNetmask(profile.getNetmask());
+ vo.setGateway(profile.getGateway());
+
+ if (profile.getBroadCastUri() != null) {
+ vo.setBroadcastUri(profile.getBroadCastUri());
+ }
+
+ if (profile.getIsolationUri() != null) {
+ vo.setIsolationUri(profile.getIsolationUri());
+ }
+
+ vo.setState(Nic.State.Allocated);
+
+ vo.setIp6Address(profile.getIp6Address());
+ vo.setIp6Gateway(profile.getIp6Gateway());
+ vo.setIp6Cidr(profile.getIp6Cidr());
+
+ return deviceId;
+ }
+
+ protected void applyProfileToNicForRelease(NicVO vo, NicProfile profile) {
+ vo.setGateway(profile.getGateway());
+ vo.setAddressFormat(profile.getFormat());
+ vo.setIp4Address(profile.getIp4Address());
+ vo.setIp6Address(profile.getIp6Address());
+ vo.setMacAddress(profile.getMacAddress());
+ if (profile.getReservationStrategy() != null) {
+ vo.setReservationStrategy(profile.getReservationStrategy());
+ }
+ vo.setBroadcastUri(profile.getBroadCastUri());
+ vo.setIsolationUri(profile.getIsolationUri());
+ vo.setNetmask(profile.getNetmask());
+ }
+
+ protected void applyProfileToNetwork(NetworkVO network, NetworkProfile profile) {
+ network.setBroadcastUri(profile.getBroadcastUri());
+ network.setDns1(profile.getDns1());
+ network.setDns2(profile.getDns2());
+ network.setPhysicalNetworkId(profile.getPhysicalNetworkId());
+ }
+
+ protected NicTO toNicTO(NicVO nic, NicProfile profile, NetworkVO config) {
+ NicTO to = new NicTO();
+ to.setDeviceId(nic.getDeviceId());
+ to.setBroadcastType(config.getBroadcastDomainType());
+ to.setType(config.getTrafficType());
+ to.setIp(nic.getIp4Address());
+ to.setNetmask(nic.getNetmask());
+ to.setMac(nic.getMacAddress());
+ to.setDns1(profile.getDns1());
+ to.setDns2(profile.getDns2());
+ if (nic.getGateway() != null) {
+ to.setGateway(nic.getGateway());
+ } else {
+ to.setGateway(config.getGateway());
+ }
+ to.setDefaultNic(nic.isDefaultNic());
+ to.setBroadcastUri(nic.getBroadcastUri());
+ to.setIsolationuri(nic.getIsolationUri());
+ if (profile != null) {
+ to.setDns1(profile.getDns1());
+ to.setDns2(profile.getDns2());
+ }
+
+ Integer networkRate = _networkModel.getNetworkRate(config.getId(), null);
+ to.setNetworkRateMbps(networkRate);
+
+ to.setUuid(config.getUuid());
+
+ return to;
+ }
+
+ boolean isNetworkImplemented(NetworkVO network) {
+ Network.State state = network.getState();
+ if (state == Network.State.Implemented || state == Network.State.Implementing) {
+ return true;
+ } else if (state == Network.State.Setup) {
+ DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
+ if (!isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) || (zone.getNetworkType() == NetworkType.Basic)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ @DB
+ public Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDestination dest, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException,
+ InsufficientCapacityException {
+ Transaction.currentTxn();
+ Pair<NetworkGuru, NetworkVO> implemented = new Pair<NetworkGuru, NetworkVO>(null, null);
+
+ NetworkVO network = _networksDao.findById(networkId);
+ NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName());
+ if (isNetworkImplemented(network)) {
+ s_logger.debug("Network id=" + networkId + " is already implemented");
+ implemented.set(guru, network);
+ return implemented;
+ }
+
+ // Acquire lock only when network needs to be implemented
+ network = _networksDao.acquireInLockTable(networkId, _networkLockTimeout);
+ if (network == null) {
+ // see NetworkVO.java
+ ConcurrentOperationException ex = new ConcurrentOperationException("Unable to acquire network configuration");
+ ex.addProxyObject(ApiDBUtils.findNetworkById(networkId).getUuid());
+ throw ex;
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Lock is acquired for network id " + networkId + " as a part of network implement");
+ }
+
+ try {
+ if (isNetworkImplemented(network)) {
+ s_logger.debug("Network id=" + networkId + " is already implemented");
+ implemented.set(guru, network);
+ return implemented;
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Asking " + guru.getName() + " to implement " + network);
+ }
+
+ NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+
+ network.setReservationId(context.getReservationId());
+ if (isSharedNetworkWithServices(network)) {
+ network.setState(Network.State.Implementing);
+ } else {
+ stateTransitTo(network, Event.ImplementNetwork);
+ }
+
+ Network result = guru.implement(network, offering, dest, context);
+ network.setCidr(result.getCidr());
+ network.setBroadcastUri(result.getBroadcastUri());
+ network.setGateway(result.getGateway());
+ network.setMode(result.getMode());
+ network.setPhysicalNetworkId(result.getPhysicalNetworkId());
+ _networksDao.update(networkId, network);
+
+ // implement network elements and re-apply all the network rules
+ implementNetworkElementsAndResources(dest, context, network, offering);
+
+ if (isSharedNetworkWithServices(network)) {
+ network.setState(Network.State.Implemented);
+ } else {
+ stateTransitTo(network,Event.OperationSucceeded);
+ }
+
+ network.setRestartRequired(false);
+ _networksDao.update(network.getId(), network);
+ implemented.set(guru, network);
+ return implemented;
+ } catch (NoTransitionException e) {
+ s_logger.error(e.getMessage());
+ return null;
+ } finally {
+ if (implemented.first() == null) {
+ s_logger.debug("Cleaning up because we're unable to implement the network " + network);
+ try {
+ if (isSharedNetworkWithServices(network)) {
+ network.setState(Network.State.Shutdown);
+ _networksDao.update(networkId, network);
+ } else {
+ stateTransitTo(network,Event.OperationFailed);
+ }
+ } catch (NoTransitionException e) {
+ s_logger.error(e.getMessage());
+ }
+
+ shutdownNetwork(networkId, context, false);
+ }
+
+ _networksDao.releaseFromLockTable(networkId);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Lock is released for network id " + networkId + " as a part of network implement");
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return super.equals(o); //To change body of overridden methods use File | Settings | File Templates.
+ }
+
+ @Override
+ public void implementNetworkElementsAndResources(DeployDestination dest, ReservationContext context,
+ Network network, NetworkOffering offering)
+ throws ConcurrentOperationException, InsufficientAddressCapacityException, ResourceUnavailableException, InsufficientCapacityException {
+
+ // Associate a source NAT IP (if one isn't already associated with the network) if this is a
+ // 1) 'Isolated' or 'Shared' guest virtual network in the advance zone
+ // 2) network has sourceNat service
+ // 3) network offering does not support a shared source NAT rule
+
+ boolean sharedSourceNat = offering.getSharedSourceNat();
+ DataCenter zone = _dcDao.findById(network.getDataCenterId());
+
+ if (!sharedSourceNat && _networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat)
+ && (network.getGuestType() == Network.GuestType.Isolated ||
+ (network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced))) {
+
+ List<IPAddressVO> ips = null;
+ if (network.getVpcId() != null) {
+ ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), true);
+ if (ips.isEmpty()) {
+ throw new CloudRuntimeException("Vpc is not implemented; there is no source nat ip");
+ }
+ } else {
+ ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true);
+ }
+
+ if (ips.isEmpty()) {
+ s_logger.debug("Creating a source nat ip for network " + network);
+ Account owner = _accountMgr.getAccount(network.getAccountId());
+ _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network);
+ }
+ }
+
+ // get providers to implement
+ List<Provider> providersToImplement = getNetworkProviders(network.getId());
+ for (NetworkElement element : _networkElements) {
+ if (providersToImplement.contains(element.getProvider())) {
+ if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+ // The physicalNetworkId will not get translated into a uuid by the reponse serializer,
+ // because the serializer would look up the NetworkVO class's table and retrieve the
+ // network id instead of the physical network id.
+ // So just throw this exception as is. We may need to TBD by changing the serializer.
+ throw new CloudRuntimeException("Service provider " + element.getProvider().getName() +
+ " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Asking " + element.getName() + " to implemenet " + network);
+ }
+
+ if (!element.implement(network, offering, dest, context)) {
+ CloudRuntimeException ex = new CloudRuntimeException("Failed to implement provider " + element.getProvider().getName() + " for network with specified id");
+ ex.addProxyObject(network.getUuid(), "networkId");
+ throw ex;
+ }
+ }
+ }
+
+ // reapply all the firewall/staticNat/lb rules
+ s_logger.debug("Reprogramming network " + network + " as a part of network implement");
+ if (!reprogramNetworkRules(network.getId(), CallContext.current().getCallingAccount(), network)) {
+ s_logger.warn("Failed to re-program the network as a part of network " + network + " implement");
+ // see DataCenterVO.java
+ ResourceUnavailableException ex = new ResourceUnavailableException("Unable to apply network rules as a part of network " + network + " implement", DataCenter.class, network.getDataCenterId());
+ ex.addProxyObject(ApiDBUtils.findZoneById(network.getDataCenterId()).getUuid());
+ throw ex;
+ }
+ }
+
+ // This method re-programs the rules/ips for existing network
+ protected boolean reprogramNetworkRules(long networkId, Account caller, Network network) throws ResourceUnavailableException {
+ boolean success = true;
+ // associate all ip addresses
+ if (!_ipAddrMgr.applyIpAssociations(network, false)) {
+ s_logger.warn("Failed to apply ip addresses as a part of network id" + networkId + " restart");
+ success = false;
+ }
+
+ // apply static nat
+ if (!_rulesMgr.applyStaticNatsForNetwork(networkId, false, caller)) {
+ s_logger.warn("Failed to apply static nats a part of network id" + networkId + " restart");
+ success = false;
+ }
+
+ // apply firewall rules
+ List<FirewallRuleVO> firewallIngressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
+ if (!_firewallMgr.applyFirewallRules(firewallIngressRulesToApply, false, caller)) {
+ s_logger.warn("Failed to reapply Ingress firewall rule(s) as a part of network id=" + networkId + " restart");
+ success = false;
+ }
+
+ List<FirewallRuleVO> firewallEgressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
+ if (firewallEgressRulesToApply.size() == 0) {
+ NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+ //there are no egress rules then apply the default egress rule
+ DataCenter zone = _dcDao.findById(network.getDataCenterId());
+ if (offering.getEgressDefaultPolicy() && _networkModel.areServicesSupportedInNetwork(network.getId(), Service.Firewall) &&
+ (network.getGuestType() == Network.GuestType.Isolated || (network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced))) {
+ // add default egress rule to accept the traffic
+ _firewallMgr.applyDefaultEgressFirewallRule(network.getId(), true);
+ }
+ } else {
+ if (!_firewallMgr.applyFirewallRules(firewallEgressRulesToApply, false, caller)) {
+ s_logger.warn("Failed to reapply firewall Egress rule(s) as a part of network id=" + networkId + " restart");
+ success = false;
+ }
+ }
+
+ // apply port forwarding rules
+ if (!_rulesMgr.applyPortForwardingRulesForNetwork(networkId, false, caller)) {
+ s_logger.warn("Failed to reapply port forwarding rule(s) as a part of network id=" + networkId + " restart");
+ success = false;
+ }
+
+ // apply static nat rules
+ if (!_rulesMgr.applyStaticNatRulesForNetwork(networkId, false, caller)) {
+ s_logger.warn("Failed to reapply static nat rule(s) as a part of network id=" + networkId + " restart");
+ success = false;
+ }
+
+ // apply public load balancer rules
+ if (!_lbMgr.applyLoadBalancersForNetwork(networkId, Scheme.Public)) {
+ s_logger.warn("Failed to reapply Public load balancer rules as a part of network id=" + networkId + " restart");
+ success = false;
+ }
+
+ // apply internal load balancer rules
+ if (!_lbMgr.applyLoadBalancersForNetwork(networkId, Scheme.Internal)) {
+ s_logger.warn("Failed to reapply internal load balancer rules as a part of network id=" + networkId + " restart");
+ success = false;
+ }
+
+ // apply vpn rules
+ List<? extends RemoteAccessVpn> vpnsToReapply = _vpnMgr.listRemoteAccessVpns(networkId);
+ if (vpnsToReapply != null) {
+ for (RemoteAccessVpn vpn : vpnsToReapply) {
+ // Start remote access vpn per ip
+ if (_vpnMgr.startRemoteAccessVpn(vpn.getServerAddressId(), false) == null) {
+ s_logger.warn("Failed to reapply vpn rules as a part of network id=" + networkId + " restart");
+ success = false;
+ }
+ }
+ }
+
+ //apply network ACLs
+ if (!_networkACLMgr.applyACLToNetwork(networkId)) {
+ s_logger.warn("Failed to reapply network ACLs as a part of of network id=" + networkId + " restart");
+ success = false;
+ }
+
+ return success;
+ }
+
+ protected boolean prepareElement(NetworkElement element, Network network,
+ NicProfile profile, VirtualMachineProfile vmProfile,
+ DeployDestination dest, ReservationContext context) throws InsufficientCapacityException,
+ ConcurrentOperationException, ResourceUnavailableException {
+ element.prepare(network, profile, vmProfile, dest, context);
+ if (vmProfile.getType() == Type.User && element.getProvider() != null) {
+ if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp) &&
+ _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, element.getProvider()) &&
+ element instanceof DhcpServiceProvider ) {
+ DhcpServiceProvider sp = (DhcpServiceProvider) element;
+ Map <Capability, String> dhcpCapabilities = element.getCapabilities().get(Service.Dhcp);
+ String supportsMultipleSubnets = dhcpCapabilities.get(Capability.DhcpAccrossMultipleSubnets);
+ if ((supportsMultipleSubnets != null && Boolean.valueOf(supportsMultipleSubnets)) && profile.getIp6Address() == null) {
+ if (!sp.configDhcpSupportForSubnet(network, profile, vmProfile, dest, context)) {
+ return false;
+ }
+ }
+ sp.addDhcpEntry(network, profile, vmProfile, dest, context);
+ }
+ if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.UserData) &&
+ _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.UserData, element.getProvider()) &&
+ element instanceof UserDataServiceProvider) {
+ UserDataServiceProvider sp = (UserDataServiceProvider) element;
+ sp.addPasswordAndUserdata(network, profile, vmProfile, dest, context);
+ }
+ }
+ return true;
+ }
+
+ @DB
+ protected void updateNic(NicVO nic, long networkId, int count) {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ _nicDao.update(nic.getId(), nic);
+
+ if (nic.getVmType() == VirtualMachine.Type.User) {
+ s_logger.debug("Changing active number of nics for network id=" + networkId + " on " + count);
+ _networksDao.changeActiveNicsBy(networkId, count);
+ }
+
+ if (nic.getVmType() == VirtualMachine.Type.User || (nic.getVmType() == VirtualMachine.Type.DomainRouter && _networksDao.findById(networkId).getTrafficType() == TrafficType.Guest)) {
+ _networksDao.setCheckForGc(networkId);
+ }
+
+ txn.commit();
+ }
+
+ @Override
+ public void prepare(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException,
+ ConcurrentOperationException, ResourceUnavailableException {
+ List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
+
+ // we have to implement default nics first - to ensure that default network elements start up first in multiple
+ //nics case
+ // (need for setting DNS on Dhcp to domR's Ip4 address)
+ Collections.sort(nics, new Comparator<NicVO>() {
+
+ @Override
+ public int compare(NicVO nic1, NicVO nic2) {
+ boolean isDefault1 = nic1.isDefaultNic();
+ boolean isDefault2 = nic2.isDefaultNic();
+
+ return (isDefault1 ^ isDefault2) ? ((isDefault1 ^ true) ? 1 : -1) : 0;
+ }
+ });
+
+ for (NicVO nic : nics) {
+ Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context);
+ if (implemented.first() == null) {
+ s_logger.warn("Failed to implement network id=" + nic.getNetworkId() + " as a part of preparing nic id=" + nic.getId());
+ throw new CloudRuntimeException("Failed to implement network id=" + nic.getNetworkId() + " as a part preparing nic id=" +nic.getId());
+ }
+
+ NetworkVO network = implemented.second();
+ NicProfile profile = prepareNic(vmProfile, dest, context, nic.getId(), network);
+ vmProfile.addNic(profile);
+ }
+ }
+
+ @Override
+ public NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination
+ dest, ReservationContext context, long nicId, Network network)
+ throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
+ ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+
+ Integer networkRate = _networkModel.getNetworkRate(network.getId(), vmProfile.getId());
+ NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName());
+ NicVO nic = _nicDao.findById(nicId);
+
+ NicProfile profile = null;
+ if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) {
+ nic.setState(Nic.State.Reserving);
+ nic.setReservationId(context.getReservationId());
+ _nicDao.update(nic.getId(), nic);
+ URI broadcastUri = nic.getBroadcastUri();
+ if (broadcastUri == null) {
+ broadcastUri = network.getBroadcastUri();
+ }
+
+ URI isolationUri = nic.getIsolationUri();
+
+ profile = new NicProfile(nic, network, broadcastUri, isolationUri,
+
+ networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
+ guru.reserve(profile, network, vmProfile, dest, context);
+ nic.setIp4Address(profile.getIp4Address());
+ nic.setAddressFormat(profile.getFormat());
+ nic.setIp6Address(profile.getIp6Address());
+ nic.setMacAddress(profile.getMacAddress());
+ nic.setIsolationUri(profile.getIsolationUri());
+ nic.setBroadcastUri(profile.getBroadCastUri());
+ nic.setReserver(guru.getName());
+ nic.setState(Nic.State.Reserved);
+ nic.setNetmask(profile.getNetmask());
+ nic.setGateway(profile.getGateway());
+
+ if (profile.getStrategy() != null) {
+ nic.setReservationStrategy(profile.getStrategy());
+ }
+
+ updateNic(nic, network.getId(), 1);
+ } else {
+ profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(),
+ networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
+ guru.updateNicProfile(profile, network);
+ nic.setState(Nic.State.Reserved);
+ updateNic(nic, network.getId(), 1);
+ }
+
+ List<Provider> providersToImplement = getNetworkProviders(network.getId());
+ for (NetworkElement element : _networkElements) {
+ if (providersToImplement.contains(element.getProvider())) {
+ if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+ throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Asking " + element.getName() + " to prepare for " + nic);
+ }
+ if(!prepareElement(element, network, profile, vmProfile, dest, context)) {
+ throw new InsufficientAddressCapacityException("unable to configure the dhcp service, due to insufficiant address capacity",Network.class, network.getId());
+ }
+ }
+ }
+
+ profile.setSecurityGroupEnabled(_networkModel.isSecurityGroupSupportedInNetwork(network));
+ guru.updateNicProfile(profile, network);
+ return profile;
+ }
+
+ @Override
+ public void prepareNicForMigration(VirtualMachineProfile vm, DeployDestination dest) {
+ List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+ ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), null, null);
+ for (NicVO nic : nics) {
+ NetworkVO network = _networksDao.findById(nic.getNetworkId());
+ Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
+
+ NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName());
+ NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate,
+ _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(), network));
+ if(guru instanceof NetworkMigrationResponder){
+ if(!((NetworkMigrationResponder) guru).prepareMigration(profile, network, vm, dest, context)){
+ s_logger.error("NetworkGuru "+guru+" prepareForMigration failed."); // XXX: Transaction error
+ }
+ }
+ List<Provider> providersToImplement = getNetworkProviders(network.getId());
+ for (NetworkElement element : _networkElements) {
+ if (providersToImplement.contains(element.getProvider())) {
+ if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+ throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
+ }
+ if(element instanceof NetworkMigrationResponder){
+ if(!((NetworkMigrationResponder) element).prepareMigration(profile, network, vm, dest, context)){
+ s_logger.error("NetworkElement "+element+" prepareForMigration failed."); // XXX: Transaction error
+ }
+ }
+ }
+ }
+ guru.updateNicProfile(profile, network);
+ vm.addNic(profile);
+ }
+ }
+
+ private NicProfile findNicProfileById(VirtualMachineProfile vm, long id){
+ for(NicProfile nic: vm.getNics()){
+ if(nic.getId() == id){
+ return nic;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void commitNicForMigration(
+ VirtualMachineProfile src,
+ VirtualMachineProfile dst) {
+ for(NicProfile nicSrc: src.getNics()){
+ NetworkVO network = _networksDao.findById(nicSrc.getNetworkId());
+ NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName());
+ NicProfile nicDst = findNicProfileById(dst, nicSrc.getId());
+ ReservationContext src_context = new ReservationContextImpl(nicSrc.getReservationId(), null, null);
+ ReservationContext dst_context = new ReservationContextImpl(nicDst.getReservationId(), null, null);
+
+ if(guru instanceof NetworkMigrationResponder){
+ ((NetworkMigrationResponder) guru).commitMigration(nicSrc, network, src, src_context, dst_context);
+ }
+ List<Provider> providersToImplement = getNetworkProviders(network.getId());
+ for (NetworkElement element : _networkElements) {
+ if (providersToImplement.contains(element.getProvider())) {
+ if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+ throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
+ }
+ if(element instanceof NetworkMigrationResponder){
+ ((NetworkMigrationResponder) element).commitMigration(nicSrc, network, src, src_context, dst_context);
+ }
+ }
+ }
+ // update the reservation id
+ NicVO nicVo = _nicDao.findById(nicDst.getId());
+ nicVo.setReservationId(nicDst.getReservationId());
+ _nicDao.persist(nicVo);
+ }
+ }
+
+ @Override
+ public void rollbackNicForMigration(
+ VirtualMachineProfile src,
+ VirtualMachineProfile dst) {
+ for(NicProfile nicDst: dst.getNics()){
+ NetworkVO network = _networksDao.findById(nicDst.getNetworkId());
+ NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName());
+ NicProfile nicSrc = findNicProfileById(src, nicDst.getId());
+ ReservationContext src_context = new ReservationContextImpl(nicSrc.getReservationId(), null, null);
+ ReservationContext dst_context = new ReservationContextImpl(nicDst.getReservationId(), null, null);
+
+ if(guru instanceof NetworkMigrationResponder){
+ ((NetworkMigrationResponder) guru).rollbackMigration(nicDst, network, dst, src_context, dst_context);
+ }
+ List<Provider> providersToImplement = getNetworkProviders(network.getId());
+ for (NetworkElement element : _networkElements) {
+ if (providersToImplement.contains(element.getProvider())) {
+ if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+ throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
+ }
+ if(element instanceof NetworkMigrationResponder){
+ ((NetworkMigrationResponder) element).rollbackMigration(nicDst, network, dst, src_context, dst_context);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ @DB
+ public void release(VirtualMachineProfile vmProfile, boolean forced) throws
+ ConcurrentOperationException, ResourceUnavailableException {
+ List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
+ for (NicVO nic : nics) {
+ releaseNic(vmProfile, nic.getId());
+ }
+ }
+
+
+ @Override
+ @DB
+ public void releaseNic(VirtualMachineProfile vmProfile, Nic nic)
+ throws ConcurrentOperationException, ResourceUnavailableException {
+ releaseNic(vmProfile, nic.getId());
+ }
+
+ @DB
+ protected void releaseNic(VirtualMachineProfile vmProfile, long nicId)
+ throws ConcurrentOperationException, ResourceUnavailableException {
+ //lock the nic
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ NicVO nic = _nicDao.lockRow(nicId, true);
+ if (nic == null) {
+ throw new ConcurrentOperationException("Unable to acquire lock on nic " + nic);
+ }
+
+ Nic.State originalState = nic.getState();
+ NetworkVO network = _networksDao.findById(nic.getNetworkId());
+
+ if (originalState == Nic.State.Reserved || originalState == Nic.State.Reserving) {
+ if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) {
+ NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName());
+ nic.setState(Nic.State.Releasing);
+ _nicDao.update(nic.getId(), nic);
+ NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null,
+ _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
+ if (guru.release(profile, vmProfile, nic.getReservationId())) {
+ applyProfileToNicForRelease(nic, profile);
+ nic.setState(Nic.State.Allocated);
+ if (originalState == Nic.State.Reserved) {
+ updateNic(nic, network.getId(), -1);
+ } else {
+ _nicDao.update(nic.getId(), nic);
+ }
+ }
+ //commit the transaction before proceeding releasing nic profile on the network elements
+ txn.commit();
+
+ // Perform release on network elements
+ List<Provider> providersToImplement = getNetworkProviders(network.getId());
+ for (NetworkElement element : _networkElements) {
+ if (providersToImplement.contains(element.getProvider())) {
+ if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+ throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Asking " + element.getName() + " to release " + nic);
+ }
+ //NOTE: Context appear to never be used in release method
+ //implementations. Consider removing it from interface Element
+ element.release(network, profile, vmProfile, null);
+ }
+ }
+
+ } else {
+ nic.setState(Nic.State.Allocated);
+ updateNic(nic, network.getId(), -1);
+ txn.commit();
+ }
+ }
+ }
+
+ @Override
+ public void cleanupNics(VirtualMachineProfile vm) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Cleaning network for vm: " + vm.getId());
+ }
+
+ List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+ for (NicVO nic : nics) {
+ removeNic(vm, nic);
+ }
+ }
+
+
+ @Override
+ public void removeNic(VirtualMachineProfile vm, Nic nic) {
+ removeNic(vm, _nicDao.findById(nic.getId()));
+ }
+
+
+ protected void removeNic(VirtualMachineProfile vm, NicVO nic) {
+ nic.setState(Nic.State.Deallocating);
+ _nicDao.update(nic.getId(), nic);
+ NetworkVO network = _networksDao.findById(nic.getNetworkId());
+ NicProfile profile = new NicProfile(nic, network, null, null, null,
+ _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(), network));
+
+ /*
+ * We need to release the nics with a Create ReservationStrategy here
+ * because the nic is now being removed.
+ */
+ if (nic.getReservationStrategy() == Nic.ReservationStrategy.Create) {
+ List<Provider> providersToImplement = getNetworkProviders(network.getId());
+ for (NetworkElement element : _networkElements) {
+ if (providersToImplement.contains(element.getProvider())) {
+ if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+ throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Asking " + element.getName() + " to release " + nic);
+ }
+ try {
+ element.release(network, profile, vm, null);
+ } catch (ConcurrentOperationException ex) {
+ s_logger.warn("release failed during the nic " + nic.toString() + " removeNic due to ", ex);
+ } catch (ResourceUnavailableException ex) {
+ s_logger.warn("release failed during the nic " + nic.toString() + " removeNic due to ", ex);
+ }
+ }
+ }
+ }
+
+ // remove the dhcpservice ip if this is the last nic in subnet.
+ if (vm.getType() == Type.User && isDhcpAccrossMultipleSubnetsSupported(network) && isLastNicInSubnet(nic) &&
+ network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestType.Shared) {
+ removeDhcpServiceInSubnet(nic);
+ }
+ NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName());
+ guru.deallocate(network, profile, vm);
+ _nicDao.remove(nic.getId());
+ s_logger.debug("Removed nic id=" + nic.getId());
+ //remove the secondary ip addresses corresponding to to this nic
+ if (!removeVmSecondaryIpsOfNic(nic.getId())) {
+ s_logger.debug("Removing nic " + nic.getId() + " secondary ip addreses failed");
+ }
+ }
+
+ public boolean isDhcpAccrossMultipleSubnetsSupported(Network network) {
+ DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network);
+ Map <Network.Capability, String> capabilities = dhcpServiceProvider.getCapabilities().get(Network.Service.Dhcp);
+ String supportsMultipleSubnets = capabilities.get(Network.Capability.DhcpAccrossMultipleSubnets);
+ if (supportsMultipleSubnets != null && Boolean.valueOf(supportsMultipleSubnets)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isLastNicInSubnet(NicVO nic) {
+ if (_nicDao.listByNetworkIdTypeAndGatewayAndBroadcastUri(nic.getNetworkId(), VirtualMachine.Type.User, nic.getGateway(), nic.getBroadcastUri()).size() > 1) {
+ return false;
+ }
+ return true;
+ }
+
+ @DB
+ @Override
+ public void removeDhcpServiceInSubnet(Nic nic) {
+ Network network = _networksDao.findById(nic.getNetworkId());
+ DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network);
+ try {
+ NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(nic.getGateway(), network.getId(), NicIpAlias.state.active);
+ if (ipAlias != null) {
+ ipAlias.setState(NicIpAlias.state.revoked);
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ _nicIpAliasDao.update(ipAlias.getId(),ipAlias);
+ IPAddressVO aliasIpaddressVo = _publicIpAddressDao.findByIpAndSourceNetworkId(ipAlias.getNetworkId(), ipAlias.getIp4Address());
+ _publicIpAddressDao.unassignIpAddress(aliasIpaddressVo.getId());
+ txn.commit();
+ if (!dhcpServiceProvider.removeDhcpSupportForSubnet(network)) {
+ s_logger.warn("Failed to remove the ip alias on the router, marking it as removed in db and freed the allocated ip " + ipAlias.getIp4Address());
+ }
+ }
+ }
+ catch (ResourceUnavailableException e) {
+ //failed to remove the dhcpconfig on the router.
+ s_logger.info ("Unable to delete the ip alias due to unable to contact the virtualrouter.");
+ }
+
+ }
+
+
+
+ @Override
+ public void expungeNics(VirtualMachineProfile vm) {
+ List<NicVO> nics = _nicDao.listByVmIdIncludingRemoved(vm.getId());
+ for (NicVO nic : nics) {
+ _nicDao.expunge(nic.getId());
+ }
+ }
+
+
+
+ @Override
+ @DB
+ public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway,
+ String cidr, String vlanId, String networkDomain, Account owner, Long domainId,
+ PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
+ Boolean isDisplayNetworkEnabled, String isolatedPvlan)
+ throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
+
+ NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
+ // this method supports only guest network creation
+ if (ntwkOff.getTrafficType() != TrafficType.Guest) {
+ s_logger.warn("Only guest networks can be created using this method");
+ return null;
+ }
+
+ boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType);
+ //check resource limits
+ if (updateResourceCount) {
+ _resourceLimitMgr.checkResourceLimit(owner, ResourceType.network);
+ }
+
+ // Validate network offering
+ if (ntwkOff.getState() != NetworkOffering.State.Enabled) {
+ // see NetworkOfferingVO
+ InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its stat is not " + NetworkOffering.State.Enabled);
+ ex.addProxyObject(ntwkOff.getUuid(), "networkOfferingId");
+ throw ex;
+ }
+
+ // Validate physical network
+ if (pNtwk.getState() != PhysicalNetwork.State.Enabled) {
+ // see PhysicalNetworkVO.java
+ InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is" +
+ " in incorrect state:" + pNtwk.getState());
+ ex.addProxyObject(pNtwk.getUuid(), "physicalNetworkId");
+ throw ex;
+ }
+
+ boolean ipv6 = false;
+
+ if (ip6Gateway != null && ip6Cidr != null) {
+ ipv6 = true;
+ }
+ // Validate zone
+ DataCenterVO zone = _dcDao.findById(zoneId);
+ if (zone.getNetworkType() == NetworkType.Basic) {
+ if (ipv6) {
+ throw new InvalidParameterValueException("IPv6 is not supported in Basic zone");
+ }
+
+ // In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
+ if (aclType == null || aclType != ACLType.Domain) {
+ throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
+ }
+
+ // Only one guest network is supported in Basic zone
+ List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest);
+ if (!guestNetworks.isEmpty()) {
+ throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type "
+ + NetworkType.Basic);
+ }
+
+ // if zone is basic, only Shared network offerings w/o source nat service are allowed
+ if (!(ntwkOff.getGuestType() == GuestType.Shared &&
+ !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
+ throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " +
+ "guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName()
+ + " service are allowed");
+ }
+
+ if (domainId == null || domainId != Domain.ROOT_DOMAIN) {
+ throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain");
+ }
+
+ if (subdomainAccess == null) {
+ subdomainAccess = true;
+ } else if (!subdomainAccess) {
+ throw new InvalidParameterValueException("Subdomain access should be set to true for the" +
+ " guest network in the Basic zone");
+ }
+
+ if (vlanId == null) {
+ vlanId = Vlan.UNTAGGED;
+ } else {
+ if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
+ throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " +
+ "the zone of type " + NetworkType.Basic);
+ }
+ }
+
+ } else if (zone.getNetworkType() == NetworkType.Advanced) {
+ if (zone.isSecurityGroupEnabled()) {
+ if (ipv6) {
+ throw new InvalidParameterValueException("IPv6 is not supported with security group!");
+ }
+ if (isolatedPvlan != null) {
+ throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
+ }
+ // Only Account specific Isolated network with sourceNat service disabled are allowed in security group
+ // enabled zone
+ if ( ntwkOff.getGuestType() != GuestType.Shared ){
+ throw new InvalidParameterValueException("Only shared guest network can be created in security group enabled zone");
+ }
+ if ( _networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)) {
+ throw new InvalidParameterValueException("Service SourceNat is not allowed in security group enabled zone");
+ }
+ if (!( _networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SecurityGroup))) {
+ throw new InvalidParameterValueException("network must have SecurityGroup provider in security group enabled zone");
+ }
+ }
+
+ //don't allow eip/elb networks in Advance zone
+ if (ntwkOff.getElasticIp() || ntwkOff.getElasticLb()) {
+ throw new InvalidParameterValueException("Elastic IP and Elastic LB services are supported in zone of type " + NetworkType.Basic);
+ }
+ }
+
+ // VlanId can be specified only when network offering supports it
+ boolean vlanSpecified = (vlanId != null);
+ if (vlanSpecified != ntwkOff.getSpecifyVlan()) {
+ if (vlanSpecified) {
+ throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
+ } else {
+ throw new InvalidParameterValueException("Vlan has to be specified; corresponding offering says specifyVlan=true");
+ }
+ }
+
+ if (vlanSpecified) {
+ //don't allow to specify vlan tag used by physical network for dynamic vlan allocation
+ if (_dcDao.findVnet(zoneId, pNtwk.getId(), vlanId).size() > 0) {
+ throw new InvalidParameterValueException("The VLAN tag " + vlanId
+ + " is already being used for dynamic vlan allocation for the guest network in zone " + zone.getName());
+ }
+
+ String uri = BroadcastDomainType.fromString(vlanId).toString();
+ // For Isolated networks, don't allow to create network with vlan that already exists in the zone
+ if (ntwkOff.getGuestType() == GuestType.Isolated) {
+ if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) {
+ throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
+ } else {
+ List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString());
+ //for the network that is created as part of private gateway,
+ //the vnet is not coming from the data center vnet table, so the list can be empty
+ if (!dcVnets.isEmpty()) {
+ DataCenterVnetVO dcVnet = dcVnets.get(0);
+ // Fail network creation if specified vlan is dedicated to a different account
+ if (dcVnet.getAccountGuestVlanMapId() != null) {
+ Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
+ AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
+ if (map
<TRUNCATED>