Skip to content

Commit e4dd889

Browse files
author
committed
Support IPv6 address in addIpToNic
The admin will manually need to add the address to the Instance, but the Security Grouping should allow it.
1 parent 1d05fea commit e4dd889

File tree

20 files changed

+522
-112
lines changed

20 files changed

+522
-112
lines changed

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

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.cloud.exception.InsufficientCapacityException;
3535
import com.cloud.exception.ResourceAllocationException;
3636
import com.cloud.exception.ResourceUnavailableException;
37+
import com.cloud.network.Network.IpAddresses;
3738
import com.cloud.network.Network.Service;
3839
import com.cloud.network.Networks.TrafficType;
3940
import com.cloud.network.vpc.Vpc;
@@ -155,15 +156,6 @@ PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkI
155156

156157
List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner);
157158

158-
/**
159-
* @param networkId
160-
* @param entityId
161-
* @return
162-
* @throws ConcurrentOperationException
163-
* @throws ResourceUnavailableException
164-
* @throws ResourceAllocationException
165-
* @throws InsufficientAddressCapacityException
166-
*/
167159
IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, ResourceAllocationException, ResourceUnavailableException,
168160
ConcurrentOperationException;
169161

@@ -189,12 +181,16 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
189181
String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId) throws ResourceAllocationException, ConcurrentOperationException,
190182
InsufficientCapacityException;
191183

192-
/* Requests an IP address for the guest nic */
193-
NicSecondaryIp allocateSecondaryGuestIP(long nicId, String ipaddress) throws InsufficientAddressCapacityException;
184+
/**
185+
* Requests an IP address for the guest nic
186+
*/
187+
NicSecondaryIp allocateSecondaryGuestIP(long nicId, IpAddresses requestedIpPair) throws InsufficientAddressCapacityException;
194188

195189
boolean releaseSecondaryIpFromNic(long ipAddressId);
196190

197-
/* lists the nic informaton */
191+
/**
192+
* lists the nic informaton
193+
*/
198194
List<? extends Nic> listNics(ListNicsCmd listNicsCmd);
199195

200196
Map<Network.Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service);

api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.cloud.exception.ResourceAllocationException;
3939
import com.cloud.exception.ResourceUnavailableException;
4040
import com.cloud.network.Network;
41+
import com.cloud.network.Network.IpAddresses;
4142
import com.cloud.utils.net.NetUtils;
4243
import com.cloud.vm.Nic;
4344
import com.cloud.vm.NicSecondaryIp;
@@ -78,14 +79,6 @@ public long getNicId() {
7879
return nicId;
7980
}
8081

81-
private String getIpaddress() {
82-
if (ipAddr != null) {
83-
return ipAddr;
84-
} else {
85-
return null;
86-
}
87-
}
88-
8982
private NetworkType getNetworkType() {
9083
Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
9184
DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
@@ -144,7 +137,6 @@ public void execute() throws ResourceUnavailableException, ResourceAllocationExc
144137
}
145138
}
146139

147-
148140
@Override
149141
public Long getSyncObjId() {
150142
return getNetworkId();
@@ -169,17 +161,25 @@ public long getEntityOwnerId() {
169161

170162
@Override
171163
public void create() throws ResourceAllocationException {
172-
String ip;
173164
NicSecondaryIp result;
174-
String secondaryIp = null;
175-
if ((ip = getIpaddress()) != null) {
176-
if (!NetUtils.isValidIp4(ip)) {
177-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip);
165+
boolean isIpv4 = true;
166+
167+
if (ipAddr != null) {
168+
if (!NetUtils.isValidIp4(ipAddr)) {
169+
isIpv4 = false;
170+
}
171+
if (!NetUtils.isValidIp6(ipAddr) && !isIpv4) {
172+
throw new InvalidParameterValueException("Invalid ip address " + ipAddr);
178173
}
179174
}
180175

176+
IpAddresses requestedIpPair = new IpAddresses(ipAddr, null);
177+
if (!isIpv4) {
178+
requestedIpPair = new IpAddresses(null, ipAddr);
179+
}
180+
181181
try {
182-
result = _networkService.allocateSecondaryGuestIP(getNicId(), getIpaddress());
182+
result = _networkService.allocateSecondaryGuestIP(getNicId(), requestedIpPair);
183183
if (result != null) {
184184
setEntityId(result.getId());
185185
setEntityUuid(result.getUuid());

api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,15 @@ public void execute() throws InvalidParameterValueException {
147147
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid IP id is passed");
148148
}
149149

150+
String secIp = nicSecIp.getIp4Address();
151+
if (secIp == null) {
152+
secIp = nicSecIp.getIp6Address();
153+
}
154+
150155
if (isZoneSGEnabled()) {
151156
//remove the security group rules for this secondary ip
152157
boolean success = false;
153-
success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), nicSecIp.getIp4Address(), false);
158+
success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), secIp, false);
154159
if (success == false) {
155160
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip");
156161
}

api/src/test/java/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void testCreateSuccess() throws ResourceAllocationException, ResourceUnav
6161
NicSecondaryIp secIp = Mockito.mock(NicSecondaryIp.class);
6262

6363
Mockito.when(
64-
networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.anyString()))
64+
networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.any()))
6565
.thenReturn(secIp);
6666

