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).
This commit is contained in:
alena 2011-01-24 18:20:05 -08:00
parent 9d3eedaf01
commit 3a008ee699
6 changed files with 110 additions and 63 deletions

View File

@ -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();
}

View File

@ -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<? extends Network> 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);

View File

@ -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.

View File

@ -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<LoadBalancingRule> 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<? extends PortForwardingRule> 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.");

View File

@ -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;
}
}
}

View File

@ -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<? extends FirewallRule> 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<? extends VpnUser> 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<? extends PublicIpAddress> 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;
}
}