From 3a008ee699e405ae016b455c0c0c0894978bfd1b Mon Sep 17 00:00:00 2001 From: alena Date: Mon, 24 Jan 2011 18:20:05 -0800 Subject: [PATCH] Changed restartNetwork command flow: * API requires network id to be passed in (it was optional before) * restartNetwork calls restart() method of all network elements in the system, and it's up to the element to decide which actions to take on the restart (for example, for Virtual Router it's IPAssoc/applyPF/applyLBRules). --- .../cloud/api/commands/RestartNetworkCmd.java | 16 ++--- api/src/com/cloud/network/NetworkService.java | 3 +- .../cloud/network/element/NetworkElement.java | 9 +++ .../com/cloud/network/NetworkManagerImpl.java | 64 ++++++------------- .../cloud/network/element/DhcpElement.java | 34 ++++++++++ .../network/element/VirtualRouterElement.java | 47 ++++++++++++-- 6 files changed, 110 insertions(+), 63 deletions(-) diff --git a/api/src/com/cloud/api/commands/RestartNetworkCmd.java b/api/src/com/cloud/api/commands/RestartNetworkCmd.java index b03c5d73ca9..32a91b75afd 100644 --- a/api/src/com/cloud/api/commands/RestartNetworkCmd.java +++ b/api/src/com/cloud/api/commands/RestartNetworkCmd.java @@ -44,20 +44,14 @@ public class RestartNetworkCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the ID of the availability zone you want to acquire an public IP address from") - private Long zoneId; - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="The network this ip address should be associated to.") - private Long networkId; + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="The network this ip address should be associated to.") + private Long id; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - - public long getZoneId() { - return zoneId; - } public String getEventDescription() { return "Restarting network: " + getNetworkId(); @@ -68,13 +62,13 @@ public class RestartNetworkCmd extends BaseAsyncCmd { } public long getEntityOwnerId() { - return _networkService.getNetwork(networkId).getAccountId(); + return _networkService.getNetwork(id).getAccountId(); } public Long getNetworkId() { - Network network = _networkService.getNetwork(networkId); + Network network = _networkService.getNetwork(id); if (network == null) { - throw new InvalidParameterValueException("Unable to find network by id " + networkId); + throw new InvalidParameterValueException("Unable to find network by id " + id); } else { return network.getId(); } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 5b0a9da8860..a6a83d83f85 100644 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -26,6 +26,7 @@ import com.cloud.api.commands.ListNetworksCmd; import com.cloud.api.commands.RestartNetworkCmd; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; @@ -51,7 +52,7 @@ public interface NetworkService { List searchForNetworks(ListNetworksCmd cmd) throws InvalidParameterValueException, PermissionDeniedException; boolean deleteNetwork(long networkId) throws InvalidParameterValueException, PermissionDeniedException; - boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException; + boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; int getActiveNicsInNetwork(long networkId); diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java index ec49880afe5..36a20dc0cc3 100644 --- a/api/src/com/cloud/network/element/NetworkElement.java +++ b/api/src/com/cloud/network/element/NetworkElement.java @@ -78,6 +78,15 @@ public interface NetworkElement extends Adapter { */ boolean shutdown(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; + /** + * The network is being restarted. + * @param network + * @param context + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean restart(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; /** * The network is being destroyed. diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 047681b979b..8a990d4dc93 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -88,10 +88,8 @@ import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.element.NetworkElement; import com.cloud.network.guru.NetworkGuru; -import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.RulesManager; import com.cloud.network.vpn.RemoteAccessVpnElement; import com.cloud.offering.NetworkOffering; @@ -101,6 +99,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; +import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.UserStatisticsVO; import com.cloud.user.dao.AccountDao; @@ -126,6 +125,7 @@ import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; +import com.cloud.vm.ReservationContextImpl; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; @@ -1774,51 +1774,27 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException { - // This method reapplies Ip addresses, LoadBalancer and PortForwarding rules - Account caller = UserContext.current().getCaller(); + public boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + // This method restarts all network elements belonging to the network Long networkId = cmd.getNetworkId(); - Network network = null; - if (networkId != null) { - network = _networksDao.findById(networkId); - if (network == null) { - throw new InvalidParameterValueException("Network id is invalid: " + networkId); - } - } - - Account owner = _accountMgr.getActiveAccount(cmd.getEntityOwnerId()); - if (!_accountMgr.isAdmin(caller.getType())) { - _accountMgr.checkAccess(caller, network); - } else { - Domain domain = _domainDao.findById(owner.getDomainId()); - _accountMgr.checkAccess(caller, domain); - } + Network network = _networksDao.findById(networkId); + Account owner = _accountMgr.getAccount(network.getAccountId()); + User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); + Account callerAccount = _accountMgr.getActiveAccount(caller.getAccountId()); + + ReservationContext context = new ReservationContextImpl(null, null, caller, owner); + + _accountMgr.checkAccess(callerAccount, network); s_logger.debug("Restarting network " + networkId + "..."); - - if (!applyIpAssociations(network, false)) { - s_logger.warn("Failed to apply ips as a part of network " + networkId + " restart"); - return false; - } else { - s_logger.debug("Ip addresses are reapplied successfully as a part of network " + networkId + " restart"); - } - - List lbRules = _lbMgr.listByNetworkId(networkId); - - if (!applyRules(lbRules, true)) { - s_logger.warn("Failed to apply load balancing rules as a part of network " + network.getId() + " restart"); - return false; - } else { - s_logger.debug("Load balancing rules are reapplied successfully as a part of network " + networkId + " restart"); - } - - // Reapply pf rules - List pfRules = _rulesMgr.listByNetworkId(networkId); - if (!applyRules(pfRules, true)) { - s_logger.warn("Failed to apply port forwarding rules as a part of network " + network.getId() + " restart"); - return false; - } else { - s_logger.debug("Port forwarding rules are reapplied successfully as a part of network " + networkId + " restart"); + + boolean success = true; + for (NetworkElement element : _networkElements) { + success = element.restart(network, context); + if (!success) { + s_logger.warn("Failed to restart network element " + element + " as a part of network restart"); + return success; + } } s_logger.debug("Network " + networkId + " is restarted successfully."); diff --git a/server/src/com/cloud/network/element/DhcpElement.java b/server/src/com/cloud/network/element/DhcpElement.java index 3caafa07466..f287c122659 100644 --- a/server/src/com/cloud/network/element/DhcpElement.java +++ b/server/src/com/cloud/network/element/DhcpElement.java @@ -25,6 +25,7 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.deploy.DeployDestination; @@ -41,6 +42,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.NetworkDao; import com.cloud.network.router.VirtualNetworkApplianceManager; +import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.offering.NetworkOffering; import com.cloud.uservm.UserVm; @@ -52,6 +54,7 @@ import com.cloud.vm.ReservationContext; import com.cloud.vm.UserVmManager; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.UserVmDao; @@ -68,6 +71,7 @@ public class DhcpElement extends AdapterBase implements NetworkElement{ @Inject UserVmManager _userVmMgr; @Inject UserVmDao _userVmDao; @Inject DomainRouterDao _routerDao; + @Inject ConfigurationManager _configMgr; private boolean canHandle(GuestIpType ipType, DeployDestination dest, TrafficType trafficType) { DataCenter dc = dest.getDataCenter(); @@ -163,4 +167,34 @@ public class DhcpElement extends AdapterBase implements NetworkElement{ return capabilities; } + + @Override + public boolean restart(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{ + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + NetworkOffering offering = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + DeployDestination dest = new DeployDestination(dc, null, null, null); + DomainRouterVO router = _routerDao.findByNetworkConfiguration(network.getId()); + if (router == null) { + s_logger.trace("Can't find dhcp element in network " + network.getId()); + return true; + } + + VirtualRouter result = null; + if (canHandle(network.getGuestType(), dest, offering.getTrafficType())) { + if (router.getState() == State.Stopped) { + result = _routerMgr.startRouter(router.getId()); + } else { + result = _routerMgr.rebootRouter(router.getId()); + } + if (result == null) { + s_logger.warn("Failed to restart dhcp element " + router + " as a part of netowrk " + network + " restart"); + return false; + } else { + return true; + } + } else { + s_logger.trace("Dhcp element doesn't handle network restart for the network " + network); + return true; + } + } } diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 10193265a50..da46251e315 100644 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -26,7 +26,9 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; @@ -48,6 +50,7 @@ import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualNetworkApplianceManager; +import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.PortForwardingRule; @@ -81,16 +84,20 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement, @Inject LoadBalancingRulesManager _lbMgr; @Inject NetworkOfferingDao _networkOfferingDao; @Inject VirtualNetworkApplianceManager _routerMgr; + @Inject ConfigurationManager _configMgr; @Inject UserVmManager _userVmMgr; @Inject UserVmDao _userVmDao; @Inject DomainRouterDao _routerDao; - @Inject DataCenterDao _dataCenterDao; @Inject LoadBalancerDao _lbDao; @Inject AccountManager _accountMgr; private boolean canHandle(GuestIpType ipType, DataCenter dc) { String provider = dc.getGatewayProvider(); - return (ipType == GuestIpType.Virtual && provider.equals(Provider.VirtualRouter.getName())); + boolean result = (ipType == GuestIpType.Virtual && provider.equals(Provider.VirtualRouter.getName())); + if (!result) { + s_logger.trace("Virtual router element only takes care of guest ip type " + GuestIpType.Virtual + " for provider " + Provider.VirtualRouter.getName()); + } + return result; } @Override @@ -150,7 +157,7 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement, @Override public boolean applyRules(Network config, List rules) throws ResourceUnavailableException { - DataCenter dc = _dataCenterDao.findById(config.getDataCenterId()); + DataCenter dc = _configMgr.getZone(config.getDataCenterId()); if (canHandle(config.getGuestType(),dc)) { long networkId = config.getId(); @@ -194,7 +201,7 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement, @Override public String[] applyVpnUsers(RemoteAccessVpn vpn, List users) throws ResourceUnavailableException{ Network network = _networkConfigDao.findById(vpn.getNetworkId()); - DataCenter dc = _dataCenterDao.findById(network.getDataCenterId()); + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); if (canHandle(network.getGuestType(),dc)) { return _routerMgr.applyVpnUsers(network, users); } else { @@ -205,7 +212,7 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement, @Override public boolean start(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException { - DataCenter dc = _dataCenterDao.findById(network.getDataCenterId()); + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); if (canHandle(network.getGuestType(),dc)) { return _routerMgr.startRemoteAccessVpn(network, vpn); } else { @@ -216,7 +223,7 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement, @Override public boolean stop(Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException { - DataCenter dc = _dataCenterDao.findById(network.getDataCenterId()); + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); if (canHandle(network.getGuestType(),dc)) { return _routerMgr.deleteRemoteAccessVpn(network, vpn); } else { @@ -228,7 +235,7 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement, @Override public boolean applyIps(Network network, List ipAddress) throws ResourceUnavailableException { - DataCenter dc = _dataCenterDao.findById(network.getDataCenterId()); + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); if (canHandle(network.getGuestType(),dc)) { return _routerMgr.associateIP(network, ipAddress); } else { @@ -281,4 +288,30 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement, return capabilities; } + @Override + public boolean restart(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{ + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + DomainRouterVO router = _routerDao.findByNetworkConfiguration(network.getId()); + if (router == null) { + s_logger.trace("Can't find domain router in network " + network.getId()); + return true; + } + + VirtualRouter result = null; + if (canHandle(network.getGuestType(), dc)) { + if (router.getState() == State.Stopped) { + result = _routerMgr.startRouter(router.getId()); + } else { + result = _routerMgr.rebootRouter(router.getId()); + } + if (result == null) { + s_logger.warn("Failed to restart domain router " + router + " as a part of netowrk " + network + " restart"); + return false; + } else { + return true; + } + } + return true; + } + }