1) Fixed associate/disassociateIP address commands. The procedure is changed from 2.1, right now on single ipAssoc command we get a new ip and reapply all exising ip associations.

2) Added restartNetwork API command. Currently the command reapplies ip addresses for the network. TODO - reapply PF/LB rules and restart the domR.
This commit is contained in:
alena 2010-12-14 19:51:51 -08:00 committed by Alena Prokharchyk
parent 66ab7e343d
commit c1db5b6fc0
11 changed files with 320 additions and 221 deletions

View File

@ -0,0 +1,120 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.api.commands;
import java.util.List;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.IPAddressResponse;
import com.cloud.api.response.SuccessResponse;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.user.UserContext;
@Implementation(description="Reapplies all ip addresses for the particular network", responseObject=IPAddressResponse.class)
public class RestartNetworkCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(RestartNetworkCmd.class.getName());
private static final String s_name = "restartnetworkresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account to associate with this IP address")
private String accountName;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the ID of the domain to associate with this IP address")
private Long domainId;
@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;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getAccountName() {
if (accountName != null) {
return accountName;
}
return UserContext.current().getAccount().getAccountName();
}
public long getDomainId() {
if (domainId != null) {
return domainId;
}
return UserContext.current().getAccount().getDomainId();
}
public long getZoneId() {
return zoneId;
}
public Long getNetworkId() {
if (networkId != null) {
return networkId;
}
List<? extends Network> networks = _networkService.getVirtualNetworksOwnedByAccountInZone(getAccountName(), getDomainId(), getZoneId());
if (networks.size() == 0) {
return null;
}
assert (networks.size() <= 1) : "Too many virtual networks. This logic should be obsolete";
return networks.get(0).getId();
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
public static String getResultObjectName() {
return "addressinfo";
}
@Override
public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
boolean result = _networkService.restartNetwork(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to restart network");
}
}
}

View File

@ -23,10 +23,10 @@ import com.cloud.api.commands.AddVpnUserCmd;
import com.cloud.api.commands.AssociateIPAddrCmd;
import com.cloud.api.commands.CreateNetworkCmd;
import com.cloud.api.commands.CreateRemoteAccessVpnCmd;
import com.cloud.api.commands.DeleteNetworkCmd;
import com.cloud.api.commands.DeleteRemoteAccessVpnCmd;
import com.cloud.api.commands.DisassociateIPAddrCmd;
import com.cloud.api.commands.ListNetworksCmd;
import com.cloud.api.commands.RestartNetworkCmd;
import com.cloud.api.commands.RemoveVpnUserCmd;
import com.cloud.exception.AccountLimitException;
import com.cloud.exception.ConcurrentOperationException;
@ -86,5 +86,6 @@ public interface NetworkService {
Network createNetwork(CreateNetworkCmd cmd) throws InvalidParameterValueException, PermissionDeniedException;
List<? extends Network> searchForNetworks(ListNetworksCmd cmd) throws InvalidParameterValueException, PermissionDeniedException;
boolean deleteNetwork(long networkId) throws InvalidParameterValueException, PermissionDeniedException;
boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException;
}

View File