6767
ipTonicCmd._networkService = networkService;
@@ -81,7 +81,7 @@ public void testCreateFailure() throws ResourceAllocationException, ResourceUnav
8181
AddIpToVmNicCmd ipTonicCmd = Mockito.mock(AddIpToVmNicCmd.class);
8282

8383
Mockito.when(
84-
networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.anyString()))
84+
networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.any()))
8585
.thenReturn(null);
8686

8787
ipTonicCmd._networkService = networkService;

engine/components-api/src/main/java/com/cloud/network/IpAddressManager.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,18 +166,18 @@ void transferPortableIP(long ipAddrId, long currentNetworkId, long newNetworkId)
166166
* @throws ConcurrentOperationException
167167
* @throws InsufficientAddressCapacityException
168168
*/
169-
PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId, boolean isSourceNat) throws ConcurrentOperationException,
170-
InsufficientAddressCapacityException;
169+
PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId, boolean isSourceNat)
170+
throws ConcurrentOperationException, InsufficientAddressCapacityException;
171171

172-
IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerId, DataCenter zone, Boolean displayIp) throws ConcurrentOperationException,
173-
ResourceAllocationException, InsufficientAddressCapacityException;
172+
IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerId, DataCenter zone, Boolean displayIp)
173+
throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException;
174174

175-
PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp,
176-
boolean isSystem) throws InsufficientAddressCapacityException;
175+
PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp, boolean isSystem)
176+
throws InsufficientAddressCapacityException;
177177

178178
@DB
179-
void allocateNicValues(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4,
180-
String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
179+
void allocateNicValues(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, String requestedIpv6)
180+
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
181181

182182
int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state);
183183

@@ -187,6 +187,8 @@ void allocateNicValues(NicProfile nic, DataCenter dc, VirtualMachineProfile vm,
187187

188188
AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException;
189189

190+
public boolean isIpEqualsGatewayOrNetworkOfferingsEmpty(Network network, String requestedIp);
191+
190192
void releasePodIp(Long id) throws CloudRuntimeException;
191193
}
192194

engine/schema/src/main/java/com/cloud/vm/dao/NicIpAliasDaoImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public List<String> getAliasIpAddressesForNic(long nicId) {
113113
List<String> ips = new ArrayList<String>(results.size());
114114
for (NicIpAliasVO result : results) {
115115
ips.add(result.getIp4Address());
116+
ips.add(result.getIp6Address());
116117
}
117118
return ips;
118119
}

engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpDao.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ public interface NicSecondaryIpDao extends GenericDao<NicSecondaryIpVO, Long> {
3434

3535
NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId);
3636

37-
/**
38-
* @param networkId
39-
* @param instanceId
40-
* @return
41-
*/
37+
NicSecondaryIpVO findByIp6AddressAndNetworkId(String ip6Address, long networkId);
4238

4339
List<NicSecondaryIpVO> getSecondaryIpAddressesForVm(long vmId);
4440

engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@
1919
import java.util.ArrayList;
2020
import java.util.List;
2121

22-
23-
import com.cloud.utils.StringUtils;
2422
import org.springframework.stereotype.Component;
2523

24+
import com.cloud.utils.StringUtils;
2625
import com.cloud.utils.db.GenericDaoBase;
2726
import com.cloud.utils.db.GenericSearchBuilder;
2827
import com.cloud.utils.db.SearchBuilder;
@@ -32,16 +31,18 @@
3231

3332
@Component
3433
public class NicSecondaryIpDaoImpl extends GenericDaoBase<NicSecondaryIpVO, Long> implements NicSecondaryIpDao {
34+
3535
private final SearchBuilder<NicSecondaryIpVO> AllFieldsSearch;
3636
private final GenericSearchBuilder<NicSecondaryIpVO, String> IpSearch;
3737
protected GenericSearchBuilder<NicSecondaryIpVO, Long> CountByNicId;
3838

39-
protected NicSecondaryIpDaoImpl() {
39+
public NicSecondaryIpDaoImpl() {
4040
super();
4141
AllFieldsSearch = createSearchBuilder();
4242
AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getVmId(), Op.EQ);
4343
AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
4444
AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.LIKE);
45+
AllFieldsSearch.and("ip6address", AllFieldsSearch.entity().getIp6Address(), Op.LIKE);
4546
AllFieldsSearch.and("nicId", AllFieldsSearch.entity().getNicId(), Op.EQ);
4647
AllFieldsSearch.done();
4748

@@ -132,6 +133,14 @@ public NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long net
132133
return findOneBy(sc);
133134
}
134135

