This is an automated email from the ASF dual-hosted git repository.
andrijapanic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/master by this push:
new 9c6b02f Userdata to display static NAT as public ip instead of VR ip
(#3862)
9c6b02f is described below
commit 9c6b02fd8b2282ceb80a1b9205871a4e93a00682
Author: Andrija Panic <[email protected]>
AuthorDate: Thu Mar 5 12:49:17 2020 +0100
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 <[email protected]>
---
.../cloud/network/router/CommandSetupHelper.java | 23 ++++++----
.../com/cloud/network/rules/RulesManagerImpl.java | 50 +++++++++++++++++++++-
2 files changed, 62 insertions(+), 11 deletions(-)
diff --git
a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
index 87a1662..63e9d80 100644
--- a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
+++ b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
@@ -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);
diff --git a/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
b/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
index aea24a4..de56774 100644
--- a/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
@@ -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