This is an automated email from the ASF dual-hosted git repository. pearl11594 pushed a commit to branch nsx-additional-fixes in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 059d20f573be9f28aa6163f6c844e71d971636df Author: Pearl Dsilva <pearl1...@gmail.com> AuthorDate: Mon Feb 26 10:25:43 2024 -0500 NSX: Fix DNS resolver for guest NSX networks (#23) * vpc: create vpc tiers with dns server of vpc instead of zone with this change ``` root@r-575-VM:~# cat /etc/dnsmasq.d/cloud.conf dhcp-hostsfile=/etc/dhcphosts.txt listen-address=127.0.0.1,172.17.1.1,172.17.2.1,172.17.3.1 dhcp-range=set:interface-eth2-0,172.17.1.1,static dhcp-option=tag:interface-eth2-0,15,cs2cloud.internal dhcp-option=tag:interface-eth2-0,6,172.17.1.1,10.0.32.1,8.8.8.8 dhcp-option=tag:interface-eth2-0,3,172.17.1.1 dhcp-option=eth2,26,1500 dhcp-option=tag:interface-eth2-0,1,255.255.255.0 dhcp-range=set:interface-eth3-1,172.17.2.1,static dhcp-option=tag:interface-eth3-1,15,cs2cloud.internal dhcp-option=tag:interface-eth3-1,6,172.17.2.1,8.8.8.8,1.1.1.1 dhcp-option=tag:interface-eth3-1,3,172.17.2.1 dhcp-option=eth3,26,1500 dhcp-option=tag:interface-eth3-1,1,255.255.255.0 dhcp-range=set:interface-eth4-2,172.17.3.1,static dhcp-option=tag:interface-eth4-2,15,cs2cloud.internal dhcp-option=tag:interface-eth4-2,6,172.17.3.1,8.8.8.8,1.1.1.1 dhcp-option=tag:interface-eth4-2,3,172.17.3.1 dhcp-option=eth4,26,1500 dhcp-option=tag:interface-eth4-2,1,255.255.255.0 root@r-575-VM:~# ``` * NSX: Fix DNS resolver for guest NSX networks * rename variable --------- Co-authored-by: Wei Zhou <weiz...@apache.org> --- .../cloud/agent/api/SetupGuestNetworkCommand.java | 9 +++ .../facade/SetGuestNetworkConfigItem.java | 1 + .../virtualnetwork/model/GuestNetwork.java | 9 +++ .../java/com/cloud/network/NetworkModelImpl.java | 16 +++++ .../cloud/network/router/CommandSetupHelper.java | 3 +- .../com/cloud/network/NetworkModelImplTest.java | 84 +++++++++++++++------- systemvm/debian/opt/cloud/bin/cs/CsGuestNetwork.py | 2 +- 7 files changed, 96 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java b/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java index e9781993239..06583f2d0d3 100644 --- a/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java +++ b/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java @@ -35,6 +35,7 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand { String routerIpv6 = null; String routerIpv6Gateway = null; String routerIpv6Cidr = null; + boolean isVrGuestGateway = false; public NicTO getNic() { return nic; @@ -114,4 +115,12 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand { public void setDefaultIp6Dns2(String defaultIp6Dns2) { this.defaultIp6Dns2 = defaultIp6Dns2; } + + public boolean isVrGuestGateway() { + return isVrGuestGateway; + } + + public void setVrGuestGateway(boolean vrGuestGateway) { + isVrGuestGateway = vrGuestGateway; + } } diff --git a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java index aee1e779571..1a6824ceb7f 100644 --- a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java +++ b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java @@ -75,6 +75,7 @@ public class SetGuestNetworkConfigItem extends AbstractConfigItemFacade { guestNetwork.setRouterIp6(command.getRouterIpv6()); guestNetwork.setRouterIp6Gateway(command.getRouterIpv6Gateway()); guestNetwork.setRouterIp6Cidr(command.getRouterIpv6Cidr()); + guestNetwork.setVrGuestGateway(command.isVrGuestGateway()); return generateConfigItems(guestNetwork); } diff --git a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java index bb5e443c2e8..a416b4bc5e4 100644 --- a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java +++ b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java @@ -37,6 +37,7 @@ public class GuestNetwork extends ConfigBase { private String routerIp6; private String routerIp6Gateway; private String routerIp6Cidr; + private boolean isVrGuestGateway; private Integer mtu; @@ -202,4 +203,12 @@ public class GuestNetwork extends ConfigBase { public Integer getMtu() { return mtu; } + + public boolean isVrGuestGateway() { + return isVrGuestGateway; + } + + public void setVrGuestGateway(boolean vrGuestGateway) { + isVrGuestGateway = vrGuestGateway; + } } diff --git a/server/src/main/java/com/cloud/network/NetworkModelImpl.java b/server/src/main/java/com/cloud/network/NetworkModelImpl.java index 407264e86aa..07e471c377f 100644 --- a/server/src/main/java/com/cloud/network/NetworkModelImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkModelImpl.java @@ -101,8 +101,10 @@ import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcGatewayVO; import com.cloud.network.vpc.dao.PrivateIpDao; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcGatewayDao; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Detail; @@ -178,6 +180,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi ProjectDao projectDao; @Inject NetworkPermissionDao _networkPermissionDao; + @Inject + VpcDao vpcDao; private List<NetworkElement> networkElements; @@ -2713,6 +2717,12 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi if (StringUtils.isNotBlank(network.getDns1())) { return new Pair<>(network.getDns1(), network.getDns2()); } + if (network.getVpcId() != null) { + Vpc vpc = vpcDao.findById(network.getVpcId()); + if (vpc != null && StringUtils.isNotBlank(vpc.getIp4Dns1())) { + return new Pair<>(vpc.getIp4Dns1(), vpc.getIp4Dns2()); + } + } return new Pair<>(zone.getDns1(), zone.getDns2()); } @@ -2721,6 +2731,12 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi if (StringUtils.isNotBlank(network.getIp6Dns1())) { return new Pair<>(network.getIp6Dns1(), network.getIp6Dns2()); } + if (network.getVpcId() != null) { + Vpc vpc = vpcDao.findById(network.getVpcId()); + if (vpc != null && StringUtils.isNotBlank(vpc.getIp6Dns1())) { + return new Pair<>(vpc.getIp6Dns1(), vpc.getIp6Dns2()); + } + } return new Pair<>(zone.getIp6Dns1(), zone.getIp6Dns2()); } 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 677707ea729..ce5024a5e1b 100644 --- a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java +++ b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java @@ -1160,7 +1160,7 @@ public class CommandSetupHelper { public SetupGuestNetworkCommand createSetupGuestNetworkCommand(final DomainRouterVO router, final boolean add, final NicProfile guestNic) { final Network network = _networkModel.getNetwork(guestNic.getNetworkId()); - + final NetworkOfferingVO networkOfferingVO = _networkOfferingDao.findById(network.getNetworkOfferingId()); String defaultDns1 = null; String defaultDns2 = null; String defaultIp6Dns1 = null; @@ -1197,6 +1197,7 @@ public class CommandSetupHelper { final SetupGuestNetworkCommand setupCmd = new SetupGuestNetworkCommand(dhcpRange, networkDomain, router.getIsRedundantRouter(), defaultDns1, defaultDns2, add, _itMgr.toNicTO(nicProfile, router.getHypervisorType())); + setupCmd.setVrGuestGateway(networkOfferingVO.isForNsx()); NicVO publicNic = _nicDao.findDefaultNicForVM(router.getId()); if (publicNic != null) { updateSetupGuestNetworkCommandIpv6(setupCmd, network, publicNic, defaultIp6Dns1, defaultIp6Dns2); diff --git a/server/src/test/java/com/cloud/network/NetworkModelImplTest.java b/server/src/test/java/com/cloud/network/NetworkModelImplTest.java index 0f15abcae77..41adb65fb80 100644 --- a/server/src/test/java/com/cloud/network/NetworkModelImplTest.java +++ b/server/src/test/java/com/cloud/network/NetworkModelImplTest.java @@ -28,13 +28,19 @@ import com.cloud.network.element.NetworkElement; import com.cloud.network.element.VpcVirtualRouterElement; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.utils.Pair; import com.cloud.utils.net.Ip; import org.junit.Assert; import org.junit.Before; import org.junit.Test; + import org.mockito.ArgumentMatchers; +import org.junit.runner.RunWith; import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; import org.mockito.Mockito; import org.springframework.test.util.ReflectionTestUtils; @@ -44,12 +50,17 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import org.mockito.junit.MockitoJUnitRunner; +@RunWith(MockitoJUnitRunner.class) public class NetworkModelImplTest { - final String[] ip4Dns1 = {"5.5.5.5", "6.6.6.6"}; - final String[] ip4Dns2 = {"7.7.7.7", "8.8.8.8"}; - final String[] ip6Dns1 = {"2001:4860:4860::5555", "2001:4860:4860::6666"}; - final String[] ip6Dns2 = {"2001:4860:4860::7777", "2001:4860:4860::8888"}; + final String[] ip4Dns1 = {"5.5.5.5", "6.6.6.6", "9.9.9.9"}; + final String[] ip4Dns2 = {"7.7.7.7", "8.8.8.8", "10.10.10.10"}; + final String[] ip6Dns1 = {"2001:4860:4860::5555", "2001:4860:4860::6666", "2001:4860:4860::9999"}; + final String[] ip6Dns2 = {"2001:4860:4860::7777", "2001:4860:4860::8888", "2001:4860:4860::AAAA"}; + + @Mock + private VpcDao vpcDao; @InjectMocks private NetworkModelImpl networkModel = new NetworkModelImpl(); @@ -63,18 +74,24 @@ public class NetworkModelImplTest { networkModel._networkOfferingDao = networkOfferingDao; networkModel._ntwkSrvcDao = networkServiceMapDao; } - private void prepareMocks(boolean isIp6, Network network, DataCenter zone, - String dns1, String dns2, String dns3, String dns4) { + + private void prepareMocks(boolean isIp6, Network network, DataCenter zone, VpcVO vpc, + String networkDns1, String zoneDns1, String networkDns2, String zoneDns2, + String vpcDns1, String vpcDns2) { if (isIp6) { - Mockito.when(network.getIp6Dns1()).thenReturn(dns1); - Mockito.when(zone.getIp6Dns1()).thenReturn(dns2); - Mockito.when(network.getIp6Dns2()).thenReturn(dns3); - Mockito.when(zone.getIp6Dns2()).thenReturn(dns4); + Mockito.when(network.getIp6Dns1()).thenReturn(networkDns1); + Mockito.when(zone.getIp6Dns1()).thenReturn(zoneDns1); + Mockito.when(network.getIp6Dns2()).thenReturn(networkDns2); + Mockito.when(zone.getIp6Dns2()).thenReturn(zoneDns2); + Mockito.when(vpc.getIp6Dns1()).thenReturn(vpcDns1); + Mockito.when(vpc.getIp6Dns2()).thenReturn(vpcDns2); } else { - Mockito.when(network.getDns1()).thenReturn(dns1); - Mockito.when(zone.getDns1()).thenReturn(dns2); - Mockito.when(network.getDns2()).thenReturn(dns3); - Mockito.when(zone.getDns2()).thenReturn(dns4); + Mockito.when(network.getDns1()).thenReturn(networkDns1); + Mockito.when(zone.getDns1()).thenReturn(zoneDns1); + Mockito.when(network.getDns2()).thenReturn(networkDns2); + Mockito.when(zone.getDns2()).thenReturn(zoneDns2); + Mockito.when(vpc.getIp4Dns1()).thenReturn(vpcDns1); + Mockito.when(vpc.getIp4Dns2()).thenReturn(vpcDns2); } } @@ -83,38 +100,53 @@ public class NetworkModelImplTest { String[] dns2 = isIp6 ? ip6Dns2 : ip4Dns2; Network network = Mockito.mock(Network.class); DataCenter zone = Mockito.mock(DataCenter.class); - // Both network and zone have valid dns - prepareMocks(isIp6, network, zone, dns1[0], dns1[1], dns2[0], dns1[1]); + VpcVO vpc = Mockito.mock(VpcVO.class); + Mockito.when(network.getVpcId()).thenReturn(1L); + Mockito.doReturn(vpc).when(vpcDao).findById(Matchers.anyLong()); + // network, vpc and zone have valid dns + prepareMocks(isIp6, network, zone, vpc, dns1[0], dns1[1], dns2[0], dns2[1], dns1[2], dns2[2]); Pair<String, String> result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) : networkModel.getNetworkIp4Dns(network, zone); Assert.assertEquals(dns1[0], result.first()); Assert.assertEquals(dns2[0], result.second()); - // Network has valid dns and zone don't - prepareMocks(isIp6, network, zone, dns1[0], null, dns2[0], null); + // Network has valid dns and vpc/zone don't + prepareMocks(isIp6, network, zone, vpc, dns1[0], null, dns2[0], null, null, null); result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) : networkModel.getNetworkIp4Dns(network, zone); Assert.assertEquals(dns1[0], result.first()); Assert.assertEquals(dns2[0], result.second()); - // Zone has a valid dns and network don't - prepareMocks(isIp6, network, zone, null, dns1[1], null, dns2[1]); + // Vpc has valid dns and network/zone don't + prepareMocks(isIp6, network, zone, vpc, null, null, null, null, dns1[2], dns2[2]); + result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) : + networkModel.getNetworkIp4Dns(network, zone); + Assert.assertEquals(dns1[2], result.first()); + Assert.assertEquals(dns2[2], result.second()); + // Zone has a valid dns and network/vpc don't + prepareMocks(isIp6, network, zone, vpc, null, dns1[1], null, dns2[1], null, null); result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) : networkModel.getNetworkIp4Dns(network, zone); Assert.assertEquals(dns1[1], result.first()); Assert.assertEquals(dns2[1], result.second()); - // Zone has a valid dns and network has only first dns - prepareMocks(isIp6, network, zone, dns1[0], dns1[1], null, dns2[1]); + // Zone/vpc has a valid dns and network has only first dns + prepareMocks(isIp6, network, zone, vpc, dns1[0], dns1[1], null, dns2[1], dns1[2], dns2[2]); result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) : networkModel.getNetworkIp4Dns(network, zone); Assert.assertEquals(dns1[0], result.first()); Assert.assertNull(result.second()); - // Both network and zone only have the first dns - prepareMocks(isIp6, network, zone, dns1[0], dns1[1], null, null); + // network don't have a valid dns, vpc has only first dns, Zone has a valid dns + prepareMocks(isIp6, network, zone, vpc, null, dns1[1], null, dns2[1], dns1[2], null); + result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) : + networkModel.getNetworkIp4Dns(network, zone); + Assert.assertEquals(dns1[2], result.first()); + Assert.assertNull(result.second()); + // network/vpc/zone only have the first dns + prepareMocks(isIp6, network, zone, vpc, dns1[0], dns1[1], null, null, dns1[2], null); result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) : networkModel.getNetworkIp4Dns(network, zone); Assert.assertEquals(dns1[0], result.first()); Assert.assertNull(result.second()); - // Both network and zone dns are null - prepareMocks(isIp6, network, zone, null, null, null, null); + // network/vpc and zone dns are null + prepareMocks(isIp6, network, zone, vpc, null, null, null, null, null, null); result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) : networkModel.getNetworkIp4Dns(network, zone); Assert.assertNull(result.first()); diff --git a/systemvm/debian/opt/cloud/bin/cs/CsGuestNetwork.py b/systemvm/debian/opt/cloud/bin/cs/CsGuestNetwork.py index a934862c224..41b8b644186 100755 --- a/systemvm/debian/opt/cloud/bin/cs/CsGuestNetwork.py +++ b/systemvm/debian/opt/cloud/bin/cs/CsGuestNetwork.py @@ -40,7 +40,7 @@ class CsGuestNetwork: return self.config.get_dns() dns = [] - if 'router_guest_gateway' in self.data and not self.config.use_extdns(): + if 'router_guest_gateway' in self.data and not self.config.use_extdns() and 'is_vr_guest_gateway' not in self.data: dns.append(self.data['router_guest_gateway']) if 'dns' in self.data: