|
91 | 91 | import com.cloud.utils.component.AdapterBase; |
92 | 92 | import com.cloud.utils.db.QueryBuilder; |
93 | 93 | import com.cloud.utils.db.SearchCriteria; |
| 94 | +import com.cloud.utils.db.Transaction; |
| 95 | +import com.cloud.utils.db.TransactionCallback; |
94 | 96 | import com.cloud.utils.exception.CloudRuntimeException; |
95 | 97 | import com.cloud.vm.NicProfile; |
96 | 98 | import com.cloud.vm.ReservationContext; |
97 | 99 | import com.cloud.vm.VMInstanceVO; |
98 | 100 | import com.cloud.vm.VirtualMachineProfile; |
99 | 101 | import com.cloud.vm.dao.VMInstanceDao; |
100 | 102 | import net.sf.ehcache.config.InvalidConfigurationException; |
| 103 | +import org.apache.cloudstack.NsxAnswer; |
101 | 104 | import org.apache.cloudstack.StartupNsxCommand; |
| 105 | +import org.apache.cloudstack.api.ApiConstants; |
102 | 106 | import org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd; |
103 | 107 | import org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd; |
104 | 108 | import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd; |
|
108 | 112 | import org.apache.cloudstack.resource.NsxOpObject; |
109 | 113 | import org.apache.logging.log4j.LogManager; |
110 | 114 | import org.apache.logging.log4j.Logger; |
| 115 | +import org.apache.cloudstack.resourcedetail.FirewallRuleDetailVO; |
| 116 | +import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; |
111 | 117 | import org.springframework.stereotype.Component; |
112 | 118 |
|
113 | 119 | import javax.inject.Inject; |
@@ -160,6 +166,8 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns |
160 | 166 | VirtualRouterProviderDao vrProviderDao; |
161 | 167 | @Inject |
162 | 168 | PhysicalNetworkServiceProviderDao pNtwkSvcProviderDao; |
| 169 | + @Inject |
| 170 | + FirewallRuleDetailsDao firewallRuleDetailsDao; |
163 | 171 |
|
164 | 172 | protected Logger logger = LogManager.getLogger(getClass()); |
165 | 173 |
|
@@ -527,45 +535,77 @@ public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) |
527 | 535 | return false; |
528 | 536 | } |
529 | 537 |
|
| 538 | + protected synchronized boolean applyPFRulesInternal(Network network, List<PortForwardingRule> rules) { |
| 539 | + return Transaction.execute((TransactionCallback<Boolean>) status -> { |
| 540 | + boolean result = true; |
| 541 | + for (PortForwardingRule rule : rules) { |
| 542 | + IPAddressVO publicIp = ApiDBUtils.findIpAddressById(rule.getSourceIpAddressId()); |
| 543 | + UserVm vm = ApiDBUtils.findUserVmById(rule.getVirtualMachineId()); |
| 544 | + if (vm == null && rule.getState() != FirewallRule.State.Revoke) { |
| 545 | + continue; |
| 546 | + } |
| 547 | + NsxOpObject nsxObject = getNsxOpObject(network); |
| 548 | + String publicPort = getPublicPortRange(rule); |
| 549 | + |
| 550 | + String privatePort = getPrivatePFPortRange(rule); |
| 551 | + |
| 552 | + NsxNetworkRule networkRule = new NsxNetworkRule.Builder() |
| 553 | + .setDomainId(nsxObject.getDomainId()) |
| 554 | + .setAccountId(nsxObject.getAccountId()) |
| 555 | + .setZoneId(nsxObject.getZoneId()) |
| 556 | + .setNetworkResourceId(nsxObject.getNetworkResourceId()) |
| 557 | + .setNetworkResourceName(nsxObject.getNetworkResourceName()) |
| 558 | + .setVpcResource(nsxObject.isVpcResource()) |
| 559 | + .setVmId(Objects.nonNull(vm) ? vm.getId() : 0) |
| 560 | + .setVmIp(Objects.nonNull(vm) ? vm.getPrivateIpAddress() : null) |
| 561 | + .setPublicIp(publicIp.getAddress().addr()) |
| 562 | + .setPrivatePort(privatePort) |
| 563 | + .setPublicPort(publicPort) |
| 564 | + .setRuleId(rule.getId()) |
| 565 | + .setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT)) |
| 566 | + .build(); |
| 567 | + FirewallRuleDetailVO ruleDetail = firewallRuleDetailsDao.findDetail(rule.getId(), ApiConstants.FOR_NSX); |
| 568 | + if (Arrays.asList(FirewallRule.State.Add, FirewallRule.State.Active).contains(rule.getState())) { |
| 569 | + if ((ruleDetail == null && FirewallRule.State.Add == rule.getState()) || (ruleDetail != null && !ruleDetail.getValue().equalsIgnoreCase("true"))) { |
| 570 | + LOGGER.debug(String.format("Creating port forwarding rule on NSX for VM %s to ports %s - %s", |
| 571 | + vm.getUuid(), rule.getDestinationPortStart(), rule.getDestinationPortEnd())); |
| 572 | + NsxAnswer answer = nsxService.createPortForwardRule(networkRule); |
| 573 | + boolean pfRuleResult = answer.getResult(); |
| 574 | + if (pfRuleResult && !answer.isObjectExistent()) { |
| 575 | + LOGGER.debug(String.format("Port forwarding rule %s created on NSX, adding detail on firewall rules details", rule.getId())); |
| 576 | + if (ruleDetail == null && FirewallRule.State.Add == rule.getState()) { |
| 577 | + LOGGER.debug(String.format("Adding new firewall detail for rule %s", rule.getId())); |
| 578 | + firewallRuleDetailsDao.addDetail(rule.getId(), ApiConstants.FOR_NSX, "true", false); |
| 579 | + } else { |
| 580 | + LOGGER.debug(String.format("Updating firewall detail for rule %s", rule.getId())); |
| 581 | + ruleDetail.setValue("true"); |
| 582 | + firewallRuleDetailsDao.update(ruleDetail.getId(), ruleDetail); |
| 583 | + } |
| 584 | + } |
| 585 | + result &= pfRuleResult; |
| 586 | + } |
| 587 | + } else if (rule.getState() == FirewallRule.State.Revoke) { |
| 588 | + if (ruleDetail != null && ruleDetail.getValue().equalsIgnoreCase("true")) { |
| 589 | + boolean pfRuleResult = nsxService.deletePortForwardRule(networkRule); |
| 590 | + if (pfRuleResult) { |
| 591 | + LOGGER.debug(String.format("Updating firewall rule detail %s for rule %s, set to false", ruleDetail.getId(), rule.getId())); |
| 592 | + ruleDetail.setValue("false"); |
| 593 | + firewallRuleDetailsDao.update(ruleDetail.getId(), ruleDetail); |
| 594 | + } |
| 595 | + result &= pfRuleResult; |
| 596 | + } |
| 597 | + } |
| 598 | + } |
| 599 | + return result; |
| 600 | + }); |
| 601 | + } |
| 602 | + |
530 | 603 | @Override |
531 | 604 | public boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException { |
532 | 605 | if (!canHandle(network, Network.Service.PortForwarding)) { |
533 | 606 | return false; |
534 | 607 | } |
535 | | - boolean result = true; |
536 | | - for (PortForwardingRule rule : rules) { |
537 | | - IPAddressVO publicIp = ApiDBUtils.findIpAddressById(rule.getSourceIpAddressId()); |
538 | | - UserVm vm = ApiDBUtils.findUserVmById(rule.getVirtualMachineId()); |
539 | | - if (vm == null && rule.getState() != FirewallRule.State.Revoke) { |
540 | | - continue; |
541 | | - } |
542 | | - NsxOpObject nsxObject = getNsxOpObject(network); |
543 | | - String publicPort = getPublicPortRange(rule); |
544 | | - |
545 | | - String privatePort = getPrivatePFPortRange(rule); |
546 | | - |
547 | | - NsxNetworkRule networkRule = new NsxNetworkRule.Builder() |
548 | | - .setDomainId(nsxObject.getDomainId()) |
549 | | - .setAccountId(nsxObject.getAccountId()) |
550 | | - .setZoneId(nsxObject.getZoneId()) |
551 | | - .setNetworkResourceId(nsxObject.getNetworkResourceId()) |
552 | | - .setNetworkResourceName(nsxObject.getNetworkResourceName()) |
553 | | - .setVpcResource(nsxObject.isVpcResource()) |
554 | | - .setVmId(Objects.nonNull(vm) ? vm.getId() : 0) |
555 | | - .setVmIp(Objects.nonNull(vm) ? vm.getPrivateIpAddress() : null) |
556 | | - .setPublicIp(publicIp.getAddress().addr()) |
557 | | - .setPrivatePort(privatePort) |
558 | | - .setPublicPort(publicPort) |
559 | | - .setRuleId(rule.getId()) |
560 | | - .setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT)) |
561 | | - .build(); |
562 | | - if (Arrays.asList(FirewallRule.State.Add, FirewallRule.State.Active).contains(rule.getState())) { |
563 | | - result &= nsxService.createPortForwardRule(networkRule); |
564 | | - } else if (rule.getState() == FirewallRule.State.Revoke) { |
565 | | - result &= nsxService.deletePortForwardRule(networkRule); |
566 | | - } |
567 | | - } |
568 | | - return result; |
| 608 | + return applyPFRulesInternal(network, rules); |
569 | 609 | } |
570 | 610 |
|
571 | 611 | public Pair<VpcVO, NetworkVO> getVpcOrNetwork(Long vpcId, long networkId) { |
|
0 commit comments