mirror of https://github.com/apache/cloudstack.git
Phase4 - Add support for Source NAT, Static NAT and Port Forwarding (#19)
* Run moodifyvxlan script if broadcast domain type is Netris * Add Netris NAT offerings * Add support to add Source nat rules for Natted offering * fix api params while creating Netris source NAT rule * Add support to add and delete source nat rule on netris * Add support to create /32 NAT subnet * Add support to add and delete Static NAT rules in Netris (#23) * Add support to add and delete Static NAT rules in Netris * fix static nat creation on netris & removal of subnet on deletion of static nat rule * remove nat subnet after deltion of the static nat rule * add check to see if subnet already exists and add license header * Add port forwarding rules as DNAT rules in Netris (#24) * Add port forwarding rules as DNAT rules in Netris * Fixes * Allow removing DNAT rules * Fixes * Fix subnet search * Fix update SNAT only for SNAT rules * Address comments * Fix * Fix netris pom xml * Fix SNAT rule creation * Fix IP and port placements (#27) * Fix IP and port placements * fix dnat to IP for PF rules * change dnatport --------- Co-authored-by: Nicolas Vazquez <nicovazquez90@gmail.com>
This commit is contained in:
parent
b70f72abec
commit
ce9cbb2ff8
|
|
@ -0,0 +1,204 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.network;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SDNProviderNetworkRule {
|
||||
|
||||
private long domainId;
|
||||
private long accountId;
|
||||
private long zoneId;
|
||||
private Long networkResourceId;
|
||||
private String networkResourceName;
|
||||
private boolean isVpcResource;
|
||||
private long vmId;
|
||||
private long ruleId;
|
||||
private String publicIp;
|
||||
private String vmIp;
|
||||
private String publicPort;
|
||||
private String privatePort;
|
||||
private String protocol;
|
||||
private String algorithm;
|
||||
private List<String> sourceCidrList;
|
||||
private List<String> destinationCidrList;
|
||||
private Integer icmpCode;
|
||||
|
||||
private Integer icmpType;
|
||||
private String trafficType;
|
||||
private Network.Service service;
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setDomainId(long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(long zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public Long getNetworkResourceId() {
|
||||
return networkResourceId;
|
||||
}
|
||||
|
||||
public void setNetworkResourceId(Long networkResourceId) {
|
||||
this.networkResourceId = networkResourceId;
|
||||
}
|
||||
|
||||
public String getNetworkResourceName() {
|
||||
return networkResourceName;
|
||||
}
|
||||
|
||||
public void setNetworkResourceName(String networkResourceName) {
|
||||
this.networkResourceName = networkResourceName;
|
||||
}
|
||||
|
||||
public boolean isVpcResource() {
|
||||
return isVpcResource;
|
||||
}
|
||||
|
||||
public void setVpcResource(boolean vpcResource) {
|
||||
isVpcResource = vpcResource;
|
||||
}
|
||||
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
public long getRuleId() {
|
||||
return ruleId;
|
||||
}
|
||||
|
||||
public void setRuleId(long ruleId) {
|
||||
this.ruleId = ruleId;
|
||||
}
|
||||
|
||||
public String getPublicIp() {
|
||||
return publicIp;
|
||||
}
|
||||
|
||||
public void setPublicIp(String publicIp) {
|
||||
this.publicIp = publicIp;
|
||||
}
|
||||
|
||||
public String getVmIp() {
|
||||
return vmIp;
|
||||
}
|
||||
|
||||
public void setVmIp(String vmIp) {
|
||||
this.vmIp = vmIp;
|
||||
}
|
||||
|
||||
public String getPublicPort() {
|
||||
return publicPort;
|
||||
}
|
||||
|
||||
public void setPublicPort(String publicPort) {
|
||||
this.publicPort = publicPort;
|
||||
}
|
||||
|
||||
public String getPrivatePort() {
|
||||
return privatePort;
|
||||
}
|
||||
|
||||
public void setPrivatePort(String privatePort) {
|
||||
this.privatePort = privatePort;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void setAlgorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public Network.Service getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public void setService(Network.Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public Integer getIcmpCode() {
|
||||
return icmpCode;
|
||||
}
|
||||
|
||||
public void setIcmpCode(Integer icmpCode) {
|
||||
this.icmpCode = icmpCode;
|
||||
}
|
||||
|
||||
public Integer getIcmpType() {
|
||||
return icmpType;
|
||||
}
|
||||
|
||||
public void setIcmpType(Integer icmpType) {
|
||||
this.icmpType = icmpType;
|
||||
}
|
||||
|
||||
public List<String> getSourceCidrList() {
|
||||
return sourceCidrList;
|
||||
}
|
||||
|
||||
public void setSourceCidrList(List<String> sourceCidrList) {
|
||||
this.sourceCidrList = sourceCidrList;
|
||||
}
|
||||
|
||||
public List<String> getDestinationCidrList() {
|
||||
return destinationCidrList;
|
||||
}
|
||||
|
||||
public void setDestinationCidrList(List<String> destinationCidrList) {
|
||||
this.destinationCidrList = destinationCidrList;
|
||||
}
|
||||
|
||||
public String getTrafficType() {
|
||||
return trafficType;
|
||||
}
|
||||
|
||||
public void setTrafficType(String trafficType) {
|
||||
this.trafficType = trafficType;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,12 +17,40 @@
|
|||
package com.cloud.network.element;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.PortForwardingRule;
|
||||
import com.cloud.network.vpc.NetworkACLItem;
|
||||
|
||||
public interface PortForwardingServiceProvider extends NetworkElement, IpDeployingRequester {
|
||||
|
||||
static String getPublicPortRange(PortForwardingRule rule) {
|
||||
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
|
||||
String.valueOf(rule.getSourcePortStart()) :
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
static String getPrivatePFPortRange(PortForwardingRule rule) {
|
||||
return rule.getDestinationPortStart() == rule.getDestinationPortEnd() ?
|
||||
String.valueOf(rule.getDestinationPortStart()) :
|
||||
String.valueOf(rule.getDestinationPortStart()).concat("-").concat(String.valueOf(rule.getDestinationPortEnd()));
|
||||
}
|
||||
|
||||
static String getPrivatePortRange(FirewallRule rule) {
|
||||
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
|
||||
String.valueOf(rule.getSourcePortStart()) :
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
static String getPrivatePortRangeForACLRule(NetworkACLItem rule) {
|
||||
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
|
||||
String.valueOf(rule.getSourcePortStart()) :
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply rules
|
||||
* @param network
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.network.netris;
|
||||
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.SDNProviderNetworkRule;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
|
||||
public interface NetrisService {
|
||||
|
|
@ -23,4 +25,10 @@ public interface NetrisService {
|
|||
boolean deleteVpcResource(long zoneId, long accountId, long domainId, Vpc vpc);
|
||||
boolean createVnetResource(Long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr);
|
||||
boolean deleteVnetResource(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr);
|
||||
boolean createSnatRule(long zoneId, long accountId, long domainId, String vpcName, long vpcId, String networkName, long networkId, boolean isForVpc, String vpcCidr, String sourceNatIp);
|
||||
boolean createPortForwardingRule(long zoneId, long accountId, long domainId, String vpcName, long vpcId, String networkName, Long networkId, boolean isForVpc, String vpcCidr, SDNProviderNetworkRule networkRule);
|
||||
boolean deletePortForwardingRule(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, boolean isForVpc, String vpcCidr, SDNProviderNetworkRule networkRule);
|
||||
boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address);
|
||||
boolean createStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String vpcCidr, String staticNatIp, String vmIp);
|
||||
boolean deleteStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String staticNatIp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ public interface VpcOffering extends InternalIdentity, Identity {
|
|||
public static final String DEFAULT_VPC_NAT_NSX_OFFERING_NAME = "VPC offering with NSX - NAT Mode";
|
||||
public static final String DEFAULT_VPC_ROUTE_NSX_OFFERING_NAME = "VPC offering with NSX - Route Mode";
|
||||
public static final String DEFAULT_VPC_ROUTE_NETRIS_OFFERING_NAME = "VPC offering with Netris - Route Mode";
|
||||
public static final String DEFAULT_VPC_NAT_NETRIS_OFFERING_NAME = "VPC offering with Netris - NAT Mode";
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
|
|||
public static final String DEFAULT_NAT_NSX_OFFERING_FOR_VPC_WITH_ILB = "DefaultNATNSXNetworkOfferingForVpcWithInternalLB";
|
||||
public static final String DEFAULT_ROUTED_NSX_OFFERING_FOR_VPC = "DefaultRoutedNSXNetworkOfferingForVpc";
|
||||
public static final String DEFAULT_ROUTED_NETRIS_OFFERING_FOR_VPC = "DefaultRoutedNetrisNetworkOfferingForVpc";
|
||||
public static final String DEFAULT_NAT_NETRIS_OFFERING_FOR_VPC = "DefaultNATNetrisNetworkOfferingForVpc";
|
||||
public static final String DEFAULT_NAT_NSX_OFFERING = "DefaultNATNSXNetworkOffering";
|
||||
public static final String DEFAULT_ROUTED_NSX_OFFERING = "DefaultRoutedNSXNetworkOffering";
|
||||
public final static String QuickCloudNoServices = "QuickCloudNoServices";
|
||||
|
|
|
|||
|
|
@ -561,27 +561,27 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true,
|
||||
Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true, Network.GuestType.Shared, false, null, true, null, true,
|
||||
false, null, false, null, true, false, false, false, null, null, null, true, null, null, false);
|
||||
false, null, false, null, true, false, false, false, false,null, null, null, true, null, null, false);
|
||||
}
|
||||
|
||||
//#2 - SG enabled network offering
|
||||
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks",
|
||||
TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true,
|
||||
null, true, false, null, false, null, true, false, false, false, null, null, null, true, null, null, false);
|
||||
null, true, false, null, false, null, true, false, false, false, false,null, null, null, true, null, null, false);
|
||||
}
|
||||
|
||||
//#3 - shared network offering with no SG service
|
||||
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) {
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true,
|
||||
Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false,
|
||||
null, true, false, false, false, null,null, null, true, null, null, false);
|
||||
null, true, false, false, false, false,null,null, null, true, null, null, false);
|
||||
}
|
||||
|
||||
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE) == null) {
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE, "Offering for Tungsten Shared Security group enabled networks",
|
||||
TrafficType.Guest, null, true, Availability.Optional, null, defaultTungstenSharedSGEnabledNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true,
|
||||
null, true, false, null, false, null, true, false, true, false, null, null,null, true, null, null, false);
|
||||
null, true, false, null, false, null, true, false, true, false, false,null, null,null, true, null, null, false);
|
||||
offering.setState(NetworkOffering.State.Enabled);
|
||||
_networkOfferingDao.update(offering.getId(), offering);
|
||||
}
|
||||
|
|
@ -591,14 +591,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
|
||||
"Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null,
|
||||
defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null,
|
||||
true, false, false, false, null, null,null, true, null, null, false);
|
||||
true, false, false, false, false,null, null,null, true, null, null, false);
|
||||
}
|
||||
|
||||
//#5 - default vpc offering with LB service
|
||||
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) {
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
|
||||
"Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null,
|
||||
defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null,true, null, null, false);
|
||||
defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, false,null, null, null,true, null, null, false);
|
||||
}
|
||||
|
||||
//#6 - default vpc offering with no LB service
|
||||
|
|
@ -607,14 +607,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
defaultVPCOffProviders.remove(Service.Lb);
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
|
||||
"Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional,
|
||||
null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null,true, null, null, false);
|
||||
null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, false,null, null, null,true, null, null, false);
|
||||
}
|
||||
|
||||
//#7 - isolated offering with source nat disabled
|
||||
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) {
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service",
|
||||
TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null,
|
||||
true, null, true, false, null, false, null, true, false, false, false, null, null, null, true, null, null, false);
|
||||
true, null, true, false, null, false, null, true, false, false, false, false,null, null, null, true, null, null, false);
|
||||
}
|
||||
|
||||
//#8 - network offering with internal lb service
|
||||
|
|
@ -636,7 +636,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) {
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB,
|
||||
"Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, null, false, Availability.Optional, null, internalLbOffProviders,
|
||||
true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null, true, null, null, false);
|
||||
true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, false,null, null, null, true, null, null, false);
|
||||
offering.setInternalLb(true);
|
||||
offering.setPublicLb(false);
|
||||
_networkOfferingDao.update(offering.getId(), offering);
|
||||
|
|
@ -667,7 +667,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) {
|
||||
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
|
||||
"Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, Availability.Optional, null,
|
||||
netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, false, false, null, null, null, true, null, null, false);
|
||||
netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, false, false,false, null, null, null, true, null, null, false);
|
||||
offering.setDedicatedLB(false);
|
||||
_networkOfferingDao.update(offering.getId(), offering);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
|
|||
ConfigurationManager configMgr = (ConfigurationManager) _configService;
|
||||
NetworkOfferingVO voffer = configMgr.createNetworkOffering(offeringName, offeringDisplayText,
|
||||
TrafficType.Public, null, true, Availability.Optional, null, serviceProviderMap, true,
|
||||
Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, false, false, null, null, null, true, null, null, false);
|
||||
Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, false, false, false,null, null, null, true, null, null, false);
|
||||
long id = voffer.getId();
|
||||
_networkOfferingDao.update(id, voffer);
|
||||
return _networkOfferingDao.findById(id);
|
||||
|
|
@ -252,7 +252,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
|
|||
ConfigurationManager configMgr = (ConfigurationManager)_configService;
|
||||
NetworkOfferingVO voffer =
|
||||
configMgr.createNetworkOffering(offeringName, offeringDisplayText, TrafficType.Guest, null, false, Availability.Optional, null, serviceProviderMap, true,
|
||||
Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), false, false, null, null, null, true, null, null, false);
|
||||
Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), false, false, false,null, null, null, true, null, null, false);
|
||||
if (offeringName.equals(vpcRouterOfferingName)) {
|
||||
voffer.setInternalLb(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
<parent>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloudstack-plugins</artifactId>
|
||||
<version>4.20.0.0-SNAPSHOT</version>
|
||||
<version>4.20.0.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<dependencies>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.agent.api;
|
||||
|
||||
public class CreateOrUpdateNetrisNatCommand extends NetrisCommand {
|
||||
private String vpcName;
|
||||
private Long vpcId;
|
||||
private String vpcCidr;
|
||||
private String natRuleName;
|
||||
private String natIp;
|
||||
private String natRuleType;
|
||||
|
||||
// Parameters for DNAT
|
||||
private String protocol;
|
||||
private String sourceAddress;
|
||||
private String sourcePort;
|
||||
private String destinationAddress;
|
||||
private String destinationPort;
|
||||
private String state;
|
||||
|
||||
// Parameters for SNAT (Static NAT)
|
||||
private String vmIp;
|
||||
|
||||
|
||||
public CreateOrUpdateNetrisNatCommand(long zoneId, Long accountId, Long domainId, String vpcName, Long vpcId, String vNetName, Long networkId, boolean isVpc, String vpcCidr) {
|
||||
super(zoneId, accountId, domainId, vNetName, networkId, isVpc);
|
||||
this.vpcName = vpcName;
|
||||
this.vpcId = vpcId;
|
||||
this.vpcCidr = vpcCidr;
|
||||
}
|
||||
|
||||
public String getVpcName() {
|
||||
return vpcName;
|
||||
}
|
||||
|
||||
public Long getVpcId() {
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
public String getNatIp() {
|
||||
return natIp;
|
||||
}
|
||||
|
||||
public void setNatRuleName(String natRuleName) {
|
||||
this.natRuleName = natRuleName;
|
||||
}
|
||||
|
||||
public String getNatRuleName() {
|
||||
return natRuleName;
|
||||
}
|
||||
|
||||
public String getVpcCidr() {
|
||||
return vpcCidr;
|
||||
}
|
||||
|
||||
public void setNatIp(String natIp) {
|
||||
this.natIp = natIp;
|
||||
}
|
||||
|
||||
public String getVmIp() {
|
||||
return vmIp;
|
||||
}
|
||||
|
||||
public void setVmIp(String vmIp) {
|
||||
this.vmIp = vmIp;
|
||||
}
|
||||
|
||||
public String getNatRuleType() {
|
||||
return natRuleType;
|
||||
}
|
||||
|
||||
public void setNatRuleType(String natRuleType) {
|
||||
this.natRuleType = natRuleType;
|
||||
}
|
||||
|
||||
public void setVpcName(String vpcName) {
|
||||
this.vpcName = vpcName;
|
||||
}
|
||||
|
||||
public void setVpcId(Long vpcId) {
|
||||
this.vpcId = vpcId;
|
||||
}
|
||||
|
||||
public void setVpcCidr(String vpcCidr) {
|
||||
this.vpcCidr = vpcCidr;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public String getSourceAddress() {
|
||||
return sourceAddress;
|
||||
}
|
||||
|
||||
public void setSourceAddress(String sourceAddress) {
|
||||
this.sourceAddress = sourceAddress;
|
||||
}
|
||||
|
||||
public String getSourcePort() {
|
||||
return sourcePort;
|
||||
}
|
||||
|
||||
public void setSourcePort(String sourcePort) {
|
||||
this.sourcePort = sourcePort;
|
||||
}
|
||||
|
||||
public String getDestinationAddress() {
|
||||
return destinationAddress;
|
||||
}
|
||||
|
||||
public void setDestinationAddress(String destinationAddress) {
|
||||
this.destinationAddress = destinationAddress;
|
||||
}
|
||||
|
||||
public String getDestinationPort() {
|
||||
return destinationPort;
|
||||
}
|
||||
|
||||
public void setDestinationPort(String destinationPort) {
|
||||
this.destinationPort = destinationPort;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.agent.api;
|
||||
|
||||
public class DeleteNetrisNatRuleCommand extends NetrisCommand {
|
||||
|
||||
private String vpcName;
|
||||
private Long vpcId;
|
||||
private String natRuleType;
|
||||
private String natRuleName;
|
||||
private String natIp;
|
||||
|
||||
public DeleteNetrisNatRuleCommand(long zoneId, Long accountId, Long domainId, String vpcName, Long vpcId, String vNetName, Long networkId, boolean isVpc) {
|
||||
super(zoneId, accountId, domainId, vNetName, networkId, isVpc);
|
||||
this.vpcName = vpcName;
|
||||
this.vpcId = vpcId;
|
||||
}
|
||||
|
||||
public String getVpcName() {
|
||||
return vpcName;
|
||||
}
|
||||
|
||||
public void setVpcName(String vpcName) {
|
||||
this.vpcName = vpcName;
|
||||
}
|
||||
|
||||
public Long getVpcId() {
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
public void setVpcId(Long vpcId) {
|
||||
this.vpcId = vpcId;
|
||||
}
|
||||
|
||||
public String getNatRuleType() {
|
||||
return natRuleType;
|
||||
}
|
||||
|
||||
public void setNatRuleType(String natRuleType) {
|
||||
this.natRuleType = natRuleType;
|
||||
}
|
||||
|
||||
public String getNatRuleName() {
|
||||
return natRuleName;
|
||||
}
|
||||
|
||||
public void setNatRuleName(String natRuleName) {
|
||||
this.natRuleName = natRuleName;
|
||||
}
|
||||
|
||||
public String getNatIp() {
|
||||
return natIp;
|
||||
}
|
||||
|
||||
public void setNatIp(String natIp) {
|
||||
this.natIp = natIp;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,11 +22,11 @@ public class NetrisCommand extends Command {
|
|||
private final long zoneId;
|
||||
private final Long accountId;
|
||||
private final Long domainId;
|
||||
private final String name;
|
||||
private final long id;
|
||||
private String name;
|
||||
private final Long id;
|
||||
private final boolean isVpc;
|
||||
|
||||
public NetrisCommand(long zoneId, Long accountId, Long domainId, String name, long id, boolean isVpc) {
|
||||
public NetrisCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc) {
|
||||
this.zoneId = zoneId;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
|
|
@ -40,7 +40,11 @@ public class NetrisCommand extends Command {
|
|||
return name;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.resource;
|
||||
|
||||
import com.cloud.network.SDNProviderNetworkRule;
|
||||
|
||||
public class NetrisNetworkRule extends SDNProviderNetworkRule {
|
||||
}
|
||||
|
|
@ -30,6 +30,8 @@ import com.cloud.resource.ServerResource;
|
|||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.NetrisAnswer;
|
||||
|
|
@ -97,6 +99,10 @@ public class NetrisResource implements ServerResource {
|
|||
return executeRequest((DeleteNetrisVnetCommand) cmd);
|
||||
} else if (cmd instanceof SetupNetrisPublicRangeCommand) {
|
||||
return executeRequest((SetupNetrisPublicRangeCommand) cmd);
|
||||
} else if (cmd instanceof DeleteNetrisNatRuleCommand) {
|
||||
return executeRequest((DeleteNetrisNatRuleCommand) cmd);
|
||||
} else if (cmd instanceof CreateOrUpdateNetrisNatCommand) {
|
||||
return executeRequest((CreateOrUpdateNetrisNatCommand) cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
|
|
@ -261,6 +267,36 @@ public class NetrisResource implements ServerResource {
|
|||
return new NetrisAnswer(cmd, true, "OK");
|
||||
}
|
||||
|
||||
private Answer executeRequest(CreateOrUpdateNetrisNatCommand cmd) {
|
||||
String natRuleType = cmd.getNatRuleType();
|
||||
if ("SNAT".equals(natRuleType)) {
|
||||
boolean result = netrisApiClient.createOrUpdateSNATRule(cmd);
|
||||
if (!result) {
|
||||
return new NetrisAnswer(cmd, false, String.format("Failed to create SNAT rule on Netris for network %s", cmd.getName()));
|
||||
}
|
||||
} else if ("DNAT".equals(natRuleType)) {
|
||||
boolean result = netrisApiClient.createOrUpdateDNATRule(cmd);
|
||||
if (!result) {
|
||||
return new NetrisAnswer(cmd, false, String.format("Failed to create DNAT rule on Netris for network %s", cmd.getName()));
|
||||
}
|
||||
} else if ("STATICNAT".equals(natRuleType)) {
|
||||
boolean result = netrisApiClient.createStaticNatRule(cmd);
|
||||
if (!result) {
|
||||
return new NetrisAnswer(cmd, false, String.format("Failed to create SNAT rule on Netris for network %s", cmd.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
return new NetrisAnswer(cmd, true, "OK");
|
||||
}
|
||||
|
||||
private Answer executeRequest(DeleteNetrisNatRuleCommand cmd) {
|
||||
boolean result = netrisApiClient.deleteNatRule(cmd);
|
||||
if (!result) {
|
||||
return new NetrisAnswer(cmd, false, String.format("Netris NAT rule: %s deletion failed", cmd.getNatRuleName()));
|
||||
}
|
||||
return new NetrisAnswer(cmd, true, "OK");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@ import org.apache.commons.lang3.ArrayUtils;
|
|||
public class NetrisResourceObjectUtils {
|
||||
|
||||
public enum NetrisObjectType {
|
||||
VPC, IPAM_ALLOCATION, IPAM_SUBNET, VNET
|
||||
VPC, IPAM_ALLOCATION, IPAM_SUBNET, VNET, SNAT, STATICNAT, DNAT
|
||||
}
|
||||
|
||||
public static String retrieveNetrisResourceObjectName(NetrisCommand cmd, NetrisObjectType netrisObjectType, String... suffixes) {
|
||||
long zoneId = cmd.getZoneId();
|
||||
Long accountId = cmd.getAccountId();
|
||||
Long domainId = cmd.getDomainId();
|
||||
long objectId = cmd.getId();
|
||||
Long objectId = cmd.getId();
|
||||
String objectName = cmd.getName();
|
||||
boolean isVpc = cmd.isVpc();
|
||||
boolean isZoneLevel = accountId == null && domainId == null;
|
||||
|
|
@ -60,6 +60,18 @@ public class NetrisResourceObjectUtils {
|
|||
stringBuilder.append(String.format("-N%s", objectId));
|
||||
}
|
||||
break;
|
||||
case SNAT:
|
||||
stringBuilder.append(String.format("%s%s-%s", prefix, suffixes[0], "SNAT"));
|
||||
suffixes = new String[0];
|
||||
break;
|
||||
case STATICNAT:
|
||||
stringBuilder.append(String.format("%s%s-%s", prefix, suffixes[0], "STATICNAT"));
|
||||
suffixes = new String[0];
|
||||
break;
|
||||
case DNAT:
|
||||
stringBuilder.append(String.format("%s%s-%s", prefix, suffixes[0], "DNAT"));
|
||||
suffixes = ArrayUtils.subarray(suffixes, 1, suffixes.length);
|
||||
break;
|
||||
case VNET:
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import io.netris.model.VPCListing;
|
|||
import io.netris.model.response.TenantResponse;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
|
||||
|
|
@ -48,8 +50,18 @@ public interface NetrisApiClient {
|
|||
*/
|
||||
boolean deleteVpc(DeleteNetrisVpcCommand cmd);
|
||||
|
||||
/**
|
||||
* Creation of a VPC network tier creates the following Netris resources:
|
||||
* - Creates a Netris IPAM Subnet for the specified network tier's CIDR
|
||||
* - Creates a Netris vNet
|
||||
*/
|
||||
boolean createVnet(CreateNetrisVnetCommand cmd);
|
||||
|
||||
/**
|
||||
* Deletion of a VPC network tier deletes the following Netris resources:
|
||||
* - Deletes the Netris IPAM Subnet for the specified network tier's CIDR
|
||||
* - Deletes the Netris vNet
|
||||
*/
|
||||
boolean deleteVnet(DeleteNetrisVnetCommand cmd);
|
||||
|
||||
/**
|
||||
|
|
@ -58,4 +70,8 @@ public interface NetrisApiClient {
|
|||
* - Check the IPAM subnet for NAT purpose for the range start-end. In case it doesn't exist, create it
|
||||
*/
|
||||
boolean setupZoneLevelPublicRange(SetupNetrisPublicRangeCommand cmd);
|
||||
boolean createOrUpdateSNATRule(CreateOrUpdateNetrisNatCommand cmd);
|
||||
boolean createOrUpdateDNATRule(CreateOrUpdateNetrisNatCommand cmd);
|
||||
boolean createStaticNatRule(CreateOrUpdateNetrisNatCommand cmd);
|
||||
boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import io.netris.api.v1.AuthenticationApi;
|
|||
import io.netris.api.v1.SitesApi;
|
||||
import io.netris.api.v1.TenantsApi;
|
||||
import io.netris.api.v2.IpamApi;
|
||||
import io.netris.api.v2.NatApi;
|
||||
import io.netris.api.v2.VNetApi;
|
||||
import io.netris.api.v2.VpcApi;
|
||||
import io.netris.model.AllocationBody;
|
||||
|
|
@ -32,6 +33,8 @@ import io.netris.model.AllocationBodyVpc;
|
|||
import io.netris.model.FilterBySites;
|
||||
import io.netris.model.FilterByVpc;
|
||||
import io.netris.model.GetSiteBody;
|
||||
import io.netris.model.InlineResponse20015;
|
||||
import io.netris.model.InlineResponse20016;
|
||||
import io.netris.model.InlineResponse2004;
|
||||
import io.netris.model.InlineResponse2004Data;
|
||||
import io.netris.model.IpTree;
|
||||
|
|
@ -39,6 +42,12 @@ import io.netris.model.IpTreeAllocation;
|
|||
import io.netris.model.IpTreeAllocationTenant;
|
||||
import io.netris.model.IpTreeSubnet;
|
||||
import io.netris.model.IpTreeSubnetSites;
|
||||
import io.netris.model.NatBodySiteSite;
|
||||
import io.netris.model.NatBodyVpcVpc;
|
||||
import io.netris.model.NatGetBody;
|
||||
import io.netris.model.NatPostBody;
|
||||
import io.netris.model.NatPutBody;
|
||||
import io.netris.model.NatResponseGetOk;
|
||||
import io.netris.model.SitesResponseOK;
|
||||
import io.netris.model.SubnetBody;
|
||||
import io.netris.model.SubnetResBody;
|
||||
|
|
@ -62,13 +71,16 @@ import io.netris.model.VnetsBody;
|
|||
import io.netris.model.response.AuthResponse;
|
||||
import io.netris.model.response.TenantResponse;
|
||||
import io.netris.model.response.TenantsResponse;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
|
||||
import org.apache.cloudstack.resource.NetrisResourceObjectUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
|
@ -245,8 +257,50 @@ public class NetrisApiClientImpl implements NetrisApiClient {
|
|||
return createdIpamAllocation != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd) {
|
||||
try {
|
||||
String suffix = getNetrisVpcNameSuffix(cmd.getVpcId(), cmd.getVpcName(), cmd.getId(), cmd.getName(), cmd.isVpc());
|
||||
String vpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffix);
|
||||
VPCListing vpcResource = getVpcByNameAndTenant(vpcName);
|
||||
if (vpcResource == null) {
|
||||
logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", vpcName, tenantId);
|
||||
return false;
|
||||
}
|
||||
String natRuleName = cmd.getNatRuleName();
|
||||
NatGetBody existingNatRule = netrisNatRuleExists(natRuleName);
|
||||
boolean ruleExists = Objects.nonNull(existingNatRule);
|
||||
if (ruleExists) {
|
||||
deleteNatRule(natRuleName, existingNatRule.getId(), vpcResource.getName());
|
||||
if (cmd.getNatRuleType().equals("STATICNAT")) {
|
||||
deleteNatSubnet(vpcResource.getId(), cmd.getNatIp());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Error deleting Netris NAT Rule", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void deleteNatSubnet(Integer netrisVpcId, String natIp) {
|
||||
FilterByVpc vpcFilter = new FilterByVpc();
|
||||
vpcFilter.add(netrisVpcId);
|
||||
String netrisSubnetName = natIp + "/32";
|
||||
deleteSubnetInternal(vpcFilter, null, netrisSubnetName);
|
||||
}
|
||||
|
||||
public void deleteNatRule(String natRuleName, Integer snatRuleId, String netrisVpcName) {
|
||||
logger.debug("Deleting NAT rule on Netris: {} for VPC {}", natRuleName, netrisVpcName);
|
||||
try {
|
||||
NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
|
||||
natApi.apiV2NatIdDelete(snatRuleId);
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException(String.format("Failed to delete NAT rule: %s for VPC: %s", natRuleName, netrisVpcName), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteVpcIpamAllocationInternal(VPCListing vpcResource, String vpcCidr) {
|
||||
logger.debug(String.format("Deleting Netris VPC IPAM Allocation %s for VPC %s", vpcCidr, vpcResource.getName()));
|
||||
logger.debug("Deleting Netris VPC IPAM Allocation {} for VPC {}", vpcCidr, vpcResource.getName());
|
||||
try {
|
||||
VpcApi vpcApi = apiClient.getApiStubForMethod(VpcApi.class);
|
||||
VPCResponseResourceOK vpcResourcesResponse = vpcApi.apiV2VpcVpcIdResourcesGet(vpcResource.getId());
|
||||
|
|
@ -300,12 +354,20 @@ public class NetrisApiClientImpl implements NetrisApiClient {
|
|||
|
||||
@Override
|
||||
public boolean deleteVpc(DeleteNetrisVpcCommand cmd) {
|
||||
String suffix = String.valueOf(cmd.getId());
|
||||
String vpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC);
|
||||
VPCListing vpcResource = getVpcByNameAndTenant(vpcName);
|
||||
if (vpcResource == null) {
|
||||
logger.error(String.format("Could not find the Netris VPC resource with name %s and tenant ID %s", vpcName, tenantId));
|
||||
logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", vpcName, tenantId);
|
||||
return false;
|
||||
}
|
||||
String snatRuleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.SNAT, suffix);
|
||||
NatGetBody existingNatRule = netrisNatRuleExists(snatRuleName);
|
||||
boolean ruleExists = Objects.nonNull(existingNatRule);
|
||||
if (ruleExists) {
|
||||
deleteNatRule(snatRuleName, existingNatRule.getId(), vpcResource.getName());
|
||||
}
|
||||
|
||||
String vpcCidr = cmd.getCidr();
|
||||
deleteVpcIpamAllocationInternal(vpcResource, vpcCidr);
|
||||
VPCResponseObjectOK response = deleteVpcInternal(vpcResource);
|
||||
|
|
@ -424,7 +486,9 @@ public class NetrisApiClientImpl implements NetrisApiClient {
|
|||
filterByVpc.add(vpc.getId());
|
||||
SubnetResBody subnetResBody = ipamApi.apiV2IpamSubnetsGet(filterByVpc);
|
||||
List<IpTreeSubnet> exactSubnetList = subnetResBody.getData().stream()
|
||||
.filter(x -> x.getAllocationID().equals(ipamAllocationId) && x.getPrefix().equals(exactCidr) && x.getPurpose() == purpose)
|
||||
.filter(x -> ipamAllocationId != null ?
|
||||
x.getAllocationID().equals(ipamAllocationId) && x.getPrefix().equals(exactCidr) && x.getPurpose() == purpose :
|
||||
x.getPrefix().equals(exactCidr) && x.getPurpose() == purpose)
|
||||
.collect(Collectors.toList());
|
||||
return CollectionUtils.isEmpty(exactSubnetList) ? null : exactSubnetList.get(0);
|
||||
}
|
||||
|
|
@ -460,6 +524,288 @@ public class NetrisApiClientImpl implements NetrisApiClient {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean createOrUpdateNatRuleInternal(CreateOrUpdateNetrisNatCommand cmd) {
|
||||
String ruleName = cmd.getNatRuleName();
|
||||
long vpcId = cmd.getVpcId();
|
||||
Long networkId = cmd.getId();
|
||||
String networkName = cmd.getName();
|
||||
String vpcName = cmd.getVpcName();
|
||||
String vpcCidr = cmd.getVpcCidr();
|
||||
boolean isVpc = cmd.isVpc();
|
||||
NatPostBody.ActionEnum action = getNatActionFromRuleType(cmd.getNatRuleType());
|
||||
NatPostBody.ProtocolEnum protocol = getProtocolFromString(cmd.getProtocol());
|
||||
NatPostBody.StateEnum state = getStateFromString(cmd.getState());
|
||||
|
||||
String vNetName = isVpc ?
|
||||
String.format("V%s-N%s-%s", vpcId, networkId, networkName) :
|
||||
String.format("N%s-%s", networkId, networkName);
|
||||
String vpcSuffix = getNetrisVpcNameSuffix(vpcId, vpcName, networkId, networkName, isVpc);
|
||||
String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, vpcSuffix);
|
||||
VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
|
||||
if (vpcResource == null) {
|
||||
logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
|
||||
return false;
|
||||
}
|
||||
|
||||
String targetIpSubnet = null;
|
||||
if (NatPostBody.ActionEnum.SNAT == action) {
|
||||
targetIpSubnet = cmd.getNatIp() + "/32";
|
||||
} else if (NatPostBody.ActionEnum.DNAT == action) {
|
||||
targetIpSubnet = cmd.getDestinationAddress() + "/32";
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(targetIpSubnet) && existsDestinationSubnet(targetIpSubnet)) {
|
||||
logger.debug(String.format("Creating subnet with NAT purpose for %s", targetIpSubnet));
|
||||
createNatSubnet(targetIpSubnet, vpcResource.getId());
|
||||
}
|
||||
|
||||
NatGetBody existingNatRule = netrisNatRuleExists(ruleName);
|
||||
boolean ruleExists = Objects.nonNull(existingNatRule);
|
||||
if (!ruleExists) {
|
||||
String destinationAddress = action == NatPostBody.ActionEnum.SNAT ? "0.0.0.0/0" : cmd.getDestinationAddress() + "/32";
|
||||
String destinationPort = cmd.getDestinationPort();
|
||||
String sourceAddress = action == NatPostBody.ActionEnum.SNAT ? vpcCidr : "0.0.0.0/0";
|
||||
String sourcePort = "1-65535";
|
||||
String snatToIp = action == NatPostBody.ActionEnum.SNAT ? targetIpSubnet : null;
|
||||
String dnatToIp = action == NatPostBody.ActionEnum.DNAT ? cmd.getSourceAddress() + "/32" : null;
|
||||
String dnatToPort = action == NatPostBody.ActionEnum.DNAT ? cmd.getSourcePort() : null;
|
||||
return createNatRuleInternal(ruleName, action, protocol, state, destinationAddress, destinationPort,
|
||||
sourceAddress, sourcePort, snatToIp, dnatToIp, dnatToPort, netrisVpcName, networkName, vNetName);
|
||||
} else if (NatPostBody.ActionEnum.SNAT == action) {
|
||||
return updateSnatRuleInternal(ruleName, targetIpSubnet, netrisVpcName, networkName, vNetName, existingNatRule.getId(), vpcCidr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private NatPostBody.StateEnum getStateFromString(String state) {
|
||||
return NatPostBody.StateEnum.fromValue(state);
|
||||
}
|
||||
|
||||
private NatPostBody.ActionEnum getNatActionFromRuleType(String natRuleType) {
|
||||
return NatPostBody.ActionEnum.fromValue(natRuleType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createOrUpdateSNATRule(CreateOrUpdateNetrisNatCommand cmd) {
|
||||
return createOrUpdateNatRuleInternal(cmd);
|
||||
}
|
||||
|
||||
private boolean existsDestinationSubnet(String destinationSubnet) {
|
||||
try {
|
||||
FilterByVpc vpcFilter = new FilterByVpc();
|
||||
vpcFilter.add(getSystemVpc().getId());
|
||||
List<IpTreeSubnet> targetSubnetList = getSubnet(vpcFilter, destinationSubnet);
|
||||
return targetSubnetList != null;
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException(String.format("Error checking if subnet %s exists: %s", destinationSubnet, e.getMessage()), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createStaticNatRule(CreateOrUpdateNetrisNatCommand cmd) {
|
||||
String staticNatRuleName = cmd.getNatRuleName();
|
||||
String natIP = cmd.getNatIp() + "/32";
|
||||
String vmIp = cmd.getVmIp() + "/32";
|
||||
String vpcName = cmd.getVpcName();
|
||||
String vpcCidr = cmd.getVpcCidr();
|
||||
Long vpcId = cmd.getVpcId();
|
||||
Long networkId = cmd.getId();
|
||||
String networkName = cmd.getName();
|
||||
boolean isVpc = cmd.isVpc();
|
||||
|
||||
try {
|
||||
String vpcSuffix = getNetrisVpcNameSuffix(vpcId, vpcName, networkId, networkName, isVpc);
|
||||
String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, vpcSuffix);
|
||||
VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
|
||||
if (vpcResource == null) {
|
||||
logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
|
||||
return false;
|
||||
}
|
||||
// Create a /32 subnet for the DNAT IP
|
||||
createNatSubnet(natIP, vpcResource.getId());
|
||||
NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
|
||||
NatPostBody natBody = new NatPostBody();
|
||||
natBody.setAction(NatPostBody.ActionEnum.DNAT);
|
||||
natBody.setDestinationAddress(natIP);
|
||||
natBody.setName(staticNatRuleName);
|
||||
natBody.setProtocol(NatPostBody.ProtocolEnum.ALL);
|
||||
natBody.setState(NatPostBody.StateEnum.ENABLED);
|
||||
natBody.setComment(String.format("Static NAT rule for %s", netrisVpcName));
|
||||
|
||||
NatBodySiteSite site = new NatBodySiteSite();
|
||||
site.setId(siteId);
|
||||
site.setName(siteName);
|
||||
natBody.setSite(site);
|
||||
natBody.setSourceAddress("0.0.0.0/0");
|
||||
natBody.setDnatToIP(vmIp);
|
||||
|
||||
NatBodyVpcVpc vpc = new NatBodyVpcVpc();
|
||||
vpc.setId(vpcResource.getId());
|
||||
vpc.setName(vpcResource.getName());
|
||||
natBody.setVpc(vpc);
|
||||
|
||||
InlineResponse20015 natResponse = natApi.apiV2NatPost(natBody);
|
||||
if (natResponse == null || !natResponse.isIsSuccess()) {
|
||||
String reason = natResponse == null ? "Empty response" : "Operation failed on Netris";
|
||||
logger.debug("The Netris static NAT (DNAT) rule creation failed for netris VPC - {}: {}", netrisVpcName, reason);
|
||||
throw new CloudRuntimeException(reason);
|
||||
}
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException(String.format("Failed to create Static NAT (DNAT) rule for network : %s", Objects.nonNull(vpcName) ? vpcName : networkName), e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void createNatSubnet(String natIp, Integer netrisVpcId) {
|
||||
try {
|
||||
FilterByVpc vpcFilter = new FilterByVpc();
|
||||
vpcFilter.add(netrisVpcId);
|
||||
String netrisSubnetName = natIp;
|
||||
List<IpTreeSubnet> matchedSubnets = getSubnet(vpcFilter, netrisSubnetName);
|
||||
if (matchedSubnets.isEmpty()) {
|
||||
VPCListing systemVpc = getSystemVpc();
|
||||
createIpamSubnetInternal(natIp, natIp, SubnetBody.PurposeEnum.NAT, systemVpc);
|
||||
return;
|
||||
}
|
||||
logger.debug("NAT subnet: {} already exists", natIp);
|
||||
} catch (ApiException e) {
|
||||
throw new CloudRuntimeException(String.format("Failed to create subnet for %s with NAT purpose", natIp));
|
||||
}
|
||||
}
|
||||
|
||||
private NatPostBody.ProtocolEnum getProtocolFromString(String protocol) {
|
||||
return NatPostBody.ProtocolEnum.fromValue(protocol);
|
||||
}
|
||||
|
||||
private NatPostBody createNatRulePostBody(String ruleName, NatPostBody.ActionEnum action, NatPostBody.ProtocolEnum protocol, NatPostBody.StateEnum state,
|
||||
String destinationAddress, String destinationPort,
|
||||
String sourceAddress, String sourcePort,
|
||||
String dnatToIp, String dnatToPort,
|
||||
String netrisVpcName, String snatIP, String comment) {
|
||||
NatPostBody natBody = new NatPostBody();
|
||||
natBody.setAction(action);
|
||||
natBody.setName(ruleName);
|
||||
natBody.setProtocol(protocol);
|
||||
natBody.setState(state);
|
||||
if (StringUtils.isNotBlank(comment)) {
|
||||
natBody.setComment(comment);
|
||||
}
|
||||
|
||||
natBody.setDestinationAddress(destinationAddress);
|
||||
if (StringUtils.isNotBlank(destinationPort)) {
|
||||
natBody.setDestinationPort(destinationPort);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(sourceAddress)) {
|
||||
natBody.setSourceAddress(sourceAddress);
|
||||
}
|
||||
if (StringUtils.isNotBlank(sourcePort)) {
|
||||
natBody.setSourcePort(sourcePort);
|
||||
}
|
||||
|
||||
NatBodySiteSite site = new NatBodySiteSite();
|
||||
site.setId(siteId);
|
||||
site.setName(siteName);
|
||||
natBody.setSite(site);
|
||||
|
||||
if (StringUtils.isNotBlank(snatIP)) {
|
||||
natBody.setSourceAddress(snatIP);
|
||||
natBody.setSnatToIP(snatIP);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(dnatToIp)) {
|
||||
natBody.setDnatToIP(dnatToIp);
|
||||
}
|
||||
if (StringUtils.isNotBlank(dnatToPort)) {
|
||||
natBody.setDnatToPort(Integer.valueOf(dnatToPort));
|
||||
}
|
||||
|
||||
NatBodyVpcVpc vpc = new NatBodyVpcVpc();
|
||||
VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
|
||||
if (vpcResource == null) {
|
||||
logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
|
||||
return null;
|
||||
}
|
||||
vpc.setId(vpcResource.getId());
|
||||
vpc.setName(vpcResource.getName());
|
||||
natBody.setVpc(vpc);
|
||||
return natBody;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createOrUpdateDNATRule(CreateOrUpdateNetrisNatCommand cmd) {
|
||||
return createOrUpdateNatRuleInternal(cmd);
|
||||
}
|
||||
|
||||
private boolean createNatRuleInternal(String ruleName, NatPostBody.ActionEnum action, NatPostBody.ProtocolEnum protocol, NatPostBody.StateEnum state,
|
||||
String destinationAddress, String destinationPort, String sourceAddress, String sourcePort,
|
||||
String sNatToIp, String dNatToIp, String dNatToPort,
|
||||
String netrisVpcName, String networkName, String vNetName) {
|
||||
try {
|
||||
NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
|
||||
String comment = String.format("NAT rule for %s with action %s", netrisVpcName, action.name());
|
||||
NatPostBody natBody = createNatRulePostBody(ruleName, action, protocol, state,
|
||||
destinationAddress, destinationPort, sourceAddress, sourcePort,
|
||||
dNatToIp, dNatToPort, netrisVpcName, sNatToIp, comment);
|
||||
if (natBody == null) {
|
||||
return false;
|
||||
}
|
||||
InlineResponse20015 natResponse = natApi.apiV2NatPost(natBody);
|
||||
if (natResponse == null || !natResponse.isIsSuccess()) {
|
||||
String reason = natResponse == null ? "Empty response" : "Operation failed on Netris";
|
||||
logger.debug("The Netris NAT rule {} creation failed for network(vNet) - {}({}): {}", action.name(), networkName, vNetName, reason);
|
||||
throw new CloudRuntimeException(reason);
|
||||
}
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException(String.format("Failed to create NAT rule %s for network(vNet): %s(%s)", action.name(), networkName, vNetName), e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateNatRequest(NatPostBody natBody) {
|
||||
|
||||
}
|
||||
|
||||
private boolean updateSnatRuleInternal(String snatRuleName, String snatIP, String netrisVpcName, String networkName,
|
||||
String vNetName, Integer netisSnatId, String vpcCidr) {
|
||||
try {
|
||||
NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
|
||||
NatPutBody natBody = new NatPutBody();
|
||||
natBody.setAction(NatPutBody.ActionEnum.SNAT);
|
||||
natBody.setDestinationAddress("0.0.0.0/0");
|
||||
natBody.setName(snatRuleName);
|
||||
natBody.setProtocol(NatPutBody.ProtocolEnum.ALL);
|
||||
|
||||
NatBodySiteSite site = new NatBodySiteSite();
|
||||
site.setId(siteId);
|
||||
site.setName(siteName);
|
||||
natBody.setSite(site);
|
||||
natBody.setSourceAddress(vpcCidr);
|
||||
natBody.setSnatToIP(snatIP);
|
||||
|
||||
NatBodyVpcVpc vpc = new NatBodyVpcVpc();
|
||||
VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
|
||||
if (vpcResource == null) {
|
||||
logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
|
||||
return false;
|
||||
}
|
||||
vpc.setId(vpcResource.getId());
|
||||
vpc.setName(vpcResource.getName());
|
||||
natBody.setVpc(vpc);
|
||||
|
||||
InlineResponse20016 natUpdateResponse = natApi.apiV2NatIdPut(natBody, netisSnatId);
|
||||
if (natUpdateResponse == null || !natUpdateResponse.isIsSuccess()) {
|
||||
String reason = natUpdateResponse == null ? "Empty response" : "Operation failed on Netris";
|
||||
logger.debug("Update of Netris SNAT rule failed for network(vNet) - {}({}): {}", networkName, vNetName, reason);
|
||||
throw new CloudRuntimeException(reason);
|
||||
}
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException(String.format("Failed to create SNAT rule for network(vNet): %s(%s)", networkName, vNetName), e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void deleteVnetInternal(VPCListing associatedVpc, FilterBySites siteFilter, FilterByVpc vpcFilter, String netrisVnetName, String vNetName) {
|
||||
try {
|
||||
VNetApi vNetApi = apiClient.getApiStubForMethod(VNetApi.class);
|
||||
|
|
@ -483,21 +829,35 @@ public class NetrisApiClientImpl implements NetrisApiClient {
|
|||
}
|
||||
}
|
||||
|
||||
private void deleteSubnetInternal(FilterByVpc vpcFilter, String netrisVnetName, String netrisSubnetName) {
|
||||
private List<IpTreeSubnet> getSubnet(FilterByVpc vpcFilter, String netrisSubnetName) {
|
||||
try {
|
||||
logger.debug("Deleting Netris VPC IPAM Subnet {} for vNet: {}", netrisSubnetName, netrisVnetName);
|
||||
IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
|
||||
SubnetResBody subnetsResponse = ipamApi.apiV2IpamSubnetsGet(vpcFilter);
|
||||
List<IpTreeSubnet> subnets = subnetsResponse.getData();
|
||||
List<IpTreeSubnet> matchedSubnets = subnets.stream().filter(subnet -> subnet.getName().equals(netrisSubnetName)).collect(Collectors.toList());
|
||||
return subnets.stream().filter(subnet -> subnet.getName().equals(netrisSubnetName)).collect(Collectors.toList());
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException(String.format("Failed to get IPAM subnet: %s", netrisSubnetName), e);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private void deleteSubnetInternal(FilterByVpc vpcFilter, String netrisVnetName, String netrisSubnetName) {
|
||||
try {
|
||||
String logString = "";
|
||||
if (Objects.nonNull(netrisVnetName)) {
|
||||
logString = String.format("for vNet: %s ", netrisVnetName);
|
||||
}
|
||||
logger.debug("Deleting Netris VPC IPAM Subnet {} {}", netrisSubnetName, logString);
|
||||
IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
|
||||
List<IpTreeSubnet> matchedSubnets = getSubnet(vpcFilter, netrisSubnetName);
|
||||
if (CollectionUtils.isEmpty(matchedSubnets)) {
|
||||
logger.debug("IPAM subnet: {} for the given vNet: {} appears to already be deleted on Netris", netrisSubnetName, netrisVnetName);
|
||||
logger.debug("IPAM subnet: {} {} appears to already be deleted on Netris", netrisSubnetName, logString);
|
||||
return;
|
||||
}
|
||||
|
||||
ipamApi.apiV2IpamTypeIdDelete("subnet", matchedSubnets.get(0).getId().intValue());
|
||||
} catch (ApiException e) {
|
||||
logAndThrowException(String.format("Failed to delete vNet: %s", netrisVnetName), e);
|
||||
logAndThrowException(String.format("Failed to delete subnet: %s", netrisSubnetName), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -607,4 +967,23 @@ public class NetrisApiClientImpl implements NetrisApiClient {
|
|||
}
|
||||
return suffix;
|
||||
}
|
||||
|
||||
private NatGetBody netrisNatRuleExists(String netrisNatRule) {
|
||||
try {
|
||||
NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
|
||||
//NatResponseGetOk response = natApi.apiV2NatGet(null, Arrays.asList(new BigDecimal(vpcId)));
|
||||
NatResponseGetOk response = natApi.apiV2NatGet(null, null);
|
||||
if (Objects.isNull(response) || !response.isIsSuccess()) {
|
||||
throw new CloudRuntimeException("Failed to list Netris NAT rules");
|
||||
}
|
||||
List<NatGetBody> data = response.getData().stream().filter(natData -> natData.getName().equals(netrisNatRule)).collect(Collectors.toList());
|
||||
if (data.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return data.get(0);
|
||||
|
||||
} catch (ApiException e) {
|
||||
throw new CloudRuntimeException("Failed to list Netris NAT rules");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.cloud.agent.api.AgentControlCommand;
|
|||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
|
|
@ -39,15 +40,25 @@ import com.cloud.network.IpAddress;
|
|||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.PhysicalNetworkServiceProvider;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
import com.cloud.network.SDNProviderOpObject;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.element.DhcpServiceProvider;
|
||||
import com.cloud.network.element.DnsServiceProvider;
|
||||
import com.cloud.network.element.IpDeployer;
|
||||
import com.cloud.network.element.NetworkACLServiceProvider;
|
||||
import com.cloud.network.element.PortForwardingServiceProvider;
|
||||
import com.cloud.network.element.StaticNatServiceProvider;
|
||||
import com.cloud.network.element.VirtualRouterElement;
|
||||
import com.cloud.network.element.VpcProvider;
|
||||
import com.cloud.network.netris.NetrisService;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.LoadBalancerContainer;
|
||||
import com.cloud.network.rules.PortForwardingRule;
|
||||
import com.cloud.network.rules.StaticNat;
|
||||
import com.cloud.network.vpc.NetworkACLItem;
|
||||
import com.cloud.network.vpc.PrivateGateway;
|
||||
import com.cloud.network.vpc.StaticRouteProfile;
|
||||
|
|
@ -61,27 +72,39 @@ import com.cloud.resource.ServerResource;
|
|||
import com.cloud.resource.UnableDeleteHostException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallback;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.apache.cloudstack.StartupNetrisCommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.resource.NetrisNetworkRule;
|
||||
import org.apache.cloudstack.resourcedetail.FirewallRuleDetailVO;
|
||||
import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
public class NetrisElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
|
||||
NetworkACLServiceProvider, ResourceStateAdapter, Listener {
|
||||
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider, ResourceStateAdapter, Listener {
|
||||
|
||||
@Inject
|
||||
NetworkModel networkModel;
|
||||
|
|
@ -101,6 +124,12 @@ public class NetrisElement extends AdapterBase implements DhcpServiceProvider, D
|
|||
private DomainDao domainDao;
|
||||
@Inject
|
||||
private VpcDao vpcDao;
|
||||
@Inject
|
||||
private FirewallRuleDetailsDao firewallRuleDetailsDao;
|
||||
@Inject
|
||||
private IPAddressDao ipAddressDao;
|
||||
@Inject
|
||||
private VMInstanceDao vmInstanceDao;
|
||||
|
||||
protected Logger logger = LogManager.getLogger(getClass());
|
||||
|
||||
|
|
@ -257,6 +286,11 @@ public class NetrisElement extends AdapterBase implements DhcpServiceProvider, D
|
|||
return capabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Network.Service> services) throws ResourceUnavailableException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Network.Provider getProvider() {
|
||||
return Network.Provider.Netris;
|
||||
|
|
@ -398,4 +432,164 @@ public class NetrisElement extends AdapterBase implements DhcpServiceProvider, D
|
|||
public boolean reorderAclRules(Vpc vpc, List<? extends Network> networks, List<? extends NetworkACLItem> networkACLItems) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpDeployer getIpDeployer(Network network) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException {
|
||||
if (!canHandle(network, Network.Service.PortForwarding)) {
|
||||
return false;
|
||||
}
|
||||
return applyPFRulesInternal(network, rules);
|
||||
}
|
||||
|
||||
private boolean addOrRemovePFRuleOnNetris(UserVm vm, PortForwardingRule rule, NetrisNetworkRule networkRule, SDNProviderOpObject netrisObject, boolean create) {
|
||||
logger.debug("{} port forwarding rule on Netris for VM {} to ports {} - {}",
|
||||
create ? "Creating" : "Deleting", vm.getUuid(), rule.getDestinationPortStart(), rule.getDestinationPortEnd());
|
||||
Long vpcId = netrisObject.getVpcVO() != null ? netrisObject.getVpcVO().getId() : null;
|
||||
String vpcName = netrisObject.getVpcVO() != null ? netrisObject.getVpcVO().getName() : null;
|
||||
Long networkId = netrisObject.getNetworkVO() != null ? netrisObject.getNetworkVO().getId() : null;
|
||||
String networkName = netrisObject.getNetworkVO() != null ? netrisObject.getNetworkVO().getName() : null;
|
||||
String vpcCidr = netrisObject.getVpcVO() != null ? netrisObject.getVpcVO().getCidr() : null;
|
||||
|
||||
return create ?
|
||||
netrisService.createPortForwardingRule(networkRule.getZoneId(), networkRule.getAccountId(), networkRule.getDomainId(),
|
||||
vpcName, vpcId, networkName, networkId, netrisObject.isVpcResource(), vpcCidr, networkRule) :
|
||||
netrisService.deletePortForwardingRule(networkRule.getZoneId(), networkRule.getAccountId(), networkRule.getDomainId(),
|
||||
vpcName, vpcId, networkName, networkId, netrisObject.isVpcResource(), vpcCidr, networkRule);
|
||||
}
|
||||
|
||||
private boolean applyPFRulesInternal(Network network, List<PortForwardingRule> rules) {
|
||||
return Transaction.execute((TransactionCallback<Boolean>) status -> {
|
||||
boolean result = true;
|
||||
for (PortForwardingRule rule : rules) {
|
||||
IPAddressVO publicIp = ApiDBUtils.findIpAddressById(rule.getSourceIpAddressId());
|
||||
UserVm vm = ApiDBUtils.findUserVmById(rule.getVirtualMachineId());
|
||||
if (vm == null && rule.getState() != FirewallRule.State.Revoke) {
|
||||
continue;
|
||||
}
|
||||
SDNProviderOpObject netrisObject = getNetrisOpObject(network);
|
||||
String publicPort = PortForwardingServiceProvider.getPublicPortRange(rule);
|
||||
String privatePort = PortForwardingServiceProvider.getPrivatePFPortRange(rule);
|
||||
FirewallRuleDetailVO ruleDetail = firewallRuleDetailsDao.findDetail(rule.getId(), ApiConstants.NETRIS_DETAIL_KEY);
|
||||
|
||||
NetrisNetworkRule networkRule = new NetrisNetworkRule();
|
||||
networkRule.setDomainId(netrisObject.getDomainId());
|
||||
networkRule.setAccountId(netrisObject.getAccountId());
|
||||
networkRule.setZoneId(netrisObject.getZoneId());
|
||||
networkRule.setNetworkResourceId(netrisObject.getNetworkResourceId());
|
||||
networkRule.setNetworkResourceName(netrisObject.getNetworkResourceName());
|
||||
networkRule.setVpcResource(netrisObject.isVpcResource());
|
||||
networkRule.setVmId(Objects.nonNull(vm) ? vm.getId() : 0);
|
||||
networkRule.setVmIp(Objects.nonNull(vm) ? vm.getPrivateIpAddress() : null);
|
||||
networkRule.setPublicIp(publicIp.getAddress().addr());
|
||||
networkRule.setPrivatePort(privatePort);
|
||||
networkRule.setPublicPort(publicPort);
|
||||
networkRule.setRuleId(rule.getId());
|
||||
networkRule.setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT));
|
||||
|
||||
if (Arrays.asList(FirewallRule.State.Add, FirewallRule.State.Active).contains(rule.getState())) {
|
||||
boolean pfRuleResult = addOrRemovePFRuleOnNetris(vm, rule, networkRule, netrisObject, true);
|
||||
if (pfRuleResult) {
|
||||
logger.debug("Port forwarding rule {} created on Netris, adding detail on firewall rules details", rule.getId());
|
||||
if (ruleDetail == null && FirewallRule.State.Add == rule.getState()) {
|
||||
logger.debug("Adding new firewall detail for rule {}", rule.getId());
|
||||
firewallRuleDetailsDao.addDetail(rule.getId(), ApiConstants.NETRIS_DETAIL_KEY, "true", false);
|
||||
} else if (ruleDetail != null) {
|
||||
logger.debug("Updating firewall detail for rule {}", rule.getId());
|
||||
ruleDetail.setValue("true");
|
||||
firewallRuleDetailsDao.update(ruleDetail.getId(), ruleDetail);
|
||||
}
|
||||
}
|
||||
result &= pfRuleResult;
|
||||
} else if (rule.getState() == FirewallRule.State.Revoke) {
|
||||
boolean pfRuleResult = addOrRemovePFRuleOnNetris(vm, rule, networkRule, netrisObject, false);
|
||||
if (pfRuleResult && ruleDetail != null) {
|
||||
logger.debug("Updating firewall rule detail {} for rule {}, set to false", ruleDetail.getId(), rule.getId());
|
||||
ruleDetail.setValue("false");
|
||||
firewallRuleDetailsDao.update(ruleDetail.getId(), ruleDetail);
|
||||
}
|
||||
result &= pfRuleResult;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private SDNProviderOpObject getNetrisOpObject(Network network) {
|
||||
Pair<VpcVO, NetworkVO> vpcOrNetwork = getVpcOrNetwork(network.getVpcId(), network.getId());
|
||||
VpcVO vpc = vpcOrNetwork.first();
|
||||
NetworkVO networkVO = vpcOrNetwork.second();
|
||||
long domainId = getResourceId("domain", vpc, networkVO);
|
||||
long accountId = getResourceId("account", vpc, networkVO);
|
||||
long zoneId = getResourceId("zone", vpc, networkVO);
|
||||
|
||||
return new SDNProviderOpObject.Builder()
|
||||
.vpcVO(vpc)
|
||||
.networkVO(networkVO)
|
||||
.domainId(domainId)
|
||||
.accountId(accountId)
|
||||
.zoneId(zoneId)
|
||||
.build();
|
||||
}
|
||||
|
||||
public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
|
||||
for(StaticNat staticNat : rules) {
|
||||
long sourceIpAddressId = staticNat.getSourceIpAddressId();
|
||||
IPAddressVO ipAddressVO = ipAddressDao.findByIdIncludingRemoved(sourceIpAddressId);
|
||||
VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(ipAddressVO.getAssociatedWithVmId());
|
||||
// floating ip is released when nic was deleted
|
||||
if (vm == null || networkModel.getNicInNetworkIncludingRemoved(vm.getId(), config.getId()) == null) {
|
||||
continue;
|
||||
}
|
||||
Pair<VpcVO, NetworkVO> vpcOrNetwork = getVpcOrNetwork(config.getVpcId(), config.getId());
|
||||
VpcVO vpc = vpcOrNetwork.first();
|
||||
NetworkVO network = vpcOrNetwork.second();
|
||||
Long networkResourceId = Objects.nonNull(vpc) ? vpc.getId() : network.getId();
|
||||
String networkResourceName = Objects.nonNull(vpc) ? vpc.getName() : network.getName();
|
||||
boolean isVpcResource = Objects.nonNull(vpc);
|
||||
if (!staticNat.isForRevoke()) {
|
||||
return netrisService.createStaticNatRule(config.getDataCenterId(), config.getAccountId(), config.getDomainId(),
|
||||
networkResourceName, networkResourceId, isVpcResource, vpc.getCidr(),
|
||||
ipAddressVO.getAddress().addr(), staticNat.getDestIpAddress());
|
||||
} else {
|
||||
return netrisService.deleteStaticNatRule(config.getDataCenterId(), config.getAccountId(), config.getDomainId(),
|
||||
networkResourceName, networkResourceId, isVpcResource, ipAddressVO.getAddress().addr());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Pair<VpcVO, NetworkVO> getVpcOrNetwork(Long vpcId, long networkId) {
|
||||
VpcVO vpc = null;
|
||||
NetworkVO network = null;
|
||||
if (Objects.nonNull(vpcId)) {
|
||||
vpc = vpcDao.findById(vpcId);
|
||||
if (Objects.isNull(vpc)) {
|
||||
throw new CloudRuntimeException(String.format("Failed to find VPC with id: %s", vpcId));
|
||||
}
|
||||
} else {
|
||||
network = networkDao.findById(networkId);
|
||||
if (Objects.isNull(network)) {
|
||||
throw new CloudRuntimeException(String.format("Failed to find network with id: %s", networkId));
|
||||
}
|
||||
}
|
||||
return new Pair<>(vpc, network);
|
||||
}
|
||||
|
||||
private long getResourceId(String resource, VpcVO vpc, NetworkVO network) {
|
||||
switch (resource) {
|
||||
case "domain":
|
||||
return Objects.nonNull(vpc) ? vpc.getDomainId() : network.getDomainId();
|
||||
case "account":
|
||||
return Objects.nonNull(vpc) ? vpc.getAccountId() : network.getAccountId();
|
||||
case "zone":
|
||||
return Objects.nonNull(vpc) ? vpc.getZoneId() : network.getDataCenterId();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,10 @@ import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
|
|||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkMigrationResponder;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.network.PhysicalNetwork;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.guru.GuestNetworkGuru;
|
||||
|
|
@ -57,6 +59,8 @@ public class NetrisGuestNetworkGuru extends GuestNetworkGuru implements Network
|
|||
|
||||
@Inject
|
||||
private NetrisService netrisService;
|
||||
@Inject
|
||||
NetworkModel networkModel;
|
||||
|
||||
public NetrisGuestNetworkGuru() {
|
||||
super();
|
||||
|
|
@ -236,6 +240,18 @@ public class NetrisGuestNetworkGuru extends GuestNetworkGuru implements Network
|
|||
|
||||
if (isNull(network.getVpcId()) && networkOfferingVO.getNetworkMode().equals(NetworkOffering.NetworkMode.NATTED)) {
|
||||
// Netris Natted mode
|
||||
long domainId = domain.getId();
|
||||
long accountId = account.getId();
|
||||
long dataCenterId = zone.getId();
|
||||
long resourceId = network.getId();
|
||||
PublicIpAddress ipAddress = networkModel.getSourceNatIpAddressForGuestNetwork(account, network);
|
||||
String snatIP = ipAddress.getAddress().addr();
|
||||
boolean result = netrisService.createSnatRule(dataCenterId, accountId, domainId, vpc.getName(), vpc.getId(), network.getName(), resourceId, nonNull(network.getVpcId()), vpc.getCidr(), snatIP);
|
||||
if (!result) {
|
||||
String msg = String.format("Could not create Netris Nat Rule for IP %s", snatIP);
|
||||
logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return nicProfile;
|
||||
|
|
@ -277,7 +293,7 @@ public class NetrisGuestNetworkGuru extends GuestNetworkGuru implements Network
|
|||
vpcName = vpc.getName();
|
||||
vpcId = vpc.getId();
|
||||
} else {
|
||||
logger.debug(String.format("Creating a Tier 1 Gateway for the network %s before creating the NSX segment", networkVO.getName()));
|
||||
logger.debug(String.format("Creating IPAM Allocation before creating IPAM Subnet", networkVO.getName()));
|
||||
long networkOfferingId = networkVO.getNetworkOfferingId();
|
||||
NetworkOfferingVO networkOfferingVO = networkOfferingDao.findById(networkOfferingId);
|
||||
boolean isSourceNatSupported = !NetworkOffering.NetworkMode.ROUTED.equals(networkOfferingVO.getNetworkMode()) &&
|
||||
|
|
|
|||
|
|
@ -128,6 +128,15 @@ public class NetrisPublicNetworkGuru extends PublicNetworkGuru {
|
|||
if (!hasNatSupport) {
|
||||
return nic;
|
||||
}
|
||||
|
||||
String snatIP = ipAddress.getAddress().addr();
|
||||
result = netrisService.createSnatRule(dataCenterId, accountId, domainId, vpc.getName(), vpc.getId(), network.getName(), network.getId(), isForVpc, vpc.getCidr(), snatIP);
|
||||
if (!result) {
|
||||
String msg = String.format("Could not create Netris Nat Rule for IP %s", snatIP);
|
||||
logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return nic;
|
||||
|
|
|
|||
|
|
@ -19,25 +19,32 @@ package org.apache.cloudstack.service;
|
|||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.network.SDNProviderNetworkRule;
|
||||
import com.cloud.network.dao.NetrisProviderDao;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.element.NetrisProviderVO;
|
||||
import com.cloud.network.netris.NetrisService;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import io.netris.model.NatPostBody;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.NetrisAnswer;
|
||||
import org.apache.cloudstack.agent.api.NetrisCommand;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.resource.NetrisResourceObjectUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NetrisServiceImpl implements NetrisService, Configurable {
|
||||
|
|
@ -110,4 +117,136 @@ public class NetrisServiceImpl implements NetrisService, Configurable {
|
|||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createSnatRule(long zoneId, long accountId, long domainId, String vpcName, long vpcId, String networkName, long networkId, boolean isForVpc, String vpcCidr, String snatIP) {
|
||||
CreateOrUpdateNetrisNatCommand cmd = new CreateOrUpdateNetrisNatCommand(zoneId, accountId, domainId, vpcName, vpcId, networkName, networkId, isForVpc, vpcCidr);
|
||||
cmd.setNatIp(snatIP);
|
||||
cmd.setNatRuleType("SNAT");
|
||||
String suffix;
|
||||
if (isForVpc) {
|
||||
suffix = String.valueOf(vpcId); // D1-A1-Z1-V25-SNAT
|
||||
} else {
|
||||
suffix = String.valueOf(networkId); // D1-A1-Z1-N25-SNAT
|
||||
}
|
||||
cmd.setProtocol(NatPostBody.ProtocolEnum.ALL.getValue());
|
||||
cmd.setState(NatPostBody.StateEnum.ENABLED.getValue());
|
||||
String snatRuleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.SNAT, suffix);
|
||||
cmd.setNatRuleName(snatRuleName);
|
||||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createPortForwardingRule(long zoneId, long accountId, long domainId, String vpcName, long vpcId, String networkName,
|
||||
Long networkId, boolean isForVpc, String vpcCidr, SDNProviderNetworkRule networkRule) {
|
||||
CreateOrUpdateNetrisNatCommand cmd = new CreateOrUpdateNetrisNatCommand(zoneId, accountId, domainId, vpcName, vpcId,
|
||||
networkName, networkId, isForVpc, vpcCidr);
|
||||
cmd.setProtocol(networkRule.getProtocol().toLowerCase(Locale.ROOT));
|
||||
cmd.setDestinationAddress(networkRule.getPublicIp());
|
||||
cmd.setDestinationPort(networkRule.getPublicPort());
|
||||
cmd.setSourceAddress(networkRule.getVmIp());
|
||||
cmd.setSourcePort(networkRule.getPrivatePort());
|
||||
cmd.setState(NatPostBody.StateEnum.ENABLED.getValue());
|
||||
String ruleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.DNAT,
|
||||
String.valueOf(vpcId), String.format("R%s", networkRule.getRuleId()));
|
||||
cmd.setNatRuleName(ruleName);
|
||||
cmd.setNatRuleType("DNAT");
|
||||
|
||||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deletePortForwardingRule(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, boolean isForVpc, String vpcCidr, SDNProviderNetworkRule networkRule) {
|
||||
DeleteNetrisNatRuleCommand cmd = new DeleteNetrisNatRuleCommand(zoneId, accountId, domainId, vpcName, vpcId, networkName, networkId, isForVpc);
|
||||
String ruleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.DNAT,
|
||||
String.valueOf(vpcId), String.format("R%s", networkRule.getRuleId()));
|
||||
cmd.setNatRuleType("DNAT");
|
||||
cmd.setNatRuleName(ruleName);
|
||||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address) {
|
||||
if (vpc == null || address == null) {
|
||||
return false;
|
||||
}
|
||||
long accountId = vpc.getAccountId();
|
||||
long domainId = vpc.getDomainId();
|
||||
long zoneId = vpc.getZoneId();
|
||||
long vpcId = vpc.getId();
|
||||
String vpcName = vpc.getName();
|
||||
|
||||
logger.debug("Updating the source NAT IP for Netris VPC {} to IP: {}", vpc.getName(), address.getAddress().addr());
|
||||
|
||||
CreateOrUpdateNetrisNatCommand cmd = new CreateOrUpdateNetrisNatCommand(zoneId, accountId, domainId, vpcName, vpcId, null, null, true, address.getAddress().addr());
|
||||
cmd.setNatRuleType("SNAT");
|
||||
String snatRuleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.SNAT, String.valueOf(vpcId));
|
||||
cmd.setNatRuleName(snatRuleName);
|
||||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
if (!answer.getResult()) {
|
||||
logger.error("Could not update the source NAT IP address for VPC {}: {}", vpc.getName(), answer.getDetails());
|
||||
return false;
|
||||
}
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String vpcCidr, String staticNatIp, String vmIp) {
|
||||
String vpcName = null;
|
||||
String networkName = null;
|
||||
Long vpcId = null;
|
||||
Long networkId = null;
|
||||
if (isForVpc) {
|
||||
vpcName = networkResourceName;
|
||||
vpcId = networkResourceId;
|
||||
} else {
|
||||
networkName = networkResourceName;
|
||||
networkId = networkResourceId;
|
||||
}
|
||||
CreateOrUpdateNetrisNatCommand cmd = new CreateOrUpdateNetrisNatCommand(zoneId, accountId, domainId, vpcName, vpcId, networkName, networkId, isForVpc, vpcCidr);
|
||||
cmd.setNatRuleType("STATICNAT");
|
||||
cmd.setNatIp(staticNatIp);
|
||||
cmd.setVmIp(vmIp);
|
||||
String suffix = getResourceSuffix(vpcId, networkId, isForVpc);
|
||||
String dnatRuleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.STATICNAT, suffix);
|
||||
cmd.setNatRuleName(dnatRuleName);
|
||||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String staticNatIp) {
|
||||
String vpcName = null;
|
||||
String networkName = null;
|
||||
Long vpcId = null;
|
||||
Long networkId = null;
|
||||
if (isForVpc) {
|
||||
vpcName = networkResourceName;
|
||||
vpcId = networkResourceId;
|
||||
} else {
|
||||
networkName = networkResourceName;
|
||||
networkId = networkResourceId;
|
||||
}
|
||||
DeleteNetrisNatRuleCommand cmd = new DeleteNetrisNatRuleCommand(zoneId, accountId, domainId, vpcName, vpcId, networkName, networkId, isForVpc);
|
||||
String suffix = getResourceSuffix(vpcId, networkId, isForVpc);
|
||||
String dnatRuleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.STATICNAT, suffix);
|
||||
cmd.setNatRuleName(dnatRuleName);
|
||||
cmd.setNatRuleType("STATICNAT");
|
||||
cmd.setNatIp(staticNatIp);
|
||||
NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
|
||||
return answer.getResult();
|
||||
}
|
||||
|
||||
private String getResourceSuffix(Long vpcId, Long networkId, boolean isForVpc) {
|
||||
String suffix;
|
||||
if (isForVpc) {
|
||||
suffix = String.valueOf(vpcId); // D1-A1-Z1-V25-STATICNAT or D1-A1-Z1-V25-SNAT
|
||||
} else {
|
||||
suffix = String.valueOf(networkId); // D1-A1-Z1-N25-STATICNAT or D1-A1-Z1-N25-SNAT
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.cloudstack.resource;
|
||||
|
||||
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
|
@ -54,4 +55,15 @@ public class NetrisResourceObjectUtilsTest {
|
|||
String expectedNetrisVpcName = String.format("D%s-A%s-Z%s-V%s-%s", domainId, accountId, zoneId, vpcId, vpcName);
|
||||
Assert.assertEquals(expectedNetrisVpcName, netrisVpcName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuffixesForDNAT() {
|
||||
CreateOrUpdateNetrisNatCommand cmd = new CreateOrUpdateNetrisNatCommand(zoneId, accountId, domainId, vpcName, vpcId, vpcName, null, true, vpcCidr);
|
||||
cmd.setNatRuleType("DNAT");
|
||||
long ruleId = 23L;
|
||||
String ruleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.DNAT,
|
||||
String.valueOf(vpcId), String.format("R%s", ruleId));
|
||||
String expectedNetrisRuleName = String.format("D%s-A%s-Z%s-V%s-DNAT-R%s", domainId, accountId, zoneId, vpcId, ruleId);
|
||||
Assert.assertEquals(expectedNetrisRuleName, ruleName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,151 +16,18 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.resource;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.SDNProviderNetworkRule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NsxNetworkRule {
|
||||
public class NsxNetworkRule extends SDNProviderNetworkRule {
|
||||
|
||||
public enum NsxRuleAction {
|
||||
ALLOW, DROP
|
||||
}
|
||||
|
||||
private long domainId;
|
||||
private long accountId;
|
||||
private long zoneId;
|
||||
private Long networkResourceId;
|
||||
private String networkResourceName;
|
||||
private boolean isVpcResource;
|
||||
private long vmId;
|
||||
private long ruleId;
|
||||
private String publicIp;
|
||||
private String vmIp;
|
||||
private String publicPort;
|
||||
private String privatePort;
|
||||
private String protocol;
|
||||
private String algorithm;
|
||||
private List<NsxLoadBalancerMember> memberList;
|
||||
private NsxRuleAction aclAction;
|
||||
private List<String> sourceCidrList;
|
||||
private List<String> destinationCidrList;
|
||||
private Integer icmpCode;
|
||||
|
||||
private Integer icmpType;
|
||||
private String trafficType;
|
||||
private Network.Service service;
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setDomainId(long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(long zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public Long getNetworkResourceId() {
|
||||
return networkResourceId;
|
||||
}
|
||||
|
||||
public void setNetworkResourceId(Long networkResourceId) {
|
||||
this.networkResourceId = networkResourceId;
|
||||
}
|
||||
|
||||
public String getNetworkResourceName() {
|
||||
return networkResourceName;
|
||||
}
|
||||
|
||||
public void setNetworkResourceName(String networkResourceName) {
|
||||
this.networkResourceName = networkResourceName;
|
||||
}
|
||||
|
||||
public boolean isVpcResource() {
|
||||
return isVpcResource;
|
||||
}
|
||||
|
||||
public void setVpcResource(boolean vpcResource) {
|
||||
isVpcResource = vpcResource;
|
||||
}
|
||||
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
public long getRuleId() {
|
||||
return ruleId;
|
||||
}
|
||||
|
||||
public void setRuleId(long ruleId) {
|
||||
this.ruleId = ruleId;
|
||||
}
|
||||
|
||||
public String getPublicIp() {
|
||||
return publicIp;
|
||||
}
|
||||
|
||||
public void setPublicIp(String publicIp) {
|
||||
this.publicIp = publicIp;
|
||||
}
|
||||
|
||||
public String getVmIp() {
|
||||
return vmIp;
|
||||
}
|
||||
|
||||
public void setVmIp(String vmIp) {
|
||||
this.vmIp = vmIp;
|
||||
}
|
||||
|
||||
public String getPublicPort() {
|
||||
return publicPort;
|
||||
}
|
||||
|
||||
public void setPublicPort(String publicPort) {
|
||||
this.publicPort = publicPort;
|
||||
}
|
||||
|
||||
public String getPrivatePort() {
|
||||
return privatePort;
|
||||
}
|
||||
|
||||
public void setPrivatePort(String privatePort) {
|
||||
this.privatePort = privatePort;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void setAlgorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public List<NsxLoadBalancerMember> getMemberList() {
|
||||
return memberList;
|
||||
|
|
@ -177,221 +44,4 @@ public class NsxNetworkRule {
|
|||
public void setAclAction(NsxRuleAction aclAction) {
|
||||
this.aclAction = aclAction;
|
||||
}
|
||||
|
||||
public Network.Service getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public void setService(Network.Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public Integer getIcmpCode() {
|
||||
return icmpCode;
|
||||
}
|
||||
|
||||
public void setIcmpCode(Integer icmpCode) {
|
||||
this.icmpCode = icmpCode;
|
||||
}
|
||||
|
||||
public Integer getIcmpType() {
|
||||
return icmpType;
|
||||
}
|
||||
|
||||
public void setIcmpType(Integer icmpType) {
|
||||
this.icmpType = icmpType;
|
||||
}
|
||||
|
||||
public List<String> getSourceCidrList() {
|
||||
return sourceCidrList;
|
||||
}
|
||||
|
||||
public void setSourceCidrList(List<String> sourceCidrList) {
|
||||
this.sourceCidrList = sourceCidrList;
|
||||
}
|
||||
|
||||
public List<String> getDestinationCidrList() {
|
||||
return destinationCidrList;
|
||||
}
|
||||
|
||||
public void setDestinationCidrList(List<String> destinationCidrList) {
|
||||
this.destinationCidrList = destinationCidrList;
|
||||
}
|
||||
|
||||
public String getTrafficType() {
|
||||
return trafficType;
|
||||
}
|
||||
|
||||
public void setTrafficType(String trafficType) {
|
||||
this.trafficType = trafficType;
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private long domainId;
|
||||
private long accountId;
|
||||
private long zoneId;
|
||||
private Long networkResourceId;
|
||||
private String networkResourceName;
|
||||
private boolean isVpcResource;
|
||||
private long vmId;
|
||||
|
||||
private long ruleId;
|
||||
private String publicIp;
|
||||
private String vmIp;
|
||||
private String publicPort;
|
||||
private String privatePort;
|
||||
private String protocol;
|
||||
private String algorithm;
|
||||
private List<NsxLoadBalancerMember> memberList;
|
||||
private NsxRuleAction aclAction;
|
||||
private List<String> sourceCidrList;
|
||||
private List<String> destinationidrList;
|
||||
private String trafficType;
|
||||
private Integer icmpType;
|
||||
private Integer icmpCode;
|
||||
private Network.Service service;
|
||||
|
||||
public Builder() {
|
||||
// Default constructor
|
||||
}
|
||||
|
||||
public Builder setDomainId(long domainId) {
|
||||
this.domainId = domainId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAccountId(long accountId) {
|
||||
this.accountId = accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setZoneId(long zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setNetworkResourceId(Long networkResourceId) {
|
||||
this.networkResourceId = networkResourceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setNetworkResourceName(String networkResourceName) {
|
||||
this.networkResourceName = networkResourceName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setVpcResource(boolean isVpcResource) {
|
||||
this.isVpcResource = isVpcResource;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder setVmId(long vmId) {
|
||||
this.vmId = vmId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRuleId(long ruleId) {
|
||||
this.ruleId = ruleId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPublicIp(String publicIp) {
|
||||
this.publicIp = publicIp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setVmIp(String vmIp) {
|
||||
this.vmIp = vmIp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPublicPort(String publicPort) {
|
||||
this.publicPort = publicPort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPrivatePort(String privatePort) {
|
||||
this.privatePort = privatePort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAlgorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMemberList(List<NsxLoadBalancerMember> memberList) {
|
||||
this.memberList = memberList;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder setAclAction(NsxRuleAction aclAction) {
|
||||
this.aclAction = aclAction;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTrafficType(String trafficType) {
|
||||
this.trafficType = trafficType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setIcmpType(Integer icmpType) {
|
||||
this.icmpType = icmpType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setIcmpCode(Integer icmpCode) {
|
||||
this.icmpCode = icmpCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSourceCidrList(List<String> sourceCidrList) {
|
||||
this.sourceCidrList = sourceCidrList;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDestinationCidrList(List<String> destinationCidrList) {
|
||||
this.destinationidrList = destinationCidrList;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setService(Network.Service service) {
|
||||
this.service = service;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NsxNetworkRule build() {
|
||||
NsxNetworkRule rule = new NsxNetworkRule();
|
||||
rule.setDomainId(this.domainId);
|
||||
rule.setAccountId(this.accountId);
|
||||
rule.setZoneId(this.zoneId);
|
||||
rule.setNetworkResourceId(this.networkResourceId);
|
||||
rule.setNetworkResourceName(this.networkResourceName);
|
||||
rule.setVpcResource(this.isVpcResource);
|
||||
rule.setVmId(this.vmId);
|
||||
rule.setVmIp(this.vmIp);
|
||||
rule.setPublicIp(this.publicIp);
|
||||
rule.setPublicPort(this.publicPort);
|
||||
rule.setPrivatePort(this.privatePort);
|
||||
rule.setProtocol(this.protocol);
|
||||
rule.setRuleId(this.ruleId);
|
||||
rule.setAlgorithm(this.algorithm);
|
||||
rule.setMemberList(this.memberList);
|
||||
rule.setAclAction(this.aclAction);
|
||||
rule.setIcmpType(this.icmpType);
|
||||
rule.setIcmpCode(this.icmpCode);
|
||||
rule.setSourceCidrList(this.sourceCidrList);
|
||||
rule.setDestinationCidrList(this.destinationidrList);
|
||||
rule.setTrafficType(this.trafficType);
|
||||
rule.setService(service);
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalanc
|
|||
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
|
||||
import org.apache.cloudstack.resource.NsxLoadBalancerMember;
|
||||
import org.apache.cloudstack.resource.NsxNetworkRule;
|
||||
import org.apache.cloudstack.resource.NsxOpObject;
|
||||
import com.cloud.network.SDNProviderOpObject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.cloudstack.resourcedetail.FirewallRuleDetailVO;
|
||||
|
|
@ -553,26 +553,26 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
if (vm == null && rule.getState() != FirewallRule.State.Revoke) {
|
||||
continue;
|
||||
}
|
||||
NsxOpObject nsxObject = getNsxOpObject(network);
|
||||
String publicPort = getPublicPortRange(rule);
|
||||
SDNProviderOpObject nsxObject = getNsxOpObject(network);
|
||||
String publicPort = PortForwardingServiceProvider.getPublicPortRange(rule);
|
||||
|
||||
String privatePort = getPrivatePFPortRange(rule);
|
||||
String privatePort = PortForwardingServiceProvider.getPrivatePFPortRange(rule);
|
||||
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule();
|
||||
networkRule.setDomainId(nsxObject.getDomainId());
|
||||
networkRule.setAccountId(nsxObject.getAccountId());
|
||||
networkRule.setZoneId(nsxObject.getZoneId());
|
||||
networkRule.setNetworkResourceId(nsxObject.getNetworkResourceId());
|
||||
networkRule.setNetworkResourceName(nsxObject.getNetworkResourceName());
|
||||
networkRule.setVpcResource(nsxObject.isVpcResource());
|
||||
networkRule.setVmId(Objects.nonNull(vm) ? vm.getId() : 0);
|
||||
networkRule.setVmIp(Objects.nonNull(vm) ? vm.getPrivateIpAddress() : null);
|
||||
networkRule.setPublicIp(publicIp.getAddress().addr());
|
||||
networkRule.setPrivatePort(privatePort);
|
||||
networkRule.setPublicPort(publicPort);
|
||||
networkRule.setRuleId(rule.getId());
|
||||
networkRule.setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT));
|
||||
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
|
||||
.setDomainId(nsxObject.getDomainId())
|
||||
.setAccountId(nsxObject.getAccountId())
|
||||
.setZoneId(nsxObject.getZoneId())
|
||||
.setNetworkResourceId(nsxObject.getNetworkResourceId())
|
||||
.setNetworkResourceName(nsxObject.getNetworkResourceName())
|
||||
.setVpcResource(nsxObject.isVpcResource())
|
||||
.setVmId(Objects.nonNull(vm) ? vm.getId() : 0)
|
||||
.setVmIp(Objects.nonNull(vm) ? vm.getPrivateIpAddress() : null)
|
||||
.setPublicIp(publicIp.getAddress().addr())
|
||||
.setPrivatePort(privatePort)
|
||||
.setPublicPort(publicPort)
|
||||
.setRuleId(rule.getId())
|
||||
.setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT))
|
||||
.build();
|
||||
FirewallRuleDetailVO ruleDetail = firewallRuleDetailsDao.findDetail(rule.getId(), ApiConstants.FOR_NSX);
|
||||
if (Arrays.asList(FirewallRule.State.Add, FirewallRule.State.Active).contains(rule.getState())) {
|
||||
if ((ruleDetail == null && FirewallRule.State.Add == rule.getState()) || (ruleDetail != null && !ruleDetail.getValue().equalsIgnoreCase("true"))) {
|
||||
|
|
@ -634,30 +634,6 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
return new Pair<>(vpc, network);
|
||||
}
|
||||
|
||||
private static String getPublicPortRange(PortForwardingRule rule) {
|
||||
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
|
||||
String.valueOf(rule.getSourcePortStart()) :
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
private static String getPrivatePFPortRange(PortForwardingRule rule) {
|
||||
return rule.getDestinationPortStart() == rule.getDestinationPortEnd() ?
|
||||
String.valueOf(rule.getDestinationPortStart()) :
|
||||
String.valueOf(rule.getDestinationPortStart()).concat("-").concat(String.valueOf(rule.getDestinationPortEnd()));
|
||||
}
|
||||
|
||||
private static String getPrivatePortRange(FirewallRule rule) {
|
||||
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
|
||||
String.valueOf(rule.getSourcePortStart()) :
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
private static String getPrivatePortRangeForACLRule(NetworkACLItem rule) {
|
||||
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
|
||||
String.valueOf(rule.getSourcePortStart()) :
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
private long getResourceId(String resource, VpcVO vpc, NetworkVO network) {
|
||||
switch (resource) {
|
||||
case "domain":
|
||||
|
|
@ -671,7 +647,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
}
|
||||
}
|
||||
|
||||
private NsxOpObject getNsxOpObject(Network network) {
|
||||
private SDNProviderOpObject getNsxOpObject(Network network) {
|
||||
Pair<VpcVO, NetworkVO> vpcOrNetwork = getVpcOrNetwork(network.getVpcId(), network.getId());
|
||||
VpcVO vpc = vpcOrNetwork.first();
|
||||
NetworkVO networkVO = vpcOrNetwork.second();
|
||||
|
|
@ -679,7 +655,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
long accountId = getResourceId("account", vpc, networkVO);
|
||||
long zoneId = getResourceId("zone", vpc, networkVO);
|
||||
|
||||
return new NsxOpObject.Builder()
|
||||
return new SDNProviderOpObject.Builder()
|
||||
.vpcVO(vpc)
|
||||
.networkVO(networkVO)
|
||||
.domainId(domainId)
|
||||
|
|
@ -694,25 +670,24 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
for (LoadBalancingRule loadBalancingRule : rules) {
|
||||
IPAddressVO publicIp = ipAddressDao.findByIpAndDcId(network.getDataCenterId(),
|
||||
loadBalancingRule.getSourceIp().addr());
|
||||
NsxOpObject nsxObject = getNsxOpObject(network);
|
||||
SDNProviderOpObject nsxObject = getNsxOpObject(network);
|
||||
|
||||
List<NsxLoadBalancerMember> lbMembers = getLoadBalancerMembers(loadBalancingRule);
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
|
||||
.setDomainId(nsxObject.getDomainId())
|
||||
.setAccountId(nsxObject.getAccountId())
|
||||
.setZoneId(nsxObject.getZoneId())
|
||||
.setNetworkResourceId(nsxObject.getNetworkResourceId())
|
||||
.setNetworkResourceName(nsxObject.getNetworkResourceName())
|
||||
.setVpcResource(nsxObject.isVpcResource())
|
||||
.setMemberList(lbMembers)
|
||||
.setPublicIp(LoadBalancerContainer.Scheme.Public == loadBalancingRule.getScheme() ?
|
||||
publicIp.getAddress().addr() : loadBalancingRule.getSourceIp().addr())
|
||||
.setPublicPort(String.valueOf(loadBalancingRule.getSourcePortStart()))
|
||||
.setPrivatePort(String.valueOf(loadBalancingRule.getDefaultPortStart()))
|
||||
.setRuleId(loadBalancingRule.getId())
|
||||
.setProtocol(loadBalancingRule.getLbProtocol().toUpperCase(Locale.ROOT))
|
||||
.setAlgorithm(loadBalancingRule.getAlgorithm())
|
||||
.build();
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule();
|
||||
networkRule.setDomainId(nsxObject.getDomainId());
|
||||
networkRule.setAccountId(nsxObject.getAccountId());
|
||||
networkRule.setZoneId(nsxObject.getZoneId());
|
||||
networkRule.setNetworkResourceId(nsxObject.getNetworkResourceId());
|
||||
networkRule.setNetworkResourceName(nsxObject.getNetworkResourceName());
|
||||
networkRule.setVpcResource(nsxObject.isVpcResource());
|
||||
networkRule.setPublicIp(LoadBalancerContainer.Scheme.Public == loadBalancingRule.getScheme() ?
|
||||
publicIp.getAddress().addr() : loadBalancingRule.getSourceIp().addr());
|
||||
networkRule.setPublicPort(String.valueOf(loadBalancingRule.getSourcePortStart()));
|
||||
networkRule.setPrivatePort(String.valueOf(loadBalancingRule.getDefaultPortStart()));
|
||||
networkRule.setRuleId(loadBalancingRule.getId());
|
||||
networkRule.setProtocol(loadBalancingRule.getLbProtocol().toUpperCase(Locale.ROOT));
|
||||
networkRule.setAlgorithm(loadBalancingRule.getAlgorithm());
|
||||
networkRule.setMemberList(lbMembers);
|
||||
if (Arrays.asList(FirewallRule.State.Add, FirewallRule.State.Active).contains(loadBalancingRule.getState())) {
|
||||
result &= nsxService.createLbRule(networkRule);
|
||||
} else if (loadBalancingRule.getState() == FirewallRule.State.Revoke) {
|
||||
|
|
@ -757,7 +732,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
List<NsxNetworkRule> nsxDelNetworkRules = new ArrayList<>();
|
||||
boolean success = true;
|
||||
for (NetworkACLItem rule : rules) {
|
||||
String privatePort = getPrivatePortRangeForACLRule(rule);
|
||||
String privatePort = PortForwardingServiceProvider.getPrivatePortRangeForACLRule(rule);
|
||||
NsxNetworkRule networkRule = getNsxNetworkRuleForAcl(rule, privatePort);
|
||||
if (Arrays.asList(NetworkACLItem.State.Active, NetworkACLItem.State.Add).contains(rule.getState())) {
|
||||
success = success && nsxService.addFirewallRules(network, List.of(networkRule));
|
||||
|
|
@ -779,7 +754,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
public boolean reorderAclRules(Vpc vpc, List<? extends Network> networks, List<? extends NetworkACLItem> networkACLItems) {
|
||||
List<NsxNetworkRule> aclRulesList = new ArrayList<>();
|
||||
for (NetworkACLItem rule : networkACLItems) {
|
||||
String privatePort = getPrivatePortRangeForACLRule(rule);
|
||||
String privatePort = PortForwardingServiceProvider.getPrivatePortRangeForACLRule(rule);
|
||||
aclRulesList.add(getNsxNetworkRuleForAcl(rule, privatePort));
|
||||
}
|
||||
for (Network network: networks) {
|
||||
|
|
@ -795,18 +770,18 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
}
|
||||
|
||||
private NsxNetworkRule getNsxNetworkRuleForAcl(NetworkACLItem rule, String privatePort) {
|
||||
return new NsxNetworkRule.Builder()
|
||||
.setRuleId(rule.getId())
|
||||
.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ? transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
|
||||
.setAclAction(transformActionValue(rule.getAction()))
|
||||
.setTrafficType(rule.getTrafficType().toString())
|
||||
.setProtocol(rule.getProtocol().toUpperCase())
|
||||
.setPublicPort(String.valueOf(rule.getSourcePortStart()))
|
||||
.setPrivatePort(privatePort)
|
||||
.setIcmpCode(rule.getIcmpCode())
|
||||
.setIcmpType(rule.getIcmpType())
|
||||
.setService(Network.Service.NetworkACL)
|
||||
.build();
|
||||
NsxNetworkRule nsxNetworkRule = new NsxNetworkRule();
|
||||
nsxNetworkRule.setRuleId(rule.getId());
|
||||
nsxNetworkRule.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ? transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"));
|
||||
nsxNetworkRule.setTrafficType(rule.getTrafficType().toString());
|
||||
nsxNetworkRule.setProtocol(rule.getProtocol().toUpperCase());
|
||||
nsxNetworkRule.setPublicPort(String.valueOf(rule.getSourcePortStart()));
|
||||
nsxNetworkRule.setPrivatePort(privatePort);
|
||||
nsxNetworkRule.setIcmpCode(rule.getIcmpCode());
|
||||
nsxNetworkRule.setIcmpType(rule.getIcmpType());
|
||||
nsxNetworkRule.setService(Network.Service.NetworkACL);
|
||||
nsxNetworkRule.setAclAction(transformActionValue(rule.getAction()));
|
||||
return nsxNetworkRule;
|
||||
}
|
||||
@Override
|
||||
public boolean applyFWRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
|
||||
|
|
@ -817,20 +792,19 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
List<NsxNetworkRule> nsxAddNetworkRules = new ArrayList<>();
|
||||
List<NsxNetworkRule> nsxDelNetworkRules = new ArrayList<>();
|
||||
for (FirewallRule rule : rules) {
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
|
||||
.setRuleId(rule.getId())
|
||||
.setAclAction(NsxNetworkRule.NsxRuleAction.ALLOW)
|
||||
.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ?
|
||||
transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
|
||||
.setDestinationCidrList(Objects.nonNull(rule.getDestinationCidrList()) ?
|
||||
transformCidrListValues(rule.getDestinationCidrList()) : List.of("ANY"))
|
||||
.setIcmpCode(rule.getIcmpCode())
|
||||
.setIcmpType(rule.getIcmpType())
|
||||
.setPrivatePort(getPrivatePortRange(rule))
|
||||
.setTrafficType(rule.getTrafficType().toString())
|
||||
.setService(Network.Service.Firewall)
|
||||
.setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT))
|
||||
.build();
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule();
|
||||
networkRule.setRuleId(rule.getId());
|
||||
networkRule.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ?
|
||||
transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"));
|
||||
networkRule.setDestinationCidrList(Objects.nonNull(rule.getDestinationCidrList()) ?
|
||||
transformCidrListValues(rule.getDestinationCidrList()) : List.of("ANY"));
|
||||
networkRule.setIcmpCode(rule.getIcmpCode());
|
||||
networkRule.setIcmpType(rule.getIcmpType());
|
||||
networkRule.setPrivatePort(PortForwardingServiceProvider.getPrivatePortRange(rule));
|
||||
networkRule.setTrafficType(rule.getTrafficType().toString());
|
||||
networkRule.setService(Network.Service.Firewall);
|
||||
networkRule.setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT));
|
||||
networkRule.setAclAction(NsxNetworkRule.NsxRuleAction.ALLOW);
|
||||
if (rule.getState() == FirewallRule.State.Add) {
|
||||
nsxAddNetworkRules.add(networkRule);
|
||||
} else if (rule.getState() == FirewallRule.State.Revoke) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import com.cloud.network.dao.NetworkDao;
|
|||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.dao.PhysicalNetworkDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.element.PortForwardingServiceProvider;
|
||||
import com.cloud.network.lb.LoadBalancingRule;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
|
|
@ -72,7 +73,6 @@ import org.mockito.junit.MockitoJUnitRunner;
|
|||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
|
@ -307,84 +307,60 @@ public class NsxElementTest {
|
|||
assertNotNull(vpcNetworkPair.second());
|
||||
}
|
||||
|
||||
private Method getPublicPortRangeMethod() throws NoSuchMethodException {
|
||||
Method method = NsxElement.class.getDeclaredMethod("getPublicPortRange", PortForwardingRule.class);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
}
|
||||
|
||||
private Method getPrivatePFPortRangeMethod() throws NoSuchMethodException {
|
||||
Method method = NsxElement.class.getDeclaredMethod("getPrivatePFPortRange", PortForwardingRule.class);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
}
|
||||
|
||||
private Method getPrivatePortRangeMethod() throws NoSuchMethodException {
|
||||
Method method = NsxElement.class.getDeclaredMethod("getPrivatePortRange", FirewallRule.class);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
}
|
||||
|
||||
private Method getPrivatePortRangeForACLRuleMethod() throws NoSuchMethodException {
|
||||
Method method = NsxElement.class.getDeclaredMethod("getPrivatePortRangeForACLRule", NetworkACLItem.class);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPublicPortRangeWhenStartAndEndPortNumbersAreDifferent() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
PortForwardingRule rule = new PortForwardingRuleVO("1", 11L, 80, 90, new Ip("172.30.10.11"), 8080, 8090, "tcp", 12L,
|
||||
5L, 2L, 15L);
|
||||
assertEquals("80-90", getPublicPortRangeMethod().invoke(null, rule));
|
||||
assertEquals("80-90", PortForwardingServiceProvider.getPublicPortRange(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPublicPortRangeWhenStartAndEndPortNumbersAreSame() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
PortForwardingRule rule = new PortForwardingRuleVO("1", 11L, 80, 80, new Ip("172.30.10.11"), 8080, 8080, "tcp", 12L,
|
||||
5L, 2L, 15L);
|
||||
assertEquals("80", getPublicPortRangeMethod().invoke(null, rule));
|
||||
assertEquals("80", PortForwardingServiceProvider.getPublicPortRange(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrivatePFPortRangeWhenStartAndEndPortNumbersAreDifferent() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
PortForwardingRule rule = new PortForwardingRuleVO("1", 11L, 80, 90, new Ip("172.30.10.11"), 8080, 8090, "tcp", 12L,
|
||||
5L, 2L, 15L);
|
||||
assertEquals("8080-8090", getPrivatePFPortRangeMethod().invoke(null, rule));
|
||||
assertEquals("8080-8090", PortForwardingServiceProvider.getPrivatePFPortRange(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrivatePFPortRangeWhenStartAndEndPortNumbersAreSame() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
PortForwardingRule rule = new PortForwardingRuleVO("1", 11L, 80, 80, new Ip("172.30.10.11"), 8080, 8080, "tcp", 12L,
|
||||
5L, 2L, 15L);
|
||||
assertEquals("8080", getPrivatePFPortRangeMethod().invoke(null, rule));
|
||||
assertEquals("8080", PortForwardingServiceProvider.getPrivatePFPortRange(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrivatePortRangeWhenStartAndEndPortNumbersAreSame() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
FirewallRuleVO rule = new FirewallRuleVO("1", 11L, 80, 80, "tcp", 23L, 5L, 2L,
|
||||
FirewallRule.Purpose.Firewall, List.of("172.30.10.0/24"), null, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.User);
|
||||
assertEquals("80", getPrivatePortRangeMethod().invoke(null, rule));
|
||||
assertEquals("80", PortForwardingServiceProvider.getPrivatePortRange(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrivatePortRangeWhenStartAndEndPortNumbersAreDifferent() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
FirewallRuleVO rule = new FirewallRuleVO("1", 11L, 80, 90, "tcp", 23L, 5L, 2L,
|
||||
FirewallRule.Purpose.Firewall, List.of("172.30.10.0/24"), null, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.User);
|
||||
assertEquals("80-90", getPrivatePortRangeMethod().invoke(null, rule));
|
||||
assertEquals("80-90", PortForwardingServiceProvider.getPrivatePortRange(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrivatePortRangeForACLWhenStartAndEndPortNumbersAreSame() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
NetworkACLItem rule = new NetworkACLItemVO(80, 80, "udp", 10L, List.of("172.30.10.0/24"), null, null, NetworkACLItem.TrafficType.Ingress, NetworkACLItem.Action.Allow,
|
||||
2, null);
|
||||
assertEquals("80", getPrivatePortRangeForACLRuleMethod().invoke(null, rule));
|
||||
assertEquals("80", PortForwardingServiceProvider.getPrivatePortRangeForACLRule(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrivatePortRangeForACLWhenStartAndEndPortNumbersAreDifferent() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
NetworkACLItem rule = new NetworkACLItemVO(80, 90, "udp", 10L, List.of("172.30.10.0/24"), null, null, NetworkACLItem.TrafficType.Ingress, NetworkACLItem.Action.Allow,
|
||||
2, null);
|
||||
assertEquals("80-90", getPrivatePortRangeForACLRuleMethod().invoke(null, rule));
|
||||
assertEquals("80-90", PortForwardingServiceProvider.getPrivatePortRangeForACLRule(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@
|
|||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.resource;
|
||||
package com.cloud.network;
|
||||
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class NsxOpObject {
|
||||
public class SDNProviderOpObject {
|
||||
VpcVO vpcVO;
|
||||
NetworkVO networkVO;
|
||||
long accountId;
|
||||
|
|
@ -116,8 +116,8 @@ public class NsxOpObject {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NsxOpObject build() {
|
||||
NsxOpObject object = new NsxOpObject();
|
||||
public SDNProviderOpObject build() {
|
||||
SDNProviderOpObject object = new SDNProviderOpObject();
|
||||
object.setVpcVO(this.vpcVO);
|
||||
object.setNetworkVO(this.networkVO);
|
||||
object.setDomainId(this.domainId);
|
||||
|
|
@ -454,6 +454,24 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
State.Enabled, null, false, false, false, NetworkOffering.NetworkMode.ROUTED, null, false);
|
||||
|
||||
}
|
||||
|
||||
// configure default vpc offering with Netris as network service provider in NAT mode
|
||||
if (_vpcOffDao.findByUniqueName(VpcOffering.DEFAULT_VPC_NAT_NETRIS_OFFERING_NAME) == null) {
|
||||
logger.debug(String.format("Creating default VPC offering for Netris network service provider %s in NAT mode", VpcOffering.DEFAULT_VPC_NAT_NETRIS_OFFERING_NAME));
|
||||
final Map<Service, Set<Provider>> svcProviderMap = new HashMap<>();
|
||||
final Set<Provider> defaultProviders = Set.of(Provider.Netris);
|
||||
for (final Service svc : getSupportedServices()) {
|
||||
if (List.of(Service.UserData, Service.Dhcp, Service.Dns).contains(svc)) {
|
||||
final Set<Provider> userDataProvider = Set.of(Provider.VPCVirtualRouter);
|
||||
svcProviderMap.put(svc, userDataProvider);
|
||||
} else {
|
||||
svcProviderMap.put(svc, defaultProviders);
|
||||
}
|
||||
}
|
||||
createVpcOffering(VpcOffering.DEFAULT_VPC_NAT_NETRIS_OFFERING_NAME, VpcOffering.DEFAULT_VPC_NAT_NETRIS_OFFERING_NAME, svcProviderMap, false,
|
||||
State.Enabled, null, false, false, false, NetworkOffering.NetworkMode.NATTED, null, false);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1220,6 +1220,10 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
|
|||
// Offering #14 - network offering for Netris provider for VPCs - ROUTED mode
|
||||
createAndPersistDefaultProviderOffering(NetworkOffering.DEFAULT_ROUTED_NETRIS_OFFERING_FOR_VPC, "Offering for Netris enabled networks on VPCs - ROUTED mode",
|
||||
NetworkOffering.NetworkMode.ROUTED, true, true, Provider.Netris);
|
||||
|
||||
// Offering #15 - network offering for Netris provider for VPCs - NATTED mode
|
||||
createAndPersistDefaultProviderOffering(NetworkOffering.DEFAULT_NAT_NETRIS_OFFERING_FOR_VPC, "Offering for Netris enabled networks on VPCs - NAT mode",
|
||||
NetworkOffering.NetworkMode.NATTED, true, true, Provider.Netris);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue