Skip to content

Commit 4fbf893

Browse files
author
Pearl Dsilva
committed
Specify IP for VR in shared networks
1 parent e9ce381 commit 4fbf893

File tree

18 files changed

+352
-20
lines changed

18 files changed

+352
-20
lines changed

api/src/main/java/com/cloud/network/Network.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,4 +452,8 @@ public void setIp6Address(String ip6Address) {
452452
String getExternalId();
453453

454454
PVlanType getPvlanType();
455+
456+
String getRouterIp();
457+
458+
String getRouterIpv6();
455459
}

api/src/main/java/com/cloud/network/NetworkProfile.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,4 +319,14 @@ public PVlanType getPvlanType() {
319319
return null;
320320
}
321321

322+
@Override
323+
public String getRouterIp() {
324+
return null;
325+
}
326+
327+
@Override
328+
public String getRouterIpv6() {
329+
return null;
330+
}
331+
322332
}

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,8 @@ public class ApiConstants {
802802
public static final String ROUTER_HEALTH_CHECKS = "healthchecks";
803803
public static final String ROUTER_CHECK_NAME = "checkname";
804804
public static final String ROUTER_CHECK_TYPE = "checktype";
805+
public static final String ROUTER_IP = "routerip";
806+
public static final String ROUTER_IPV6 = "routeripv6";
805807
public static final String LAST_UPDATED = "lastupdated";
806808
public static final String PERFORM_FRESH_CHECKS = "performfreshchecks";
807809
public static final String CACHE_MODE = "cachemode";

api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd implements AdminCm
4242
@Parameter(name=ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description="when true ip address usage for the network will not be exported by the listUsageRecords API")
4343
private Boolean hideIpAddressUsage;
4444

45+
@Parameter(name = ApiConstants.ROUTER_IP, type = CommandType.STRING, description = "IPV4 address to be assigned to a router in a shared network", since = "4.16")
46+
private String routerIp;
47+
48+
@Parameter(name = ApiConstants.ROUTER_IPV6, type = CommandType.STRING, description = "IPV6 address to be assigned to a router in a shared network", since = "4.16")
49+
private String routerIpv6;
50+
4551
/////////////////////////////////////////////////////
4652
/////////////////// Accessors ///////////////////////
4753
/////////////////////////////////////////////////////
@@ -63,4 +69,12 @@ public Boolean getHideIpAddressUsage() {
6369
}
6470
return false;
6571
}
72+
73+
public String getRouterIp() {
74+
return routerIp;
75+
}
76+
77+
public String getRouterIpv6() {
78+
return routerIpv6;
79+
}
6680
}

engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ void prepare(VirtualMachineProfile profile, DeployDestination dest, ReservationC
182182

183183
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain, Account owner,
184184
Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
185-
Boolean displayNetworkEnabled, String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
185+
Boolean displayNetworkEnabled, String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
186186

187187
UserDataServiceProvider getPasswordResetProvider(Network network);
188188

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,19 @@ protected NetworkOrchestrator() {
640640
setStateMachine();
641641
}
642642

643+
private void updateNetworkDetails(NetworkVO networkPersisted, Network network) {
644+
NetworkDetailVO networkDetailVO = null;
645+
if (isNotBlank(network.getRouterIp())) {
646+
networkDetailVO = new NetworkDetailVO(networkPersisted.getId(), ApiConstants.ROUTER_IP, network.getRouterIp().toString(), true);
647+
}
648+
if (isNotBlank(network.getRouterIpv6())) {
649+
networkDetailVO = new NetworkDetailVO(networkPersisted.getId(), ApiConstants.ROUTER_IPV6, network.getRouterIpv6().toString(), true);
650+
}
651+
if (networkDetailVO != null) {
652+
networkDetailsDao.persist(networkDetailVO);
653+
}
654+
}
655+
643656
@Override
644657
public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final DeploymentPlan plan, final String name, final String displayText, final boolean isDefault)
645658
throws ConcurrentOperationException {
@@ -718,10 +731,12 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
718731
networks.add(networkPersisted);
719732

720733
if (network.getPvlanType() != null) {
721-
NetworkDetailVO detailVO = new NetworkDetailVO(networkPersisted.getId(), ApiConstants.ISOLATED_PVLAN_TYPE, network.getPvlanType().toString(), true);
734+
NetworkDetailVO detailVO = new NetworkDetailVO(networkPersisted.getId(), ApiConstants.ISOLATED_PVLAN_TYPE, network.getPvlanType().toString(), true);
722735
networkDetailsDao.persist(detailVO);
723736
}
724737

738+
updateNetworkDetails(networkPersisted, network);
739+
725740
if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){
726741
final NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru;
727742
functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID());
@@ -2314,26 +2329,26 @@ public Network createPrivateNetwork(final long networkOfferingId, final String n
23142329
// create network for private gateway
23152330
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
23162331
bypassVlanOverlapCheck, null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null,
2317-
vpcId, null, null, true, null, null, null, true);
2332+
vpcId, null, null, true, null, null, null, true, null, null);
23182333
}
23192334

23202335
@Override
23212336
@DB
23222337
public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
23232338
boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
23242339
final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
2325-
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
2340+
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
23262341
// create Isolated/Shared/L2 network
23272342
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck,
23282343
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr,
2329-
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false);
2344+
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false, routerIp, routerIpv6);
23302345
}
23312346

23322347
@DB
23332348
private Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
23342349
boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
23352350
final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
2336-
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
2351+
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
23372352

23382353
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
23392354
final DataCenterVO zone = _dcDao.findById(zoneId);
@@ -2591,6 +2606,14 @@ public Network doInTransaction(final TransactionStatus status) {
25912606
userNetwork.setExternalId(externalId);
25922607
}
25932608

2609+
if (isNotBlank(routerIp)) {
2610+
userNetwork.setRouterIp(routerIp);
2611+
}
2612+
2613+
if (isNotBlank(routerIpv6)) {
2614+
userNetwork.setRouterIpv6(routerIpv6);
2615+
}
2616+
25942617
if (vlanIdFinal != null) {
25952618
if (isolatedPvlan == null) {
25962619
URI uri = null;
@@ -2630,7 +2653,7 @@ public Network doInTransaction(final TransactionStatus status) {
26302653

26312654
final List<? extends Network> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId,
26322655
isDisplayNetworkEnabled);
2633-
2656+
26342657
Network network = null;
26352658
if (networks == null || networks.isEmpty()) {
26362659
throw new CloudRuntimeException("Fail to create a network");

engine/schema/src/main/java/com/cloud/network/dao/NetworkVO.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,12 @@ public class NetworkVO implements Network {
175175
@Column(name = "external_id")
176176
String externalId;
177177

178+
@Transient
179+
String routerIp;
180+
181+
@Transient
182+
String routerIpv6;
183+
178184
@Transient
179185
transient String vlanIdAsUUID;
180186

@@ -672,4 +678,20 @@ public PVlanType getPvlanType() {
672678
public void setPvlanType(PVlanType pvlanType) {
673679
this.pVlanType = pvlanType;
674680
}
681+
682+
public String getRouterIp() {
683+
return routerIp;
684+
}
685+
686+
public void setRouterIp(String routerIp) {
687+
this.routerIp = routerIp;
688+
}
689+
690+
public String getRouterIpv6() {
691+
return routerIpv6;
692+
}
693+
694+
public void setRouterIpv6(String routerIpv6) {
695+
this.routerIpv6 = routerIpv6;
696+
}
675697
}

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ private Network getKubernetesClusterNetworkIfMissing(final String clusterName, f
797797

798798
try {
799799
network = networkMgr.createGuestNetwork(networkOffering.getId(), clusterName + "-network", owner.getAccountName() + "-network",
800-
null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ControlledEntity.ACLType.Account, null, null, null, null, true, null, null, null);
800+
null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ControlledEntity.ACLType.Account, null, null, null, null, true, null, null, null, null, null);
801801
} catch (ConcurrentOperationException | InsufficientCapacityException | ResourceAllocationException e) {
802802
logAndThrow(Level.ERROR, String.format("Unable to create network for the Kubernetes cluster: %s", clusterName));
803803
}

server/src/main/java/com/cloud/network/IpAddressManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1729,7 +1729,7 @@ public Ternary<Boolean, List<NetworkOfferingVO>, Network> doInTransaction(Transa
17291729
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
17301730
+ " as a part of createVlanIpRange process");
17311731
guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
1732-
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null, null);
1732+
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null, null, null, null);
17331733
if (guestNetwork == null) {
17341734
s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
17351735
throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT "

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

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,26 @@ private void checkSharedNetworkCidrOverlap(Long zoneId, long physicalNetworkId,
10291029
}
10301030
}
10311031

1032+
private void validateRouterIps(String routerIp, String routerIpv6, String startIp, String endIp, String startIpv6, String endIpv6) {
1033+
if (isNotBlank(routerIp)) {
1034+
if (!NetUtils.isValidIp4(routerIp)) {
1035+
throw new CloudRuntimeException("Router IPv4 IP provided is of incorrect format");
1036+
}
1037+
if (!NetUtils.isIpInRange(routerIp, startIp, endIp)) {
1038+
throw new CloudRuntimeException("Router IPv4 IP provided is not within the specified range: " + startIp + " - " + endIp);
1039+
}
1040+
}
1041+
if (isNotBlank(routerIpv6)) {
1042+
String ipv6Range = startIpv6 + "-" + endIpv6;
1043+
if (!NetUtils.isValidIp6(routerIpv6)) {
1044+
throw new CloudRuntimeException("Router IPv6 IP provided is of incorrect format");
1045+
}
1046+
if (!NetUtils.isIp6InRange(routerIp, ipv6Range)) {
1047+
throw new CloudRuntimeException("Router IPv4 IP provided is not within the specified range: " + startIp + " - " + endIp);
1048+
}
1049+
}
1050+
}
1051+
10321052
@Override
10331053
@DB
10341054
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network")
@@ -1042,10 +1062,14 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac
10421062
String vlanId = null;
10431063
boolean bypassVlanOverlapCheck = false;
10441064
boolean hideIpAddressUsage = false;
1065+
String routerIp = null;
1066+
String routerIpv6 = null;
10451067
if (cmd instanceof CreateNetworkCmdByAdmin) {
10461068
vlanId = ((CreateNetworkCmdByAdmin)cmd).getVlan();
10471069
bypassVlanOverlapCheck = ((CreateNetworkCmdByAdmin)cmd).getBypassVlanOverlapCheck();
10481070
hideIpAddressUsage = ((CreateNetworkCmdByAdmin)cmd).getHideIpAddressUsage();
1071+
routerIp = ((CreateNetworkCmdByAdmin)cmd).getRouterIp();
1072+
routerIpv6 = ((CreateNetworkCmdByAdmin)cmd).getRouterIpv6();
10491073
}
10501074

10511075
String name = cmd.getNetworkName();
@@ -1150,6 +1174,16 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac
11501174
throw new InvalidParameterValueException("Only Admins can create network with guest type " + GuestType.Shared);
11511175
}
11521176

1177+
if (ntwkOff.getGuestType() != GuestType.Shared && (isNotBlank(routerIp) || isNotBlank(routerIpv6))) {
1178+
throw new InvalidParameterValueException("Router IP can be specified only for Shared networks");
1179+
}
1180+
1181+
if (ntwkOff.getGuestType() == GuestType.Shared && !_networkModel.isProviderForNetworkOffering(Provider.VirtualRouter, networkOfferingId)
1182+
&& (isNotBlank(routerIp) || isNotBlank(routerIpv6))) {
1183+
throw new InvalidParameterValueException("Virtual Router is not a supported provider for the Shared network, hence router ip should not be provided");
1184+
}
1185+
1186+
validateRouterIps(routerIp, routerIpv6, startIP, endIP, startIPv6, endIPv6);
11531187
// Check if the network is domain specific
11541188
if (aclType == ACLType.Domain) {
11551189
// only Admin can create domain with aclType=Domain
@@ -1365,7 +1399,7 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac
13651399

13661400
Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId,
13671401
domainId, isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, secondaryVlanId, privateVlanType, ntwkOff, pNtwk, aclType, owner, cidr, createVlan,
1368-
externalId);
1402+
externalId, routerIp, routerIpv6);
13691403

13701404
if (hideIpAddressUsage) {
13711405
_networkDetailsDao.persist(new NetworkDetailVO(network.getId(), Network.hideIpAddressUsage, String.valueOf(hideIpAddressUsage), false));
@@ -1445,7 +1479,7 @@ private Network commitNetwork(final Long networkOfferingId, final String gateway
14451479
final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
14461480
final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway, final String ip6Cidr,
14471481
final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final PVlanType isolatedPvlanType, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk, final ACLType aclType, final Account ownerFinal,
1448-
final String cidr, final boolean createVlan, final String externalId) throws InsufficientCapacityException, ResourceAllocationException {
1482+
final String cidr, final boolean createVlan, final String externalId, String routerIp, String routerIpv6) throws InsufficientCapacityException, ResourceAllocationException {
14491483
try {
14501484
Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
14511485
@Override
@@ -1500,7 +1534,7 @@ public Network doInTransaction(TransactionStatus status) throws InsufficientCapa
15001534
}
15011535

15021536
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk,
1503-
zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, isolatedPvlanType, externalId);
1537+
zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, isolatedPvlanType, externalId, routerIp, routerIpv6);
15041538
}
15051539

15061540
if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {

0 commit comments

Comments
 (0)