mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Userdata to display static NAT as public ip instead of VR ip (#3862)
* Userdata to display static NAT as public ip instead of VR ip If static nat is enabled on VM then metadata service should return the static nat instead of gateway IP. If static not is not enabled then it should return the gateway IP as the public IP Test results: Step to reproduce: 1. Create a vm 2. Ssh to vm. 3. Run the below command inside the vm wget http://<VR public ip>/latest/meta-data/public-ipv4 Note down the output of the above command 4. Now acquire a new public and enable static NAT on that IP to this vm 5. Now run the same command mentioned above in the VM This should display the static NAT ip instead of VR public IP Output: Before enabling static nat wget http://10.10.10.40/latest/meta-data/public-ipv4 $ cat public-ipv4 10.10.10.29 After enabling static nat wget http://10.10.10.40/latest/meta-data/public-ipv4 $ cat public-ipv4 10.11.10.30 * server: apply vm user data when release a public ip Co-authored-by: Wei Zhou <ustcweizhou@gmail.com>
This commit is contained in:
parent
897224a319
commit
9c6b02fd8b
@ -188,9 +188,11 @@ public class CommandSetupHelper {
|
||||
public void createVmDataCommand(final VirtualRouter router, final UserVm vm, final NicVO nic, final String publicKey, final Commands cmds) {
|
||||
final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
|
||||
final String zoneName = _dcDao.findById(router.getDataCenterId()).getName();
|
||||
final IPAddressVO staticNatIp = _ipAddressDao.findByVmIdAndNetworkId(nic.getNetworkId(), vm.getId());
|
||||
cmds.addCommand(
|
||||
"vmdata",
|
||||
generateVmDataCommand(router, nic.getIPv4Address(), vm.getUserData(), serviceOffering, zoneName, nic.getIPv4Address(), vm.getHostName(), vm.getInstanceName(),
|
||||
generateVmDataCommand(router, nic.getIPv4Address(), vm.getUserData(), serviceOffering, zoneName,
|
||||
staticNatIp == null || staticNatIp.getState() != IpAddress.State.Allocated ? null : staticNatIp.getAddress().addr(), vm.getHostName(), vm.getInstanceName(),
|
||||
vm.getId(), vm.getUuid(), publicKey, nic.getNetworkId()));
|
||||
}
|
||||
|
||||
@ -1035,7 +1037,7 @@ public class CommandSetupHelper {
|
||||
}
|
||||
|
||||
private VmDataCommand generateVmDataCommand(final VirtualRouter router, final String vmPrivateIpAddress, final String userData, final String serviceOffering,
|
||||
final String zoneName, final String guestIpAddress, final String vmName, final String vmInstanceName, final long vmId, final String vmUuid, final String publicKey,
|
||||
final String zoneName, final String publicIpAddress, final String vmName, final String vmInstanceName, final long vmId, final String vmUuid, final String publicKey,
|
||||
final long guestNetworkId) {
|
||||
final VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkModel.getExecuteInSeqNtwkElmtCmd());
|
||||
|
||||
@ -1049,18 +1051,21 @@ public class CommandSetupHelper {
|
||||
cmd.addVmData("userdata", "user-data", userData);
|
||||
cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering));
|
||||
cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName));
|
||||
cmd.addVmData("metadata", "local-ipv4", guestIpAddress);
|
||||
cmd.addVmData("metadata", "local-ipv4", vmPrivateIpAddress);
|
||||
cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vmName));
|
||||
if (dcVo.getNetworkType() == NetworkType.Basic) {
|
||||
cmd.addVmData("metadata", "public-ipv4", guestIpAddress);
|
||||
|
||||
Network network = _networkDao.findById(guestNetworkId);
|
||||
if (dcVo.getNetworkType() == NetworkType.Basic || network.getGuestType() == Network.GuestType.Shared) {
|
||||
cmd.addVmData("metadata", "public-ipv4", vmPrivateIpAddress);
|
||||
cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vmName));
|
||||
} else {
|
||||
if (router.getPublicIpAddress() == null) {
|
||||
cmd.addVmData("metadata", "public-ipv4", guestIpAddress);
|
||||
} else {
|
||||
if (publicIpAddress != null) {
|
||||
cmd.addVmData("metadata", "public-ipv4", publicIpAddress);
|
||||
cmd.addVmData("metadata", "public-hostname", publicIpAddress);
|
||||
} else if (router.getPublicIpAddress() != null) {
|
||||
cmd.addVmData("metadata", "public-ipv4", router.getPublicIpAddress());
|
||||
cmd.addVmData("metadata", "public-hostname", router.getPublicIpAddress());
|
||||
}
|
||||
cmd.addVmData("metadata", "public-hostname", router.getPublicIpAddress());
|
||||
}
|
||||
if (vmUuid == null) {
|
||||
cmd.addVmData("metadata", "instance-id", vmInstanceName);
|
||||
|
||||
@ -24,6 +24,12 @@ import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.network.element.UserDataServiceProvider;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
@ -145,6 +151,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
LoadBalancerVMMapDao _loadBalancerVMMapDao;
|
||||
@Inject
|
||||
VpcService _vpcSvc;
|
||||
@Inject
|
||||
VMTemplateDao _templateDao;
|
||||
|
||||
protected void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller, Boolean ignoreVmState) {
|
||||
if (ipAddress == null || ipAddress.getAllocatedTime() == null || ipAddress.getAllocatedToAccountId() == null) {
|
||||
@ -597,6 +605,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
// 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)) {
|
||||
applyUserData(vmId, network, guestNic);
|
||||
performedIpAssoc = false; // ignor unassignIPFromVpcNetwork in finally block
|
||||
return true;
|
||||
} else {
|
||||
@ -620,6 +629,24 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void applyUserData(long vmId, Network network, Nic guestNic) throws ResourceUnavailableException {
|
||||
UserVmVO vm = _vmDao.findById(vmId);
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
|
||||
NicProfile nicProfile = new NicProfile(guestNic, network, null, null, null,
|
||||
_networkModel.isSecurityGroupSupportedInNetwork(network),
|
||||
_networkModel.getNetworkTag(template.getHypervisorType(), network));
|
||||
VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vm);
|
||||
UserDataServiceProvider element = _networkModel.getUserDataUpdateProvider(network);
|
||||
if (element == null) {
|
||||
s_logger.error("Can't find network element for " + Service.UserData.getName() + " provider needed for UserData update");
|
||||
} else {
|
||||
boolean result = element.saveUserData(network, nicProfile, vmProfile);
|
||||
if (!result) {
|
||||
s_logger.error("Failed to update userdata for vm " + vm + " and nic " + guestNic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, String vmIp, Account caller, long callerUserId) throws NetworkRuleConflictException,
|
||||
ResourceUnavailableException {
|
||||
if (ipAddress.isSourceNat()) {
|
||||
@ -1096,6 +1123,10 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
revokeStaticNatRuleInternal(rule.getId(), caller, userId, false);
|
||||
}
|
||||
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
|
||||
Long vmId = ipAddress.getAssociatedWithVmId();
|
||||
Long networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
|
||||
boolean success = true;
|
||||
|
||||
// revoke all port forwarding rules
|
||||
@ -1105,7 +1136,17 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
success = success && applyStaticNatRulesForIp(ipId, _ipAddrMgr.RulesContinueOnError.value(), caller, true);
|
||||
|
||||
// revoke static nat for the ip address
|
||||
success = success && applyStaticNatForIp(ipId, false, caller, true);
|
||||
if (vmId != null && networkId != null) {
|
||||
Network guestNetwork = _networkModel.getNetwork(networkId);
|
||||
Nic guestNic = _networkModel.getNicInNetwork(vmId, guestNetwork.getId());
|
||||
if (applyStaticNatForIp(ipId, false, caller, true)) {
|
||||
if (ipAddress.getState() == IpAddress.State.Releasing) {
|
||||
applyUserData(vmId, guestNetwork, guestNic);
|
||||
}
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we check again in case more rules have been inserted.
|
||||
rules.addAll(_portForwardingDao.listByIpAndNotRevoked(ipId));
|
||||
@ -1243,7 +1284,12 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
}
|
||||
}
|
||||
|
||||
return disableStaticNat(ipId, caller, ctx.getCallingUserId(), false);
|
||||
if (disableStaticNat(ipId, caller, ctx.getCallingUserId(), false)) {
|
||||
Nic guestNic = _networkModel.getNicInNetworkIncludingRemoved(vmId, guestNetwork.getId());
|
||||
applyUserData(vmId, guestNetwork, guestNic);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user