mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
VPC: CS-15569/CS-15568 - release ip address from VPC when fail to enable static nat
Conflicts: server/src/com/cloud/network/rules/RulesManagerImpl.java
This commit is contained in:
parent
ad80f426a0
commit
d48d4c24e7
@ -376,7 +376,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException {
|
@DB
|
||||||
|
public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm)
|
||||||
|
throws NetworkRuleConflictException, ResourceUnavailableException {
|
||||||
UserContext ctx = UserContext.current();
|
UserContext ctx = UserContext.current();
|
||||||
Account caller = ctx.getCaller();
|
Account caller = ctx.getCaller();
|
||||||
|
|
||||||
@ -386,84 +388,100 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||||||
if (ipAddress == null) {
|
if (ipAddress == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find ip address by id " + ipId);
|
throw new InvalidParameterValueException("Unable to find ip address by id " + ipId);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean setNetworkId = false;
|
// Verify input parameters
|
||||||
Network network = _networkMgr.getNetwork(networkId);
|
boolean performedIpAssoc = false;
|
||||||
if (network == null) {
|
boolean result = false;
|
||||||
throw new InvalidParameterValueException("Unable to find network by id");
|
try {
|
||||||
}
|
Network network = _networkMgr.getNetwork(networkId);
|
||||||
|
if (network == null) {
|
||||||
if (!isSystemVm) {
|
throw new InvalidParameterValueException("Unable to find network by id");
|
||||||
UserVmVO vm = _vmDao.findById(vmId);
|
|
||||||
if (vm == null) {
|
|
||||||
throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId +
|
|
||||||
", invalid virtual machine id specified (" + vmId + ").");
|
|
||||||
}
|
}
|
||||||
//associate ip address to network (if needed)
|
|
||||||
if (ipAddress.getAssociatedWithNetworkId() == null) {
|
// Check that vm has a nic in the network
|
||||||
boolean assignToVpcNtwk = network.getVpcId() != null
|
Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId);
|
||||||
&& ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
|
if (guestNic == null) {
|
||||||
if (assignToVpcNtwk) {
|
throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
|
||||||
_networkMgr.checkIpForService(ipAddress, Service.StaticNat, networkId);
|
}
|
||||||
|
|
||||||
s_logger.debug("The ip is not associated with the VPC network id="+ networkId + ", so assigning");
|
|
||||||
try {
|
if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
|
||||||
ipAddress = _networkMgr.associateIPToGuestNetwork(ipId, networkId);
|
throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " +
|
||||||
} catch (Exception ex) {
|
"supported in network with specified id");
|
||||||
s_logger.warn("Failed to associate ip id=" + ipId + " to VPC network id=" + networkId + " as " +
|
}
|
||||||
"a part of enable static nat");
|
|
||||||
return false;
|
if (!isSystemVm) {
|
||||||
|
UserVmVO vm = _vmDao.findById(vmId);
|
||||||
|
if (vm == null) {
|
||||||
|
throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId +
|
||||||
|
", invalid virtual machine id specified (" + vmId + ").");
|
||||||
|
}
|
||||||
|
//associate ip address to network (if needed)
|
||||||
|
if (ipAddress.getAssociatedWithNetworkId() == null) {
|
||||||
|
boolean assignToVpcNtwk = network.getVpcId() != null
|
||||||
|
&& ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
|
||||||
|
if (assignToVpcNtwk) {
|
||||||
|
_networkMgr.checkIpForService(ipAddress, Service.StaticNat, networkId);
|
||||||
|
|
||||||
|
s_logger.debug("The ip is not associated with the VPC network id="+ networkId + ", so assigning");
|
||||||
|
try {
|
||||||
|
ipAddress = _networkMgr.associateIPToGuestNetwork(ipId, networkId);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
s_logger.warn("Failed to associate ip id=" + ipId + " to VPC network id=" + networkId + " as " +
|
||||||
|
"a part of enable static nat");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
performedIpAssoc = true;
|
||||||
}
|
}
|
||||||
setNetworkId = true;
|
} else {
|
||||||
|
_networkMgr.checkIpForService(ipAddress, Service.StaticNat, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipAddress.getAssociatedWithNetworkId() == null) {
|
||||||
|
throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check permissions
|
||||||
|
checkIpAndUserVm(ipAddress, vm, caller);
|
||||||
|
|
||||||
|
// Verify ip address parameter
|
||||||
|
isIpReadyForStaticNat(vmId, ipAddress, caller, ctx.getCallerUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
ipAddress.setOneToOneNat(true);
|
||||||
|
ipAddress.setAssociatedWithVmId(vmId);
|
||||||
|
|
||||||
|
if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) {
|
||||||
|
// enable static nat on the backend
|
||||||
|
s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
|
||||||
|
if (applyStaticNatForIp(ipId, false, caller, false)) {
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_networkMgr.checkIpForService(ipAddress, Service.StaticNat, null);
|
s_logger.warn("Failed to update ip address " + ipAddress + " in the DB as a part of enableStaticNat");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
if (!result) {
|
||||||
if (ipAddress.getAssociatedWithNetworkId() == null) {
|
Transaction txn = Transaction.currentTxn();
|
||||||
throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
|
txn.start();
|
||||||
}
|
|
||||||
|
|
||||||
// Check permissions
|
|
||||||
checkIpAndUserVm(ipAddress, vm, caller);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that vm has a nic in the network
|
|
||||||
Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId);
|
|
||||||
if (guestNic == null) {
|
|
||||||
throw new InvalidParameterValueException("Vm doesn't belong to the network " + networkId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
|
|
||||||
throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " +
|
|
||||||
"supported in network id=" + networkId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify ip address parameter
|
|
||||||
isIpReadyForStaticNat(vmId, ipAddress, caller, ctx.getCallerUserId());
|
|
||||||
ipAddress.setOneToOneNat(true);
|
|
||||||
ipAddress.setAssociatedWithVmId(vmId);
|
|
||||||
|
|
||||||
if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) {
|
|
||||||
// enable static nat on the backend
|
|
||||||
s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
|
|
||||||
if (applyStaticNatForIp(ipId, false, caller, false)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
ipAddress.setOneToOneNat(false);
|
ipAddress.setOneToOneNat(false);
|
||||||
ipAddress.setAssociatedWithVmId(null);
|
ipAddress.setAssociatedWithVmId(null);
|
||||||
if (setNetworkId) {
|
|
||||||
ipAddress.setAssociatedWithNetworkId(null);
|
|
||||||
}
|
|
||||||
_ipAddressDao.update(ipAddress.getId(), ipAddress);
|
_ipAddressDao.update(ipAddress.getId(), ipAddress);
|
||||||
s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
|
if (performedIpAssoc) {
|
||||||
return false;
|
//if the rule is the last one for the ip address assigned to VPC, unassign it from the network
|
||||||
|
IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
|
||||||
|
if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) {
|
||||||
|
s_logger.debug("Releasing VPC ip address " + ip + " as PF rule failed to create");
|
||||||
|
_networkMgr.unassignIPFromVpcNetwork(ip.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
txn.commit();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
s_logger.warn("Failed to update ip address " + ipAddress + " in the DB as a part of enableStaticNat");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId)
|
protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user