Skip to content

Commit 2e21060

Browse files
rajesh-battalamurali-reddy
authored andcommitted
CLOUDSTACK-869 nTier Apps 2.0 : Support NetScalar as external LB provider
1 parent 2e1877a commit 2e21060

8 files changed

Lines changed: 406 additions & 23 deletions

File tree

api/src/com/cloud/network/vpc/VpcOffering.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public enum State {
2626
}
2727

2828
public static final String defaultVPCOfferingName = "Default VPC offering";
29+
public static final String defaultVPCNSOfferingName = "Default VPC offering with Netscaler";
2930

3031
/**
3132
*

plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
import com.cloud.network.rules.LbStickinessMethod;
6262
import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
6363
import com.cloud.network.rules.StaticNat;
64+
import com.cloud.network.vpc.PrivateGateway;
65+
import com.cloud.network.vpc.StaticRouteProfile;
66+
import com.cloud.network.vpc.Vpc;
6467
import com.cloud.offering.NetworkOffering;
6568
import com.cloud.utils.NumbersUtil;
6669
import com.cloud.utils.db.DB;
@@ -85,7 +88,7 @@
8588
@Local(value = {NetworkElement.class, StaticNatServiceProvider.class, LoadBalancingServiceProvider.class, GslbServiceProvider.class})
8689
public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider,
8790
NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager, IpDeployer, StaticNatServiceProvider,
88-
GslbServiceProvider {
91+
GslbServiceProvider, VpcProvider {
8992

9093
private static final Logger s_logger = Logger.getLogger(NetscalerElement.class);
9194
public static final AutoScaleCounterType AutoScaleCounterSnmp = new AutoScaleCounterType("snmp");
@@ -957,4 +960,33 @@ public String getZoneGslbProviderPrivateIp(long zoneId) {
957960
}
958961
return null;
959962
}
963+
964+
@Override
965+
public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context)
966+
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
967+
return true;
968+
}
969+
970+
@Override
971+
public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException,
972+
ResourceUnavailableException {
973+
return true;
974+
}
975+
976+
@Override
977+
public boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException,
978+
ResourceUnavailableException {
979+
return true;
980+
}
981+
982+
@Override
983+
public boolean deletePrivateGateway(PrivateGateway privateGateway) throws ConcurrentOperationException,
984+
ResourceUnavailableException {
985+
return true;
986+
}
987+
988+
@Override
989+
public boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes) throws ResourceUnavailableException {
990+
return true;
991+
}
960992
}

server/pom.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@
154154
<exclude>com/cloud/network/vpn/RemoteAccessVpnTest.java</exclude>
155155
<exclude>com/cloud/network/security/SecurityGroupManagerImpl2Test.java</exclude>
156156
<exclude>com/cloud/network/security/SecurityGroupManagerImpl2Test.java</exclude>
157-
<exclude>com/cloud/vpc/*</exclude>
157+
<exclude>com/cloud/vpc/VpcTestConfiguration.java</exclude>
158+
<exclude>com/cloud/vpc/VpcApiUnitTest.java</exclude>
159+
<exclude>com/cloud/vpc/VpcManagerTest.java</exclude>
158160
</excludes>
159161
</configuration>
160162
</plugin>

server/src/com/cloud/network/NetworkServiceImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,11 @@ && areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
11211121
// validate if CIDR specified overlaps with any of the CIDR's allocated for isolated networks and shared networks in the zone
11221122
checkSharedNetworkCidrOverlap(zoneId, pNtwk.getId(), cidr);
11231123
} else {
1124-
throw new InvalidParameterValueException("Cannot specify CIDR when using network offering with external devices!");
1124+
// if the guest network is for the VPC, if any External Provider are supported in VPC
1125+
// cidr will not be null as it is generated from the super cidr of vpc.
1126+
// if cidr is not null and network is not part of vpc then throw the exception
1127+
if (vpcId == null)
1128+
throw new InvalidParameterValueException("Cannot specify CIDR when using network offering with external devices!");
11251129
}
11261130
}
11271131

server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public Network implement(Network config, NetworkOffering offering, DeployDestina
118118
if (Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key()))) {
119119
return null;
120120
}
121-
121+
122122
if (!_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
123123
return super.implement(config, offering, dest, context);
124124
}
@@ -145,25 +145,31 @@ public Network implement(Network config, NetworkOffering offering, DeployDestina
145145
implemented.setBroadcastUri(config.getBroadcastUri());
146146
}
147147

148-
// Determine the offset from the lowest vlan tag
149-
int offset = getVlanOffset(config.getPhysicalNetworkId(), vlanTag);
150-
151148
// Determine the new gateway and CIDR
152149
String[] oldCidr = config.getCidr().split("/");
153150
String oldCidrAddress = oldCidr[0];
154-
int cidrSize = getGloballyConfiguredCidrSize();
155-
156-
// If the offset has more bits than there is room for, return null
157-
long bitsInOffset = 32 - Integer.numberOfLeadingZeros(offset);
158-
if (bitsInOffset > (cidrSize - 8)) {
159-
throw new CloudRuntimeException("The offset " + offset + " needs " + bitsInOffset + " bits, but only have " + (cidrSize - 8) + " bits to work with.");
151+
int cidrSize = Integer.parseInt(oldCidr[1]);
152+
long newCidrAddress = (NetUtils.ip2Long(oldCidrAddress));
153+
// if the implementing network is for vpc, no need to generate newcidr, use the cidr that came from super cidr
154+
if (config.getVpcId() != null) {
155+
implemented.setGateway(config.getGateway());
156+
implemented.setCidr(config.getCidr());
157+
implemented.setState(State.Implemented);
158+
} else {
159+
// Determine the offset from the lowest vlan tag
160+
int offset = getVlanOffset(config.getPhysicalNetworkId(), vlanTag);
161+
cidrSize = getGloballyConfiguredCidrSize();
162+
// If the offset has more bits than there is room for, return null
163+
long bitsInOffset = 32 - Integer.numberOfLeadingZeros(offset);
164+
if (bitsInOffset > (cidrSize - 8)) {
165+
throw new CloudRuntimeException("The offset " + offset + " needs " + bitsInOffset + " bits, but only have " + (cidrSize - 8) + " bits to work with.");
166+
}
167+
newCidrAddress = (NetUtils.ip2Long(oldCidrAddress) & 0xff000000) | (offset << (32 - cidrSize));
168+
implemented.setGateway(NetUtils.long2Ip(newCidrAddress + 1));
169+
implemented.setCidr(NetUtils.long2Ip(newCidrAddress) + "/" + cidrSize);
170+
implemented.setState(State.Implemented);
160171
}
161172

162-
long newCidrAddress = (NetUtils.ip2Long(oldCidrAddress) & 0xff000000) | (offset << (32 - cidrSize));
163-
implemented.setGateway(NetUtils.long2Ip(newCidrAddress + 1));
164-
implemented.setCidr(NetUtils.long2Ip(newCidrAddress) + "/" + cidrSize);
165-
implemented.setState(State.Implemented);
166-
167173
// Mask the Ipv4 address of all nics that use this network with the new guest VLAN offset
168174
List<NicVO> nicsInNetwork = _nicDao.listByNetworkId(config.getId());
169175
for (NicVO nic : nicsInNetwork) {
@@ -172,8 +178,8 @@ public Network implement(Network config, NetworkOffering offering, DeployDestina
172178
nic.setIp4Address(NetUtils.long2Ip(newCidrAddress | ipMask));
173179
_nicDao.persist(nic);
174180
}
175-
}
176-
181+
}
182+
177183
// Mask the destination address of all port forwarding rules in this network with the new guest VLAN offset
178184
List<PortForwardingRuleVO> pfRulesInNetwork = _pfRulesDao.listByNetwork(config.getId());
179185
for (PortForwardingRuleVO pfRule : pfRulesInNetwork) {

server/src/com/cloud/network/vpc/VpcManagerImpl.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
184184
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
185185
private List<VpcProvider> vpcElements = null;
186186
private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
187-
private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp);
188-
187+
private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.Netscaler);
189188
int _cleanupInterval;
190189
int _maxNetworks;
191190
SearchBuilder<IPAddressVO> IpAddressSearch;
@@ -215,7 +214,27 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
215214
createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap,
216215
true, State.Enabled);
217216
}
218-
217+
218+
//configure default vpc offering with Netscaler as LB Provider
219+
if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName ) == null) {
220+
s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName);
221+
Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
222+
Set<Provider> defaultProviders = new HashSet<Provider>();
223+
defaultProviders.add(Provider.VPCVirtualRouter);
224+
for (Service svc : getSupportedServices()) {
225+
if (svc == Service.Lb) {
226+
Set<Provider> lbProviders = new HashSet<Provider>();
227+
lbProviders.add(Provider.Netscaler);
228+
lbProviders.add(Provider.VPCVirtualRouter);
229+
svcProviderMap.put(svc, lbProviders);
230+
} else {
231+
svcProviderMap.put(svc, defaultProviders);
232+
}
233+
}
234+
createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName,
235+
svcProviderMap, false, State.Enabled);
236+
}
237+
219238
txn.commit();
220239

221240
Map<String, String> configs = _configDao.getConfiguration(params);
@@ -1084,6 +1103,12 @@ public void validateNtwkOffForVpc(NetworkOffering guestNtwkOff, List<Service> su
10841103
if (guestNtwkOff.isConserveMode()) {
10851104
throw new InvalidParameterValueException("Only networks with conserve mode Off can belong to VPC");
10861105
}
1106+
1107+
//5) If Netscaler is LB provider make sure it is in dedicated mode
1108+
if ( providers.contains(Provider.Netscaler) && !guestNtwkOff.getDedicatedLB() ) {
1109+
throw new InvalidParameterValueException("Netscaler only with Dedicated LB can belong to VPC");
1110+
}
1111+
return ;
10871112
}
10881113

10891114
@DB
@@ -1155,6 +1180,7 @@ protected List<VpcProvider> getVpcElements() {
11551180
if (vpcElements == null) {
11561181
vpcElements = new ArrayList<VpcProvider>();
11571182
vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.VPCVirtualRouter.getName()));
1183+
vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.Netscaler.getName()));
11581184
}
11591185

11601186
if (vpcElements == null) {

0 commit comments

Comments
 (0)