Skip to content

Commit fbf4884

Browse files
GabrielBrascherrafaelweingartner
authored andcommitted
Support IPv6 address in addIpToNic (#2773)
The admin will manually need to add the address to the Instance, but the Security Grouping should allow it.
1 parent d12c106 commit fbf4884

File tree

27 files changed

+671
-128
lines changed

27 files changed

+671
-128
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public interface NetworkModel {
282282

283283
boolean isNetworkInlineMode(Network network);
284284

285-
boolean isIP6AddressAvailableInNetwork(long networkId);
285+
boolean areThereIPv6AddressAvailableInNetwork(long networkId);
286286

287287
boolean isIP6AddressAvailableInVlan(long vlanId);
288288

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 information
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: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.apache.log4j.Logger;
3030

3131
import com.cloud.dc.DataCenter;
32-
import com.cloud.dc.DataCenter.NetworkType;
3332
import com.cloud.event.EventTypes;
3433
import com.cloud.exception.ConcurrentOperationException;
3534
import com.cloud.exception.InsufficientAddressCapacityException;
@@ -38,6 +37,7 @@
3837
import com.cloud.exception.ResourceAllocationException;
3938
import com.cloud.exception.ResourceUnavailableException;
4039
import com.cloud.network.Network;
40+
import com.cloud.network.Network.IpAddresses;
4141
import com.cloud.utils.net.NetUtils;
4242
import com.cloud.vm.Nic;
4343
import com.cloud.vm.NicSecondaryIp;
@@ -78,20 +78,6 @@ public long getNicId() {
7878
return nicId;
7979
}
8080

81-
private String getIpaddress() {
82-
if (ipAddr != null) {
83-
return ipAddr;
84-
} else {
85-
return null;
86-
}
87-
}
88-
89-
private NetworkType getNetworkType() {
90-
Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
91-
DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
92-
return dc.getNetworkType();
93-
}
94-
9581
private boolean isZoneSGEnabled() {
9682
Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
9783
DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
@@ -144,7 +130,6 @@ public void execute() throws ResourceUnavailableException, ResourceAllocationExc
144130
}
145131
}
146132

147-
148133
@Override
149134
public Long getSyncObjId() {
150135
return getNetworkId();
@@ -169,17 +154,15 @@ public long getEntityOwnerId() {
169154

170155
@Override
171156
public void create() throws ResourceAllocationException {
172-
String ip;
173157
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);
178-
}
158+
159+
IpAddresses requestedIpPair = new IpAddresses(ipAddr, null);
160+
if (!NetUtils.isIpv4(ipAddr)) {
161+
requestedIpPair = new IpAddresses(null, ipAddr);
179162
}
180163

181164
try {
182-
result = _networkService.allocateSecondaryGuestIP(getNicId(), getIpaddress());
165+
result = _networkService.allocateSecondaryGuestIP(getNicId(), requestedIpPair);
183166
if (result != null) {
184167
setEntityId(result.getId());
185168
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: 14 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,13 +3623,24 @@ 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+
setResponseIpAddress(result, response);
36273627
response.setNicId(nic.getUuid());
36283628
response.setNwId(network.getUuid());
36293629
response.setObjectName("nicsecondaryip");
36303630
return response;
36313631
}
36323632

3633+
/**
3634+
* Set the NicSecondaryIpResponse object with the IP address that is not null (IPv4 or IPv6)
3635+
*/
3636+
public static void setResponseIpAddress(NicSecondaryIp result, NicSecondaryIpResponse response) {
3637+
if (result.getIp4Address() != null) {
3638+
response.setIpAddr(result.getIp4Address());
3639+
} else if (result.getIp6Address() != null) {
3640+
response.setIpAddr(result.getIp6Address());
3641+
}
3642+
}
3643+
36333644
/**
36343645
* The resulting Response attempts to be in line with what is returned from
36353646
* @see com.cloud.api.query.dao.UserVmJoinDaoImpl#setUserVmResponse(ResponseView, UserVmResponse, UserVmJoinVO)
@@ -3706,7 +3717,7 @@ public NicResponse createNicResponse(Nic result) {
37063717
for (NicSecondaryIpVO ip : secondaryIps) {
37073718
NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
37083719
ipRes.setId(ip.getUuid());
3709-
ipRes.setIpAddr(ip.getIp4Address());
3720+
setResponseIpAddress(ip, ipRes);
37103721
ipList.add(ipRes);
37113722
}
37123723
response.setSecondaryIps(ipList);

0 commit comments

Comments
 (0)