136+
@Override
137+
public NicSecondaryIpVO findByIp6AddressAndNetworkId(String ip6Address, long networkId) {
138+
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
139+
sc.setParameters("network", networkId);
140+
sc.setParameters("ip6address", ip6Address);
141+
return findOneBy(sc);
142+
}
143+
135144
@Override
136145
public NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId) {
137146
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();

server/src/main/java/com/cloud/api/ApiResponseHelper.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ public ConfigurationResponse createConfigurationResponse(Configuration cfg) {
471471
cfgResponse.setCategory(cfg.getCategory());
472472
cfgResponse.setDescription(cfg.getDescription());
473473
cfgResponse.setName(cfg.getName());
474-
if(cfg.isEncrypted()) {
474+
if (cfg.isEncrypted()) {
475475
cfgResponse.setValue(DBEncryptionUtil.encrypt(cfg.getValue()));
476476
} else {
477477
cfgResponse.setValue(cfg.getValue());
@@ -3623,7 +3623,11 @@ public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp resu
36233623
NicVO nic = _entityMgr.findById(NicVO.class, result.getNicId());
36243624
NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
36253625
response.setId(result.getUuid());
3626-
response.setIpAddr(result.getIp4Address());
3626+
if (result.getIp4Address() != null) {
3627+
response.setIpAddr(result.getIp4Address());
3628+
} else if (result.getIp6Address() != null) {
3629+
response.setIpAddr(result.getIp6Address());
3630+
}
36273631
response.setNicId(nic.getUuid());
36283632
response.setNwId(network.getUuid());
36293633
response.setObjectName("nicsecondaryip");
@@ -3706,7 +3710,11 @@ public NicResponse createNicResponse(Nic result) {
37063710
for (NicSecondaryIpVO ip : secondaryIps) {
37073711
NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
37083712
ipRes.setId(ip.getUuid());
3709-
ipRes.setIpAddr(ip.getIp4Address());
3713+
if(ip.getIp4Address() != null) {
3714+
ipRes.setIpAddr(ip.getIp4Address());
3715+
} else {
3716+
ipRes.setIpAddr(ip.getIp6Address());
3717+
}
37103718
ipList.add(ipRes);
37113719
}
37123720
response.setSecondaryIps(ipList);

server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,15 +267,20 @@ public UserVmResponse newUserVmResponse(ResponseView view, String objectName, Us
267267
for (NicSecondaryIpVO ip : secondaryIps) {
268268
NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
269269
ipRes.setId(ip.getUuid());
270-
ipRes.setIpAddr(ip.getIp4Address());
270+
271+
String secIpAddr = ip.getIp4Address();
272+
if (secIpAddr == null) {
273+
secIpAddr = ip.getIp6Address();
274+
}
275+
ipRes.setIpAddr(secIpAddr);
276+
271277
ipList.add(ipRes);
272278
}
273279
nicResponse.setSecondaryIps(ipList);
274280
}
275281
nicResponse.setObjectName("nic");
276282

277-
List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = _nicExtraDhcpOptionDao.listByNicId(nic_id)
278-
.stream()
283+
List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = _nicExtraDhcpOptionDao.listByNicId(nic_id).stream()
279284
.map(vo -> new NicExtraDhcpOptionResponse(Dhcp.DhcpOptionCode.valueOfInt(vo.getCode()).getName(), vo.getCode(), vo.getValue()))
280285
.collect(Collectors.toList());
281286
nicResponse.setExtraDhcpOptions(nicExtraDhcpOptionResponses);
@@ -400,7 +405,13 @@ public UserVmResponse setUserVmResponse(ResponseView view, UserVmResponse userVm
400405
for (NicSecondaryIpVO ip : secondaryIps) {
401406
NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
402407
ipRes.setId(ip.getUuid());
403-
ipRes.setIpAddr(ip.getIp4Address());
408+
409+
String ipAddr = ip.getIp4Address();
410+
if (ipAddr == null) {
411+
ipAddr = ip.getIp6Address();
412+
}
413+
ipRes.setIpAddr(ipAddr);
414+
404415
ipList.add(ipRes);
405416
}
406417
nicResponse.setSecondaryIps(ipList);

0 commit comments

Comments
 (0)