Skip to content

Commit aedb8c4

Browse files
JayapalUradiAbhinandan Prateek
authored andcommitted
1 parent fe649f6 commit aedb8c4

44 files changed

Lines changed: 1866 additions & 68 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/src/com/cloud/network/IpAddress.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,7 @@ enum Purpose {
8787
* @param vpcId
8888
*/
8989
void setVpcId(Long vpcId);
90+
String getVmIp();
91+
void setVmIp(String vmIp);
92+
9093
}

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

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

2121
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
22+
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
2223
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
2324
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
24-
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
25+
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
2526

2627
import com.cloud.exception.ConcurrentOperationException;
2728
import com.cloud.exception.InsufficientAddressCapacityException;
@@ -33,6 +34,8 @@
3334
import com.cloud.user.Account;
3435
import com.cloud.user.User;
3536
import com.cloud.utils.Pair;
37+
import com.cloud.vm.Nic;
38+
import com.cloud.vm.NicSecondaryIp;
3639

3740
/**
3841
* The NetworkService interface is the "public" api to entities that make requests to the orchestration engine
@@ -153,5 +156,13 @@ IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAdd
153156
Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan,
154157
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId)
155158
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException;
156-
159+
160+
/* Requests an IP address for the guest nic */
161+
String allocateSecondaryGuestIP(Account account, long zoneId, Long nicId,
162+
Long networkId, String ipaddress) throws InsufficientAddressCapacityException;
163+
164+
boolean releaseSecondaryIpFromNic(long ipAddressId);
165+
166+
/* lists the nic informaton */
167+
List<? extends Nic> listNics(ListNicsCmd listNicsCmd);
157168
}

api/src/com/cloud/network/rules/RulesService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.cloud.exception.ResourceUnavailableException;
2626
import com.cloud.user.Account;
2727
import com.cloud.utils.Pair;
28+
import com.cloud.utils.net.Ip;
2829

2930
public interface RulesService {
3031
Pair<List<? extends FirewallRule>, Integer> searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId, Long projectId, boolean isRecursive, boolean listAll);
@@ -43,7 +44,7 @@ public interface RulesService {
4344
* @throws NetworkRuleConflictException
4445
* if conflicts in the network rules are detected.
4546
*/
46-
PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall) throws NetworkRuleConflictException;
47+
PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, Ip vmIp, boolean openFirewall) throws NetworkRuleConflictException;
4748

4849
/**
4950
* Revokes a port forwarding rule
@@ -66,7 +67,7 @@ public interface RulesService {
6667

6768
boolean applyPortForwardingRules(long ipAdddressId, Account caller) throws ResourceUnavailableException;
6869

69-
boolean enableStaticNat(long ipAddressId, long vmId, long networkId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException;
70+
boolean enableStaticNat(long ipAddressId, long vmId, long networkId, boolean isSystemVm, String vmGuestIp) throws NetworkRuleConflictException, ResourceUnavailableException;
7071

7172
PortForwardingRule getPortForwardigRule(long ruleId);
7273

api/src/com/cloud/vm/Nic.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,5 @@ public enum ReservationStrategy {
151151
String getIp6Cidr();
152152

153153
String getIp6Address();
154+
boolean getSecondaryIp();
154155
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.vm;
18+
19+
import org.apache.cloudstack.acl.ControlledEntity;
20+
import org.apache.cloudstack.api.Identity;
21+
import org.apache.cloudstack.api.InternalIdentity;
22+
23+
24+
/**
25+
* Nic represents one nic on the VM.
26+
*/
27+
public interface NicSecondaryIp extends ControlledEntity, Identity, InternalIdentity {
28+
/**
29+
* @return id in the CloudStack database
30+
*/
31+
long getId();
32+
long getNicId();
33+
String getIp4Address();
34+
long getNetworkId();
35+
long getVmId();
36+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ public class ApiConstants {
458458
public static final String UCS_PROFILE_DN = "profiledn";
459459
public static final String UCS_BLADE_DN = "bladedn";
460460
public static final String UCS_BLADE_ID = "bladeid";
461+
public static final String VM_GUEST_IP = "vmguestip";
461462

462463
public enum HostDetails {
463464
all, capacity, events, stats, min;

api/src/org/apache/cloudstack/api/ResponseGenerator.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
import org.apache.cloudstack.api.response.NetworkACLResponse;
5454
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
5555
import org.apache.cloudstack.api.response.NetworkResponse;
56+
import org.apache.cloudstack.api.response.NicResponse;
57+
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
5658
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
5759
import org.apache.cloudstack.api.response.PodResponse;
5860
import org.apache.cloudstack.api.response.PrivateGatewayResponse;
@@ -163,6 +165,8 @@
163165
import com.cloud.user.UserAccount;
164166
import com.cloud.uservm.UserVm;
165167
import com.cloud.vm.InstanceGroup;
168+
import com.cloud.vm.Nic;
169+
import com.cloud.vm.NicSecondaryIp;
166170
import com.cloud.vm.VirtualMachine;
167171
import com.cloud.vm.snapshot.VMSnapshot;
168172

@@ -385,4 +389,7 @@ public interface ResponseGenerator {
385389

386390
TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor);
387391
VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot);
392+
NicSecondaryIpResponse createSecondaryIPToNicResponse(String ip,
393+
Long nicId, Long networkId);
394+
public NicResponse createNicResponse(Nic result);
388395
}

api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
9494
description="The network of the vm the Port Forwarding rule will be created for. " +
9595
"Required when public Ip address is not associated with any Guest network yet (VPC case)")
9696
private Long networkId;
97+
@Parameter(name = ApiConstants.VM_GUEST_IP, type = CommandType.STRING, required = false,
98+
description = "VM guest nic Secondary ip address for the port forwarding rule")
99+
private String vmSecondaryIp;
97100

