Uh oh!
There was an error while loading. Please reload this page.
fix: NsxResource.executeRequest DeleteNsxNatRuleCommand comparison bug - #12833
Conversation
Congratulations on your first Pull Request and welcome to the Apache CloudStack community! If you have any issues or are unsure about any anything please check our Contribution Guide (https://github.com/apache/cloudstack/blob/main/CONTRIBUTING.md)
|
DaanHoogland
commented
Mar 17, 2026
@blueorangutan package |
blueorangutan
commented
Mar 17, 2026
@DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@## main #12833 +/- ##
=========================================
Coverage 18.02% 18.02% - Complexity 16450 16452 +2
=========================================
Files 5968 5968 Lines 537086 537091 +5 Branches 65961 65961 =========================================
+ Hits 96820 96825 +5 + Misses 429346 429344 -2 - Partials 10920 10922 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Fixes NSX NAT rule deletion behavior when DeleteNsxNatRuleCommand is executed in a different process (where Network.Service may be deserialized into a non-singleton instance), by switching comparisons to use the service name rather than object identity.
Changes:
- Update
NsxResource.executeRequest(DeleteNsxNatRuleCommand)to compareNetwork.ServiceviagetName()(through a newgetNetworkServiceName()accessor). - Add/update a unit test to exercise deletion using a non-static
Network.Serviceinstance and verify thedeleteNatRule(...)call parameters. - Fix an incorrect log message in load balancer rule deletion error handling (“add” → “delete”).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java | Uses service-name equality for NAT ruleName selection; fixes LB delete log message. |
plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxNatRuleCommand.java | Adds getNetworkServiceName() helper to safely fetch the service name. |
plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java | Extends NAT delete test to set a non-static service and verify NSX client invocation. |
Comments suppressed due to low confidence (2)
plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java:429
executeRequest(DeleteNsxNatRuleCommand)now correctly uses the service name for ruleName selection, but it still passescmd.getService()intonsxApiClient.deleteNatRule(...). Downstream,NsxApiClient.deleteNatRuleuses identity comparison (service == Network.Service.PortForwarding) to decide whether to delete the port-forwarding service object, so a deserializedNetwork.Serviceinstance will still skip that cleanup. Consider canonicalizing the service before calling the API (e.g., resolve viaNetwork.Service.getService(cmd.getNetworkServiceName())and pass that), or update the API to useservice.getName()/serviceName instead of identity checks.
if (Network.Service.StaticNat.getName().equals(cmd.getNetworkServiceName())) {
ruleName = NsxControllerUtils.getStaticNatRuleName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
} else if (Network.Service.PortForwarding.getName().equals(cmd.getNetworkServiceName())) {
ruleName = NsxControllerUtils.getPortForwardRuleName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.getRuleId(), cmd.isResourceVpc());
}
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
try {
nsxApiClient.deleteNatRule(cmd.getService(), cmd.getPrivatePort(), cmd.getProtocol(),
cmd.getNetworkResourceName(), tier1GatewayName, ruleName);
plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java:430
- If
cmd.getNetworkServiceName()is null or not one of the handled values,ruleNamestays null but the code still callsnsxApiClient.deleteNatRule(...)with a nullruleName, which can lead to confusing errors or NPEs inside the NSX client. Please add explicit validation/handling (e.g., return a failedNsxAnswerwith a clear message) when the service is unsupported or ruleName cannot be derived.
private NsxAnswer executeRequest(DeleteNsxNatRuleCommand cmd) {
String ruleName = null;
if (Network.Service.StaticNat.getName().equals(cmd.getNetworkServiceName())) {
ruleName = NsxControllerUtils.getStaticNatRuleName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
} else if (Network.Service.PortForwarding.getName().equals(cmd.getNetworkServiceName())) {
ruleName = NsxControllerUtils.getPortForwardRuleName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.getRuleId(), cmd.isResourceVpc());
}
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
try {
nsxApiClient.deleteNatRule(cmd.getService(), cmd.getPrivatePort(), cmd.getProtocol(),
cmd.getNetworkResourceName(), tier1GatewayName, ruleName);
} catch (Exception e) {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Uh oh!
There was an error while loading. Please reload this page.
Fixes an issue in NsxResource.executeRequest where Network.Service comparison failed when DeleteNsxNatRuleCommand was executed in a different process. Due to serialization/deserialization, the deserialized Network.Service instance was not equal to the static instances Network.Service.StaticNat and Network.Service.PortForwarding, causing the comparison to always return false.
6bff177 to
f300f5aCompareblueorangutan
commented
Mar 17, 2026
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 17171 |
blueorangutan
commented
Mar 17, 2026
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 17172 |
DaanHoogland
commented
Mar 19, 2026
@blueorangutan test |
blueorangutan
commented
Mar 19, 2026
@DaanHoogland a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
blueorangutan
commented
Mar 20, 2026
[SF] Trillian test result (tid-15696)
|
Hi |
blueorangutan
commented
Mar 30, 2026
[SF] Trillian test result (tid-15756)
|
DaanHoogland
commented
Mar 30, 2026
looking at the code it makes sense to conclude the failures have nothing to do with this PR. only nsx plugin is touched. @weizhouapache@winterhazel , up to you guys |
ZhyliaievD
commented
Apr 6, 2026
@weizhouapache@winterhazel a kind reminder about this PR 😅 |
There was a problem hiding this comment.
@ZhyliaievD sorry for the delay. This one seems a safe change and the test failures unrelated, so I'm merging it already.
Uh oh!
There was an error while loading. Please reload this page.
Awesome work, congrats on your first merged pull request! |
weizhouapache
commented
Apr 15, 2026
do we need to cherry-pick the commit from main to 4.22 branch ? cc @DaanHoogland@sureshanaparti@rajujith@nvazquez@Pearl1594 @@ZhyliaievD |
yeah, I think so |
winterhazel
commented
Apr 15, 2026
@weizhouapache yes, it would be nice to cherry-pick it to 4.22, as the other NSX patches are being re-targeted too. |
#12833) Fixes an issue in NsxResource.executeRequest where Network.Service comparison failed when DeleteNsxNatRuleCommand was executed in a different process. Due to serialization/deserialization, the deserialized Network.Service instance was not equal to the static instances Network.Service.StaticNat and Network.Service.PortForwarding, causing the comparison to always return false. Co-authored-by: Andrey Volchkov <avolchkov@playtika.com> (cherry picked from commit 30dd234)
Source local main commit: - b078081e41 nsx: compare NAT delete service by name Source Apache commits: - 30dd234 fix: NsxResource.executeRequest DeleteNsxNatRuleCommand comparison bug (apache#12833) Change summary: - add getNetworkServiceName() to DeleteNsxNatRuleCommand - compare NSX NAT delete service selection by service name instead of object identity - add a focused test for the Port Forwarding delete path - record Record 043 sync notes and mark e10c066 as already satisfied in the history document Functional impact: - prevents NSX NAT rule deletion from missing the correct branch when the command carries an equivalent service object rather than the same enum instance - improves reliability of Port Forwarding and Static NAT rule cleanup in NSX-backed networks Validation: - cherry-pick from main applied cleanly on ablestack-europa with no additional manual conflict resolution - mvn/mvnw-based tests not run in this environment by request
Description
PR Fixes an issue in NsxResource.executeRequest where Network.Service comparison failed when DeleteNsxNatRuleCommand was executed in a different process. Due to serialization/deserialization, the deserialized Network.Service instance was not equal to the static instances Network.Service.StaticNat and Network.Service.PortForwarding, causing the comparison to always return false.
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity