Skip to content

Commit aa01580

Browse files
authored
network: Specify IP for VR in shared networks (#4503)
This PR enables admins to specify IP for a VR in a shared network.
1 parent b6fe9f9 commit aa01580

File tree

20 files changed

+452
-34
lines changed

20 files changed

+452
-34
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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.admin.network;
1818

19+
import org.apache.cloudstack.api.ApiArgValidator;
1920
import org.apache.log4j.Logger;
2021

2122
import org.apache.cloudstack.api.APICommand;
@@ -42,6 +43,14 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd implements AdminCm
4243
@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")
4344
private Boolean hideIpAddressUsage;
4445

46+
@Parameter(name = ApiConstants.ROUTER_IP, type = CommandType.STRING, description = "IPV4 address to be assigned to a router in a shared network", since = "4.16",
47+
validations = {ApiArgValidator.NotNullOrEmpty})
48+
private String routerIp;
49+
50+
@Parameter(name = ApiConstants.ROUTER_IPV6, type = CommandType.STRING, description = "IPV6 address to be assigned to a router in a shared network", since = "4.16",
51+
validations = {ApiArgValidator.NotNullOrEmpty})
52+
private String routerIpv6;
53+
4554
/////////////////////////////////////////////////////
4655
/////////////////// Accessors ///////////////////////
4756
/////////////////////////////////////////////////////
@@ -63,4 +72,12 @@ public Boolean getHideIpAddressUsage() {
6372
}
6473
return false;
6574
}
75+
76+
public String getRouterIp() {
77+
return routerIp;
78+
}
79+
80+
public String getRouterIpv6() {
81+
return routerIpv6;
82+
}
6683
}

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: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,15 @@ protected NetworkOrchestrator() {
623623
setStateMachine();
624624
}
625625

626+
private void updateRouterIpInNetworkDetails(Long networkId, String routerIp, String routerIpv6) {
627+
if (isNotBlank(routerIp)) {
628+
networkDetailsDao.addDetail(networkId, ApiConstants.ROUTER_IP, routerIp, true);
629+
}
630+
if (isNotBlank(routerIpv6)) {
631+
networkDetailsDao.addDetail(networkId, ApiConstants.ROUTER_IPV6, routerIpv6, true);
632+
}
633+
}
634+
626635
@Override
627636
public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final DeploymentPlan plan, final String name, final String displayText, final boolean isDefault)
628637
throws ConcurrentOperationException {
@@ -705,6 +714,8 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
705714
networkDetailsDao.persist(detailVO);
706715
}
707716

717+
updateRouterIpInNetworkDetails(networkPersisted.getId(), network.getRouterIp(), network.getRouterIpv6());
718+
708719
if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){
709720
final NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru;
710721
functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID());
@@ -2297,26 +2308,26 @@ public Network createPrivateNetwork(final long networkOfferingId, final String n
22972308
// create network for private gateway
22982309
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
22992310
bypassVlanOverlapCheck, null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null,
2300-
vpcId, null, null, true, null, null, null, true);
2311+
vpcId, null, null, true, null, null, null, true, null, null);
23012312
}
23022313

23032314
@Override
23042315
@DB
23052316
public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
23062317
boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
23072318
final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
2308-
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
2319+
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
23092320
// create Isolated/Shared/L2 network
23102321
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck,
23112322
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr,
2312-
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false);
2323+
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false, routerIp, routerIpv6);
23132324
}
23142325

23152326
@DB
23162327
private Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
23172328
boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
23182329
final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
2319-
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
2330+
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
23202331

23212332
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
23222333
final DataCenterVO zone = _dcDao.findById(zoneId);
@@ -2577,6 +2588,14 @@ public Network doInTransaction(final TransactionStatus status) {
25772588
userNetwork.setExternalId(externalId);
25782589
}
25792590

2591+
if (isNotBlank(routerIp)) {
2592+
userNetwork.setRouterIp(routerIp);
2593+
}
2594+
2595+
if (isNotBlank(routerIpv6)) {
2596+
userNetwork.setRouterIpv6(routerIpv6);
2597+
}
2598+
25802599
if (vlanIdFinal != null) {
25812600
if (isolatedPvlan == null) {
25822601
URI uri = null;
@@ -2616,7 +2635,6 @@ public Network doInTransaction(final TransactionStatus status) {
26162635

26172636
final List<? extends Network> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId,
26182637
isDisplayNetworkEnabled);
2619-
26202638
Network network = null;
26212639
if (networks == null || networks.isEmpty()) {
26222640
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: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
3434
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
35+
import org.apache.cloudstack.api.ApiConstants;
3536
import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
3637
import org.apache.cloudstack.context.CallContext;
3738
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@@ -850,10 +851,16 @@ public IPAddressVO doInTransaction(TransactionStatus status) throws Insufficient
850851
errorMessage.append(", network id=" + guestNetworkId);
851852
}
852853
sc.setJoinParameters("vlan", "type", vlanUse);
853-
854+
String routerIpAddress = null;
855+
if (network != null) {
856+
NetworkDetailVO routerIpDetail = _networkDetailsDao.findDetail(network.getId(), ApiConstants.ROUTER_IP);
857+
routerIpAddress = routerIpDetail != null ? routerIpDetail.getValue() : null;
858+
}
854859
if (requestedIp != null) {
855860
sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
856861
errorMessage.append(": requested ip " + requestedIp + " is not available");
862+
} else if (routerIpAddress != null) {
863+
sc.addAnd("address", Op.NEQ, routerIpAddress);
857864
}
858865

859866
boolean ascOrder = ! forSystemVms;
@@ -1729,7 +1736,7 @@ public Ternary<Boolean, List<NetworkOfferingVO>, Network> doInTransaction(Transa
17291736
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
17301737
+ " as a part of createVlanIpRange process");
17311738
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);
1739+
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null, null, null, null);
17331740
if (guestNetwork == null) {
17341741
s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
17351742
throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT "
@@ -2104,7 +2111,6 @@ public void allocateDirectIp(final NicProfile nic, final DataCenter dc, final Vi
21042111
public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
21052112
//This method allocates direct ip for the Shared network in Advance zones
21062113
boolean ipv4 = false;
2107-
21082114
if (network.getGateway() != null) {
21092115
if (nic.getIPv4Address() == null) {
21102116
PublicIp ip = null;

0 commit comments

Comments
 (0)