98101
// ///////////////////////////////////////////////////
99102
// ///////////////// Accessors ///////////////////////
@@ -104,6 +107,13 @@ public Long getIpAddressId() {
104107
return ipAddressId;
105108
}
106109

110+
public Ip getVmSecondaryIp() {
111+
if (vmSecondaryIp == null) {
112+
return null;
113+
}
114+
return new Ip(vmSecondaryIp);
115+
}
116+
107117
@Override
108118
public String getProtocol() {
109119
return protocol.trim();
@@ -300,8 +310,15 @@ public void create() {
300310
throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
301311
}
302312

313+
Ip privateIp = getVmSecondaryIp();
314+
if (privateIp != null) {
315+
if ( !privateIp.isIp4()) {
316+
throw new InvalidParameterValueException("Invalid vm ip address");
317+
}
318+
}
319+
303320
try {
304-
PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, getOpenFirewall());
321+
PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, privateIp, getOpenFirewall());
305322
setEntityId(result.getId());
306323
setEntityUuid(result.getUuid());
307324
} catch (NetworkRuleConflictException ex) {

api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ public class EnableStaticNatCmd extends BaseCmd{
5959
description="The network of the vm the static nat will be enabled for." +
6060
" Required when public Ip address is not associated with any Guest network yet (VPC case)")
6161
private Long networkId;
62+
@Parameter(name = ApiConstants.VM_GUEST_IP, type = CommandType.STRING, required = false,
63+
description = "VM guest nic Secondary ip address for the port forwarding rule")
64+
private String vmSecondaryIp;
6265

6366
/////////////////////////////////////////////////////
6467
/////////////////// Accessors ///////////////////////
@@ -72,6 +75,13 @@ public Long getVirtualMachineId() {
7275
return virtualMachineId;
7376
}
7477

78+
public String getVmSecondaryIp() {
79+
if (vmSecondaryIp == null) {
80+
return null;
81+
}
82+
return vmSecondaryIp;
83+
}
84+
7585
public long getNetworkId() {
7686
IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId());
7787
Long ntwkId = null;
@@ -110,7 +120,7 @@ public long getEntityOwnerId() {
110120
@Override
111121
public void execute() throws ResourceUnavailableException{
112122
try {
113-
boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), false);
123+
boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), false, getVmSecondaryIp());
114124
if (result) {
115125
SuccessResponse response = new SuccessResponse(getCommandName());
116126
this.setResponseObject(response);
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api.command.user.vm;
18+
19+
import org.apache.log4j.Logger;
20+
21+
import org.apache.cloudstack.api.APICommand;
22+
import org.apache.cloudstack.api.ApiConstants;
23+
import org.apache.cloudstack.api.ApiErrorCode;
24+
import org.apache.cloudstack.api.BaseAsyncCmd;
25+
import org.apache.cloudstack.api.Parameter;
26+
import org.apache.cloudstack.api.ServerApiException;
27+
import org.apache.cloudstack.api.response.NicResponse;
28+
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
29+
30+
import com.cloud.async.AsyncJob;
31+
import com.cloud.event.EventTypes;
32+
import com.cloud.exception.ConcurrentOperationException;
33+
import com.cloud.exception.InsufficientAddressCapacityException;
34+
import com.cloud.exception.InsufficientCapacityException;
35+
import com.cloud.exception.InvalidParameterValueException;
36+
import com.cloud.exception.ResourceAllocationException;
37+
import com.cloud.exception.ResourceUnavailableException;
38+
import com.cloud.network.Network;
39+
import com.cloud.user.Account;
40+
import com.cloud.user.UserContext;
41+
import com.cloud.utils.net.NetUtils;
42+
import com.cloud.vm.Nic;
43+
44+
@APICommand(name = "addIpToNic", description = "Assigns secondary IP to NIC", responseObject = NicSecondaryIpResponse.class)
45+
public class AddIpToVmNicCmd extends BaseAsyncCmd {
46+
public static final Logger s_logger = Logger.getLogger(AddIpToVmNicCmd.class.getName());
47+
private static final String s_name = "addiptovmnicresponse";
48+
49+
/////////////////////////////////////////////////////
50+
//////////////// API parameters /////////////////////
51+
/////////////////////////////////////////////////////
52+
@Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType = NicResponse.class, required = true,
53+
description="the ID of the nic to which you want to assign private IP")
54+
private Long nicId;
55+
56+
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = false,
57+
description = "Secondary IP Address")
58+
private String ipAddr;
59+
60+
/////////////////////////////////////////////////////
61+
/////////////////// Accessors ///////////////////////
62+
/////////////////////////////////////////////////////
63+
64+
public String getEntityTable() {
65+
return "nic_secondary_ips";
66+
}
67+
68+
public String getAccountName() {
69+
return UserContext.current().getCaller().getAccountName();
70+
}
71+
72+
public long getDomainId() {
73+
return UserContext.current().getCaller().getDomainId();
74+
}
75+
76+
private long getZoneId() {
77+
Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
78+
if (ntwk == null) {
79+
throw new InvalidParameterValueException("Can't find zone id for specified");
80+
}
81+
return ntwk.getDataCenterId();
82+
}
83+
84+
public Long getNetworkId() {
85+
Nic nic = _entityMgr.findById(Nic.class, nicId);
86+
Long networkId = nic.getNetworkId();
87+
return networkId;
88+
}
89+
90+
public Long getNicId() {
91+
return nicId;
92+
}
93+
94+
public String getIpaddress () {
95+
if (ipAddr != null) {
96+
return ipAddr;
97+
} else {
98+
return null;
99+
}
100+
}
101+
@Override
102+
public long getEntityOwnerId() {
103+
Account caller = UserContext.current().getCaller();
104+
return caller.getAccountId();
105+
}
106+
107+
@Override
108+
public String getEventType() {
109+
return EventTypes.EVENT_NET_IP_ASSIGN;
110+
}
111+
112+
@Override
113+
public String getEventDescription() {
114+
return "associating ip to nic id: " + getNetworkId() + " in zone " + getZoneId();
115+
}
116+
117+
/////////////////////////////////////////////////////
118+
/////////////// API Implementation///////////////////
119+
/////////////////////////////////////////////////////
120+
121+
122+
@Override
123+
public String getCommandName() {
124+
return s_name;
125+
}
126+
127+
public static String getResultObjectName() {
128+
return "addressinfo";
129+
}
130+
131+
@Override
132+
public void execute() throws ResourceUnavailableException, ResourceAllocationException,
133+
ConcurrentOperationException, InsufficientCapacityException {
134+
135+
UserContext.current().setEventDetails("Nic Id: " + getNicId() );
136+
String ip;
137+
String SecondaryIp = null;
138+
if ((ip = getIpaddress()) != null) {
139+
if (!NetUtils.isValidIp(ip)) {
140+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip);
141+
}
142+
}
143+
144+
try {
145+
SecondaryIp = _networkService.allocateSecondaryGuestIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNicId(), getNetworkId(), getIpaddress());
146+
} catch (InsufficientAddressCapacityException e) {
147+
throw new InvalidParameterValueException("Allocating guest ip for nic failed");
148+
}
149+
150+
if (SecondaryIp != null) {
151+
s_logger.info("Associated ip address to NIC : " + SecondaryIp);
152+
NicSecondaryIpResponse response = new NicSecondaryIpResponse();
153+
response = _responseGenerator.createSecondaryIPToNicResponse(ip, getNicId(), getNetworkId());
154+
response.setResponseName(getCommandName());
155+
this.setResponseObject(response);
156+
} else {
157+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign secondary ip to nic");
158+
}
159+
}
160+
161+
@Override
162+
public String getSyncObjType() {
163+
return BaseAsyncCmd.networkSyncObject;
164+
}
165+
166+
@Override
167+
public Long getSyncObjId() {
168+
return getNetworkId();
169+
}
170+
171+
@Override
172+
public AsyncJob.Type getInstanceType() {
173+
return AsyncJob.Type.IpAddress;
174+
}
175+
176+
}

0 commit comments

Comments
 (0)