@ -68,23 +68,15 @@ public interface NetworkElement extends Adapter {
*/
boolean shutdown(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException;
/**
* Associate a new ip address to this network
* Apply ip addresses to this network
* @param network
* @param ipAddress
* @return
* @throws ResourceUnavailableException
*/
boolean associate(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException;
/**
* Disassociate the ip address from this network
* @param network
* @param ipAddress
* @return
* @throws ResourceUnavailableException
*/
boolean disassociate(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException;
boolean applyIps(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException;
/**
* Apply rules

View File

@ -102,6 +102,7 @@ listVlanIpRanges=com.cloud.api.commands.ListVlanIpRangesCmd;1
associateIpAddress=com.cloud.api.commands.AssociateIPAddrCmd;15
disassociateIpAddress=com.cloud.api.commands.DisassociateIPAddrCmd;15
listPublicIpAddresses=com.cloud.api.commands.ListPublicIpAddressesCmd;15
restartNetwork=com.cloud.api.commands.RestartNetworkCmd;15
#### firewall commands
listPortForwardingRules=com.cloud.api.commands.ListPortForwardingRulesCmd;15

View File

@ -127,6 +127,4 @@ public interface NetworkManager extends NetworkService {
boolean applyRules(Ip ip, List<? extends FirewallRule> rules, boolean continueOnError) throws ResourceUnavailableException;
Commands getAssociateIPCommands(DomainRouterVO router,
List<String> ipAddrList, boolean add, long vmId, Commands cmds);
}

View File

@ -49,6 +49,7 @@ import com.cloud.api.commands.CreateRemoteAccessVpnCmd;
import com.cloud.api.commands.DeleteRemoteAccessVpnCmd;
import com.cloud.api.commands.DisassociateIPAddrCmd;
import com.cloud.api.commands.ListNetworksCmd;
import com.cloud.api.commands.RestartNetworkCmd;
import com.cloud.api.commands.RemoveVpnUserCmd;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.configuration.Config;
@ -337,54 +338,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
}
@Override
public Commands getAssociateIPCommands(final DomainRouterVO router, final List<String> ipAddrList, final boolean add, long vmId, Commands cmds) {
boolean sourceNat = false;
Map<VlanVO, ArrayList<IPAddressVO>> vlanIpMap = new HashMap<VlanVO, ArrayList<IPAddressVO>>();
for (final String ipAddress: ipAddrList) {
IPAddressVO ip = _ipAddressDao.findById(ipAddress);
VlanVO vlan = _vlanDao.findById(ip.getVlanId());
ArrayList<IPAddressVO> ipList = vlanIpMap.get(vlan.getId());
if (ipList == null) {
ipList = new ArrayList<IPAddressVO>();
}
ipList.add(ip);
vlanIpMap.put(vlan, ipList);
}
for (Map.Entry<VlanVO, ArrayList<IPAddressVO>> vlanAndIp: vlanIpMap.entrySet()) {
boolean firstIP = true;
ArrayList<IPAddressVO> ipList = vlanAndIp.getValue();
Collections.sort(ipList, new Comparator<IPAddressVO>() {
@Override
public int compare(IPAddressVO o1, IPAddressVO o2) {
return o1.getAddress().compareTo(o2.getAddress());
} });
for (final IPAddressVO ip: ipList) {
sourceNat = ip.isSourceNat();
VlanVO vlan = vlanAndIp.getKey();
String vlanId = vlan.getVlanId();
String vlanGateway = vlan.getVlanGateway();
String vlanNetmask = vlan.getVlanNetmask();
String vifMacAddress = null;
if (firstIP && add) {
String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId());
vifMacAddress = macAddresses[1];
}
String vmGuestAddress = null;
if(vmId!=0){
vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress();
}
cmds.addCommand("IPAssocCommand", new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress));
firstIP = false;
}
}
return cmds;
}
@Override
public boolean associateIP(final DomainRouterVO router, final List<String> ipAddrList, final boolean add, long vmId) {
@ -501,7 +455,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
boolean success = true;
for (NetworkElement element : _networkElements) {
try {
element.associate(network, userIps);
element.applyIps(network, userIps);
} catch (ResourceUnavailableException e) {
success = false;
if (!continueOnError) {
@ -611,6 +565,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
txn.commit();
success = applyIpAssociations(network, false);
if (success) {
s_logger.debug("Successfully associated ip address " + ip + " for account " + owner.getId() + " in zone " + network.getDataCenterId());
} else {
s_logger.warn("Failed to associate ip address " + ip + " for account " + owner.getId() + " in zone " + network.getDataCenterId());
}
return ip;
} catch (ResourceUnavailableException e) {
@ -1179,7 +1138,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override
@DB
public boolean disassociateIpAddress(DisassociateIPAddrCmd cmd) throws PermissionDeniedException, IllegalArgumentException {
Transaction txn = Transaction.currentTxn();
Long userId = UserContext.current().getUserId();
Account account = UserContext.current().getAccount();
@ -1251,12 +1209,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
throw new PermissionDeniedException(ipAddress + " belongs to Account wide IP pool and cannot be disassociated");
}
txn.start();
boolean success = releasePublicIpAddress(ipAddress, accountId, userId);
if (success) {
_accountMgr.decrementResourceCount(accountId, ResourceType.public_ip);
}
txn.commit();
return success;
} catch (PermissionDeniedException pde) {
@ -1264,7 +1220,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
} catch (IllegalArgumentException iae) {
throw iae;
} catch (Throwable t) {
s_logger.error("Disassociate IP address threw an exception.");
s_logger.error("Disassociate IP address threw an exception.", t);
throw new IllegalArgumentException("Disassociate IP address threw an exception");
}
}
@ -2072,6 +2028,40 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
shutdownNetwork(networkId);
}
}
}
@Override
public boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException{
String accountName = cmd.getAccountName();
long domainId = cmd.getDomainId();
Account caller = UserContext.current().getAccount();
Account owner = _accountDao.findActiveAccount(accountName, domainId);
if (owner == null) {
throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied");
}
_accountMgr.checkAccess(caller, owner);
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);
}
}
//TODO - re-apply port forwarding and load balancing rules in the future
boolean success = applyIpAssociations(network, false);
if (!success) {
s_logger.warn("Failed to reapply the ip addresses for the account " + owner.getId() + " in zone " + network.getDataCenterId() + ", in network " + network.getId());
} else {
s_logger.debug("Ip addresses are reapplied successfully for the account " + owner.getId() + " in zone " + network.getDataCenterId() + ", in network " + network.getId());
}
return success;
}
}

View File

@ -115,10 +115,6 @@ public class DhcpElement extends AdapterBase implements NetworkElement {
}
return _routerMgr.stopRouter(router.getId(), 1);
}
protected DhcpElement() {
super();
}
@Override
public boolean applyRules(Network config, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
@ -126,12 +122,7 @@ public class DhcpElement extends AdapterBase implements NetworkElement {
}
@Override
public boolean associate(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException {
return true;
}
@Override
public boolean disassociate(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException {
return true;
public boolean applyIps(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException {
return true;
}
}

View File

@ -64,6 +64,7 @@ public class DomainRouterElement extends AdapterBase implements NetworkElement {
@Inject UserVmDao _userVmDao;
@Inject DomainRouterDao _routerDao;
private boolean canHandle(GuestIpType ipType, DeployDestination dest) {
DataCenter dc = dest.getDataCenter();
String provider = dc.getGatewayProvider();
@ -99,7 +100,6 @@ public class DomainRouterElement extends AdapterBase implements NetworkElement {
} else {
return false;
}
}
@Override
@ -115,25 +115,15 @@ public class DomainRouterElement extends AdapterBase implements NetworkElement {
}
return _routerMgr.stopRouter(router.getId(), 1);
}
protected DomainRouterElement() {
super();
}
@Override
public boolean applyRules(Network config, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
return false;
return true;
}
@Override
public boolean associate(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException {
// TODO Auto-generated method stub
return false;
public boolean applyIps(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException {
return _routerMgr.associateIP(network, ipAddress);
}
@Override
public boolean disassociate(Network network, List<? extends IpAddress> ipAddress) throws ResourceUnavailableException {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -20,6 +20,7 @@ package com.cloud.network.router;
import java.util.List;
import java.util.Map;
import com.cloud.agent.manager.Commands;
import com.cloud.api.commands.UpgradeRouterCmd;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
@ -31,6 +32,8 @@ import com.cloud.exception.InsufficientNetworkCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.IPAddressVO;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.RemoteAccessVpnVO;
import com.cloud.network.VpnUserVO;
@ -158,4 +161,6 @@ public interface DomainRouterManager extends Manager {
boolean deleteRemoteAccessVpn(RemoteAccessVpnVO vpnVO);
DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile<UserVm> vm, DeployDestination dest, ReservationContext context, Boolean startDhcp) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException;
boolean associateIP (Network network, List<? extends IpAddress> ipAddress);
}

View File

@ -2275,15 +2275,11 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
router.setPrivateMacAddress(nic.getMacAddress());
}
}
//source NAT address is stored in /proc/cmdline of the domR and gets
//source NAT address is stored in /proc/cmdline of the domR and gets
//reassigned upon powerup. Source NAT rule gets configured in StartRouter command
final List<IPAddressVO> ipAddrs = _networkMgr.listPublicIpAddressesInVirtualNetwork(router.getAccountId(), router.getDataCenterId(), null);
final List<String> ipAddrList = new ArrayList<String>();
for (final IPAddressVO ipVO : ipAddrs) {
ipAddrList.add(ipVO.getAddress());
}
if (!ipAddrList.isEmpty()) {
_networkMgr.getAssociateIPCommands(router, ipAddrList, true, 0, cmds);
if (!ipAddrs.isEmpty()) {
cmds = getAssociateIPCommands(router, ipAddrs, cmds, 0);
}
return true;
}
@ -2295,10 +2291,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
return false;
}
// FIXME: Need to check return values from ipassoc command
return true;
}
@ -2557,15 +2550,15 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
return router;
}
private void reconstructRouterPortForwardingRules(Commands cmds, List<? extends IpAddress> ipAddrs) {
List<? extends PortForwardingRule> rules = _rulesMgr.gatherPortForwardingRulesForApplication(ipAddrs);
if (rules.size() == 0) {
s_logger.debug("There are not port forwarding rules to send. ");
return;
}
SetPortForwardingRulesCommand pfrCmd = new SetPortForwardingRulesCommand(rules);
cmds.addCommand(pfrCmd);
}
// private void reconstructRouterPortForwardingRules(Commands cmds, List<? extends IpAddress> ipAddrs) {
// List<? extends PortForwardingRule> rules = _rulesMgr.gatherPortForwardingRulesForApplication(ipAddrs);
// if (rules.size() == 0) {
// s_logger.debug("There are not port forwarding rules to send. ");
// return;
// }
// SetPortForwardingRulesCommand pfrCmd = new SetPortForwardingRulesCommand(rules);
// cmds.addCommand(pfrCmd);
// }
/*
private List<? extends IpAddress> reconstructRouterIpAssocations(Commands cmds, VirtualRouter router) {
List<IPAddressVO> ipAddrs = _networkMgr.listPublicIpAddressesInVirtualNetwork(router.getAccountId(), router.getDataCenterId(), null);
@ -2573,81 +2566,6 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
}
*/
public boolean associateIP(final DomainRouterVO router, final List<String> ipAddrList, final boolean add, long vmId) {
Commands cmds = new Commands(OnError.Continue);
boolean sourceNat = false;
Map<VlanVO, ArrayList<IPAddressVO>> vlanIpMap = new HashMap<VlanVO, ArrayList<IPAddressVO>>();
for (final String ipAddress: ipAddrList) {
IPAddressVO ip = _ipAddressDao.findById(ipAddress);
VlanVO vlan = _vlanDao.findById(ip.getVlanId());
ArrayList<IPAddressVO> ipList = vlanIpMap.get(vlan.getId());
if (ipList == null) {
ipList = new ArrayList<IPAddressVO>();
}
ipList.add(ip);
vlanIpMap.put(vlan, ipList);
}
for (Map.Entry<VlanVO, ArrayList<IPAddressVO>> vlanAndIp: vlanIpMap.entrySet()) {
boolean firstIP = true;
ArrayList<IPAddressVO> ipList = vlanAndIp.getValue();
Collections.sort(ipList, new Comparator<IPAddressVO>() {
@Override
public int compare(IPAddressVO o1, IPAddressVO o2) {
return o1.getAddress().compareTo(o2.getAddress());
} });
for (final IPAddressVO ip: ipList) {
sourceNat = ip.isSourceNat();
VlanVO vlan = vlanAndIp.getKey();
String vlanId = vlan.getVlanId();
String vlanGateway = vlan.getVlanGateway();
String vlanNetmask = vlan.getVlanNetmask();
String vifMacAddress = null;
if (firstIP && add) {
String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId());
vifMacAddress = macAddresses[1];
}
String vmGuestAddress = null;
if(vmId!=0){
vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress();
}
cmds.addCommand(new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress));
firstIP = false;
}
}
Answer[] answers = null;
try {
answers = _agentMgr.send(router.getHostId(), cmds);
} catch (final AgentUnavailableException e) {
s_logger.warn("Agent unavailable", e);
return false;
} catch (final OperationTimedoutException e) {
s_logger.warn("Timed Out", e);
return false;
}
if (answers == null) {
return false;
}
if (answers.length != ipAddrList.size()) {
return false;
}
// FIXME: this used to be a loop for all answers, but then we always returned the
// first one in the array, so what should really be done here?
if (answers.length > 0) {
Answer ans = answers[0];
return ans.getResult();
}
return true;
}
/*
private boolean reconstructRouterState(Network config, DomainRouterVO router, Commands cmds) {
@ -2685,39 +2603,134 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
}
*/
private boolean resendDhcpEntries(Network config, DomainRouterVO router, Commands cmd){
final List<UserVmVO> vms = _vmDao.listBy(router.getId(), State.Creating, State.Starting, State.Running, State.Stopping, State.Stopped, State.Migrating);
Commands cmds = new Commands(OnError.Continue);
for (UserVmVO vm: vms) {
if (vm.getGuestIpAddress() == null || vm.getGuestMacAddress() == null || vm.getName() == null) {
continue;
}
DhcpEntryCommand decmd = new DhcpEntryCommand(vm.getGuestMacAddress(), vm.getGuestIpAddress(), router.getPrivateIpAddress(), vm.getName());
cmds.addCommand(decmd);
// private boolean resendDhcpEntries(Network config, DomainRouterVO router, Commands cmd){
// final List<UserVmVO> vms = _vmDao.listBy(router.getId(), State.Creating, State.Starting, State.Running, State.Stopping, State.Stopped, State.Migrating);
// Commands cmds = new Commands(OnError.Continue);
// for (UserVmVO vm: vms) {
// if (vm.getGuestIpAddress() == null || vm.getGuestMacAddress() == null || vm.getName() == null) {
// continue;
// }
// DhcpEntryCommand decmd = new DhcpEntryCommand(vm.getGuestMacAddress(), vm.getGuestIpAddress(), router.getPrivateIpAddress(), vm.getName());
// cmds.addCommand(decmd);
// }
// if (cmds.size() > 0) {
// try {
// _agentMgr.send(router.getHostId(), cmds);
// } catch (final AgentUnavailableException e) {
// s_logger.warn("agent unavailable", e);
// } catch (final OperationTimedoutException e) {
// s_logger.warn("Timed Out", e);
// }
// Answer[] answers = cmds.getAnswers();
// if (answers == null ){
// return false;
// }
// int i=0;
// while (i < cmds.size()) {
// Answer ans = answers[i];
// i++;
// if ((ans != null) && (ans.getResult())) {
// continue;
// } else {
// return false;
// }
// }
// }
// return true;
// }
private Commands getAssociateIPCommands(final DomainRouterVO router, final List<? extends IpAddress> ipAddrList, Commands cmds, long vmId) {
boolean sourceNat = false;
Map<VlanVO, ArrayList<IpAddress>> vlanIpMap = new HashMap<VlanVO, ArrayList<IpAddress>>();
for (final IpAddress ip: ipAddrList) {
VlanVO vlan = _vlanDao.findById(ip.getVlanId());
ArrayList<IpAddress> ipList = vlanIpMap.get(vlan);
if (ipList == null) {
ipList = new ArrayList<IpAddress>();
}
ipList.add(ip);
vlanIpMap.put(vlan, ipList);
}
for (Map.Entry<VlanVO, ArrayList<IpAddress>> vlanAndIp: vlanIpMap.entrySet()) {
boolean firstIP = true;
ArrayList<IpAddress> ipList = vlanAndIp.getValue();
Collections.sort(ipList, new Comparator<IpAddress>() {
@Override
public int compare(IpAddress o1, IpAddress o2) {
return o1.getAddress().compareTo(o2.getAddress());
} });
for (final IpAddress ip: ipList) {
boolean add = (ip.getState() == IpAddress.State.Releasing ? false : true);
sourceNat = ip.isSourceNat();
VlanVO vlan = vlanAndIp.getKey();
String vlanId = vlan.getVlanId();
String vlanGateway = vlan.getVlanGateway();
String vlanNetmask = vlan.getVlanNetmask();
String vifMacAddress = null;
if (firstIP && add) {
String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId());
vifMacAddress = macAddresses[1];
}
String vmGuestAddress = null;
if(vmId!=0){
vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress();
}
cmds.addCommand("IPAssocCommand", new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress));
firstIP = false;
}
}
return cmds;
}
private boolean sendAssociateIPCommands(final DomainRouterVO router, Commands cmds) {
Answer[] answers = null;
try {
answers = _agentMgr.send(router.getHostId(), cmds);
} catch (final OperationTimedoutException e) {
s_logger.warn("Timed Out", e);
throw new ResourceUnavailableException("Unable to assign ip addresses", e);
}
if (cmds.size() > 0) {
try {
_agentMgr.send(router.getHostId(), cmds);
} catch (final AgentUnavailableException e) {
s_logger.warn("agent unavailable", e);
} catch (final OperationTimedoutException e) {
s_logger.warn("Timed Out", e);
}
Answer[] answers = cmds.getAnswers();
if (answers == null ){
return false;
}
int i=0;
while (i < cmds.size()) {
Answer ans = answers[i];
i++;
if ((ans != null) && (ans.getResult())) {
continue;
} else {
return false;
}
}
if (answers == null) {
return false;
}
if (answers.length != cmds.size()) {
return false;
}
// FIXME: Have to return state for individual ipAssoc command in the future
if (answers.length > 0) {
Answer ans = answers[0];
return ans.getResult();
}
return true;
}
@Override
public boolean associateIP (Network network, List<? extends IpAddress> ipAddress) {
DomainRouterVO router = _routerDao.findByNetworkConfiguration(network.getId());
if (router == null) {
s_logger.warn("Unable to associate ip addresses, virtual router doesn't exist in the network " + network.getId());
throw new ResourceUnavailableException("Unable to assign ip addresses");
}
if (router.getState() == State.Running || router.getState() == State.Starting) {
Commands cmds = new Commands(OnError.Continue);
//We have to resend all already associated ip addresses
cmds = getAssociateIPCommands(router, ipAddress, cmds, 0);
return sendAssociateIPCommands(router, cmds);
} else if (router.getState() == State.Stopped || router.getState() == State.Stopping){
return true;
} else {
s_logger.warn("Unable to associate ip addresses, virtual router is not in the right state " + router.getState());
throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState());
}
}
}

View File

@ -115,8 +115,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster
@Inject private DomainRouterDao _routerDao;
@Inject private ConsoleProxyDao _consoleDao;
@Inject private SecondaryStorageVmDao _secondaryDao;
@Inject private NicDao _nicDao;
@Inject private NetworkDao _networkDao;
@Inject(adapter=DeploymentPlanner.class)
private Adapters<DeploymentPlanner> _planners;