You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ts...@apache.org on 2013/03/04 14:43:01 UTC
[7/44] git commit: refs/heads/marvin-refactor - CLOUDSTACK-24:
multiple ip address per vm nic changes for isolated and vpc networks changes.
CLOUDSTACK-24: multiple ip address per vm nic changes for isolated and vpc networks changes.
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/f9d96c91
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/f9d96c91
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/f9d96c91
Branch: refs/heads/marvin-refactor
Commit: f9d96c9169a50917143914ffb53e227c8673c50f
Parents: 1a4ab95
Author: Jayapal Uradi <ja...@citrix.com>
Authored: Fri Mar 1 16:40:26 2013 +0530
Committer: Abhinandan Prateek <ap...@apache.org>
Committed: Fri Mar 1 16:40:26 2013 +0530
----------------------------------------------------------------------
api/src/com/cloud/network/IpAddress.java | 3 +
api/src/com/cloud/network/NetworkService.java | 15 +-
api/src/com/cloud/network/rules/RulesService.java | 5 +-
api/src/com/cloud/vm/Nic.java | 1 +
api/src/com/cloud/vm/NicSecondaryIp.java | 36 +++
.../org/apache/cloudstack/api/ApiConstants.java | 1 +
.../apache/cloudstack/api/ResponseGenerator.java | 7 +
.../user/firewall/CreatePortForwardingRuleCmd.java | 19 ++-
.../api/command/user/nat/EnableStaticNatCmd.java | 12 +-
.../api/command/user/vm/AddIpToVmNicCmd.java | 176 +++++++++++++++
.../api/command/user/vm/ListNicsCmd.java | 133 +++++++++++
.../api/command/user/vm/RemoveIpFromVmNicCmd.java | 123 ++++++++++
.../api/response/AddIpToVmNicResponse.java | 85 +++++++
.../cloudstack/api/response/IPAddressResponse.java | 8 +
.../cloudstack/api/response/NicResponse.java | 12 +-
.../api/response/NicSecondaryIpResponse.java | 85 +++++++
.../api/command/test/AddIpToVmNicTest.java | 132 +++++++++++
client/tomcatconf/commands.properties.in | 5 +
server/src/com/cloud/api/ApiDBUtils.java | 10 +
server/src/com/cloud/api/ApiResponseHelper.java | 56 +++++
server/src/com/cloud/network/NetworkManager.java | 12 +
.../src/com/cloud/network/NetworkManagerImpl.java | 76 ++++++-
server/src/com/cloud/network/NetworkModelImpl.java | 5 +
.../src/com/cloud/network/NetworkServiceImpl.java | 170 ++++++++++++++
server/src/com/cloud/network/addr/PublicIp.java | 34 ++-
server/src/com/cloud/network/dao/IPAddressDao.java | 7 +-
.../com/cloud/network/dao/IPAddressDaoImpl.java | 17 ++-
server/src/com/cloud/network/dao/IPAddressVO.java | 16 ++-
.../network/lb/LoadBalancingRulesManagerImpl.java | 2 +-
.../router/VirtualNetworkApplianceManagerImpl.java | 3 +-
.../com/cloud/network/rules/RulesManagerImpl.java | 113 +++++++---
.../network/rules/dao/PortForwardingRulesDao.java | 2 +
.../rules/dao/PortForwardingRulesDaoImpl.java | 8 +
.../src/com/cloud/server/ManagementServerImpl.java | 3 +
server/src/com/cloud/vm/NicVO.java | 11 +
server/src/com/cloud/vm/UserVmManagerImpl.java | 8 +
server/src/com/cloud/vm/dao/NicDao.java | 2 +
server/src/com/cloud/vm/dao/NicDaoImpl.java | 12 +-
server/src/com/cloud/vm/dao/NicSecondaryIpDao.java | 53 +++++
.../com/cloud/vm/dao/NicSecondaryIpDaoImpl.java | 138 +++++++++++
server/src/com/cloud/vm/dao/NicSecondaryIpVO.java | 160 +++++++++++++
.../com/cloud/network/MockNetworkManagerImpl.java | 47 ++++
.../com/cloud/network/MockRulesManagerImpl.java | 19 +-
.../test/com/cloud/vpc/MockNetworkManagerImpl.java | 73 ++++++
setup/db/db/schema-410to420.sql | 21 ++
45 files changed, 1867 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/com/cloud/network/IpAddress.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/IpAddress.java b/api/src/com/cloud/network/IpAddress.java
index 47df4d6..fce8f38 100644
--- a/api/src/com/cloud/network/IpAddress.java
+++ b/api/src/com/cloud/network/IpAddress.java
@@ -87,4 +87,7 @@ public interface IpAddress extends ControlledEntity, Identity, InternalIdentity
* @param vpcId
*/
void setVpcId(Long vpcId);
+ String getVmIp();
+ void setVmIp(String vmIp);
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/com/cloud/network/NetworkService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java
index 95bcc42..ab6d7bf 100755
--- a/api/src/com/cloud/network/NetworkService.java
+++ b/api/src/com/cloud/network/NetworkService.java
@@ -19,9 +19,10 @@ package com.cloud.network;
import java.util.List;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
+import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
-import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
+import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
@@ -33,6 +34,8 @@ import com.cloud.network.Networks.TrafficType;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.utils.Pair;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
/**
* The NetworkService interface is the "public" api to entities that make requests to the orchestration engine
@@ -153,5 +156,13 @@ public interface NetworkService {
Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan,
String startIp, String endIP, String gateway, String netmask, long networkOwnerId, Long vpcId)
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException;
-
+
+ /* Requests an IP address for the guest nic */
+ String allocateSecondaryGuestIP(Account account, long zoneId, Long nicId,
+ Long networkId, String ipaddress) throws InsufficientAddressCapacityException;
+
+ boolean releaseSecondaryIpFromNic(long ipAddressId);
+
+ /* lists the nic informaton */
+ List<? extends Nic> listNics(ListNicsCmd listNicsCmd);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/com/cloud/network/rules/RulesService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/rules/RulesService.java b/api/src/com/cloud/network/rules/RulesService.java
index 921a86e..d47b38f 100644
--- a/api/src/com/cloud/network/rules/RulesService.java
+++ b/api/src/com/cloud/network/rules/RulesService.java
@@ -25,6 +25,7 @@ import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
+import com.cloud.utils.net.Ip;
public interface RulesService {
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 {
* @throws NetworkRuleConflictException
* if conflicts in the network rules are detected.
*/
- PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall) throws NetworkRuleConflictException;
+ PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, Ip vmIp, boolean openFirewall) throws NetworkRuleConflictException;
/**
* Revokes a port forwarding rule
@@ -66,7 +67,7 @@ public interface RulesService {
boolean applyPortForwardingRules(long ipAdddressId, Account caller) throws ResourceUnavailableException;
- boolean enableStaticNat(long ipAddressId, long vmId, long networkId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException;
+ boolean enableStaticNat(long ipAddressId, long vmId, long networkId, boolean isSystemVm, String vmGuestIp) throws NetworkRuleConflictException, ResourceUnavailableException;
PortForwardingRule getPortForwardigRule(long ruleId);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/com/cloud/vm/Nic.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/Nic.java b/api/src/com/cloud/vm/Nic.java
index 9d21130..b2f6976 100644
--- a/api/src/com/cloud/vm/Nic.java
+++ b/api/src/com/cloud/vm/Nic.java
@@ -151,4 +151,5 @@ public interface Nic extends Identity, InternalIdentity {
String getIp6Cidr();
String getIp6Address();
+ boolean getSecondaryIp();
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/com/cloud/vm/NicSecondaryIp.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/NicSecondaryIp.java b/api/src/com/cloud/vm/NicSecondaryIp.java
new file mode 100644
index 0000000..655d172
--- /dev/null
+++ b/api/src/com/cloud/vm/NicSecondaryIp.java
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.vm;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+
+/**
+ * Nic represents one nic on the VM.
+ */
+public interface NicSecondaryIp extends ControlledEntity, Identity, InternalIdentity {
+ /**
+ * @return id in the CloudStack database
+ */
+ long getId();
+ long getNicId();
+ String getIp4Address();
+ long getNetworkId();
+ long getVmId();
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 4fdc91e..1b544fd 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -458,6 +458,7 @@ public class ApiConstants {
public static final String UCS_PROFILE_DN = "profiledn";
public static final String UCS_BLADE_DN = "bladedn";
public static final String UCS_BLADE_ID = "bladeid";
+ public static final String VM_GUEST_IP = "vmguestip";
public enum HostDetails {
all, capacity, events, stats, min;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/ResponseGenerator.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
index 267238a..a602514 100644
--- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
@@ -53,6 +53,8 @@ import org.apache.cloudstack.api.response.LoadBalancerResponse;
import org.apache.cloudstack.api.response.NetworkACLResponse;
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.PrivateGatewayResponse;
@@ -163,6 +165,8 @@ import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.uservm.UserVm;
import com.cloud.vm.InstanceGroup;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.snapshot.VMSnapshot;
@@ -385,4 +389,7 @@ public interface ResponseGenerator {
TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor);
VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot);
+ NicSecondaryIpResponse createSecondaryIPToNicResponse(String ip,
+ Long nicId, Long networkId);
+ public NicResponse createNicResponse(Nic result);
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
index 39ab812..4012852 100644
--- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
@@ -94,6 +94,9 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
description="The network of the vm the Port Forwarding rule will be created for. " +
"Required when public Ip address is not associated with any Guest network yet (VPC case)")
private Long networkId;
+ @Parameter(name = ApiConstants.VM_GUEST_IP, type = CommandType.STRING, required = false,
+ description = "VM guest nic Secondary ip address for the port forwarding rule")
+ private String vmSecondaryIp;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
@@ -104,6 +107,13 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
return ipAddressId;
}
+ public Ip getVmSecondaryIp() {
+ if (vmSecondaryIp == null) {
+ return null;
+ }
+ return new Ip(vmSecondaryIp);
+ }
+
@Override
public String getProtocol() {
return protocol.trim();
@@ -300,8 +310,15 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
}
+ Ip privateIp = getVmSecondaryIp();
+ if (privateIp != null) {
+ if ( !privateIp.isIp4()) {
+ throw new InvalidParameterValueException("Invalid vm ip address");
+ }
+ }
+
try {
- PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, getOpenFirewall());
+ PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, privateIp, getOpenFirewall());
setEntityId(result.getId());
setEntityUuid(result.getUuid());
} catch (NetworkRuleConflictException ex) {
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java b/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java
index ce6ea16..a0ec68e 100644
--- a/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java
@@ -59,6 +59,9 @@ public class EnableStaticNatCmd extends BaseCmd{
description="The network of the vm the static nat will be enabled for." +
" Required when public Ip address is not associated with any Guest network yet (VPC case)")
private Long networkId;
+ @Parameter(name = ApiConstants.VM_GUEST_IP, type = CommandType.STRING, required = false,
+ description = "VM guest nic Secondary ip address for the port forwarding rule")
+ private String vmSecondaryIp;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@@ -72,6 +75,13 @@ public class EnableStaticNatCmd extends BaseCmd{
return virtualMachineId;
}
+ public String getVmSecondaryIp() {
+ if (vmSecondaryIp == null) {
+ return null;
+ }
+ return vmSecondaryIp;
+ }
+
public long getNetworkId() {
IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId());
Long ntwkId = null;
@@ -110,7 +120,7 @@ public class EnableStaticNatCmd extends BaseCmd{
@Override
public void execute() throws ResourceUnavailableException{
try {
- boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), false);
+ boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), false, getVmSecondaryIp());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java
new file mode 100644
index 0000000..0f99274
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java
@@ -0,0 +1,176 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+
+@APICommand(name = "addIpToNic", description = "Assigns secondary IP to NIC", responseObject = NicSecondaryIpResponse.class)
+public class AddIpToVmNicCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(AddIpToVmNicCmd.class.getName());
+ private static final String s_name = "addiptovmnicresponse";
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType = NicResponse.class, required = true,
+ description="the ID of the nic to which you want to assign private IP")
+ private Long nicId;
+
+ @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = false,
+ description = "Secondary IP Address")
+ private String ipAddr;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public String getEntityTable() {
+ return "nic_secondary_ips";
+ }
+
+ public String getAccountName() {
+ return UserContext.current().getCaller().getAccountName();
+ }
+
+ public long getDomainId() {
+ return UserContext.current().getCaller().getDomainId();
+ }
+
+ private long getZoneId() {
+ Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
+ if (ntwk == null) {
+ throw new InvalidParameterValueException("Can't find zone id for specified");
+ }
+ return ntwk.getDataCenterId();
+ }
+
+ public Long getNetworkId() {
+ Nic nic = _entityMgr.findById(Nic.class, nicId);
+ Long networkId = nic.getNetworkId();
+ return networkId;
+ }
+
+ public Long getNicId() {
+ return nicId;
+ }
+
+ public String getIpaddress () {
+ if (ipAddr != null) {
+ return ipAddr;
+ } else {
+ return null;
+ }
+ }
+ @Override
+ public long getEntityOwnerId() {
+ Account caller = UserContext.current().getCaller();
+ return caller.getAccountId();
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_NET_IP_ASSIGN;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "associating ip to nic id: " + getNetworkId() + " in zone " + getZoneId();
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ public static String getResultObjectName() {
+ return "addressinfo";
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException, ResourceAllocationException,
+ ConcurrentOperationException, InsufficientCapacityException {
+
+ UserContext.current().setEventDetails("Nic Id: " + getNicId() );
+ String ip;
+ String SecondaryIp = null;
+ if ((ip = getIpaddress()) != null) {
+ if (!NetUtils.isValidIp(ip)) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip);
+ }
+ }
+
+ try {
+ SecondaryIp = _networkService.allocateSecondaryGuestIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNicId(), getNetworkId(), getIpaddress());
+ } catch (InsufficientAddressCapacityException e) {
+ throw new InvalidParameterValueException("Allocating guest ip for nic failed");
+ }
+
+ if (SecondaryIp != null) {
+ s_logger.info("Associated ip address to NIC : " + SecondaryIp);
+ NicSecondaryIpResponse response = new NicSecondaryIpResponse();
+ response = _responseGenerator.createSecondaryIPToNicResponse(ip, getNicId(), getNetworkId());
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign secondary ip to nic");
+ }
+ }
+
+ @Override
+ public String getSyncObjType() {
+ return BaseAsyncCmd.networkSyncObject;
+ }
+
+ @Override
+ public Long getSyncObjId() {
+ return getNetworkId();
+ }
+
+ @Override
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.IpAddress;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java
new file mode 100644
index 0000000..9af044e
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java
@@ -0,0 +1,133 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+
+import com.cloud.async.AsyncJob;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
+
+@APICommand(name = "listNics", description = "list the vm nics IP to NIC", responseObject = NicResponse.class)
+public class ListNicsCmd extends BaseListCmd {
+ public static final Logger s_logger = Logger.getLogger(ListNicsCmd.class.getName());
+ private static final String s_name = "listnics";
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType = NicResponse.class, required = false,
+ description="the ID of the nic to to list IPs")
+ private Long nicId;
+
+ @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = UserVmResponse.class, required = true,
+ description="the ID of the vm")
+ private Long vmId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public String getEntityTable() {
+ return "nics";
+ }
+
+ public String getAccountName() {
+ return UserContext.current().getCaller().getAccountName();
+ }
+
+ public long getDomainId() {
+ return UserContext.current().getCaller().getDomainId();
+ }
+
+ public Long getNicId() {
+ return nicId;
+ }
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ Account caller = UserContext.current().getCaller();
+ return caller.getAccountId();
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ public static String getResultObjectName() {
+ return "addressinfo";
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException, ResourceAllocationException,
+ ConcurrentOperationException, InsufficientCapacityException {
+
+ try {
+ List<? extends Nic> results = _networkService.listNics(this);
+ ListResponse<NicResponse> response = new ListResponse<NicResponse>();
+ List<NicResponse> resList = new ArrayList<NicResponse>(results.size());
+ for (Nic r : results) {
+ NicResponse resp = _responseGenerator.createNicResponse(r);
+ resp.setObjectName("nic");
+ resList.add(resp);
+ }
+ response.setResponses(resList);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+
+ } catch (Exception e) {
+ s_logger.warn("Failed to list secondary ip address per nic ");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+
+ @Override
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.IpAddress;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java
new file mode 100644
index 0000000..cb5e085
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java
@@ -0,0 +1,123 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+
+@APICommand(name = "removeIpFromNic", description="Assigns secondary IP to NIC.", responseObject=SuccessResponse.class)
+public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(RemoveIpFromVmNicCmd.class.getName());
+ private static final String s_name = "unassignsecondaryipaddrtonicresponse";
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.ID, type=CommandType.UUID, required = true, entityType = NicSecondaryIpResponse.class,
+ description="the ID of the secondary ip address to nic")
+ private long id;
+
+ // unexposed parameter needed for events logging
+ @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, expose=false)
+ private Long ownerId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public String getEntityTable() {
+ return "nic_secondary_ips";
+ }
+
+ public long getIpAddressId() {
+ return id;
+ }
+
+ public String getAccountName() {
+ return UserContext.current().getCaller().getAccountName();
+ }
+
+ public long getDomainId() {
+ return UserContext.current().getCaller().getDomainId();
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ Account caller = UserContext.current().getCaller();
+ return caller.getAccountId();
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_NET_IP_ASSIGN;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return ("Disassociating ip address with id=" + id);
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ public static String getResultObjectName() {
+ return "addressinfo";
+ }
+
+ @Override
+ public void execute() throws InvalidParameterValueException {
+ UserContext.current().setEventDetails("Ip Id: " + getIpAddressId());
+ boolean result = _networkService.releaseSecondaryIpFromNic(getIpAddressId());
+ if (result) {
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove secondary ip address for the nic");
+ }
+ }
+
+ @Override
+ public String getSyncObjType() {
+ return BaseAsyncCmd.networkSyncObject;
+ }
+
+ @Override
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.IpAddress;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/response/AddIpToVmNicResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/AddIpToVmNicResponse.java b/api/src/org/apache/cloudstack/api/response/AddIpToVmNicResponse.java
new file mode 100644
index 0000000..9af20b2
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/AddIpToVmNicResponse.java
@@ -0,0 +1,85 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+@SuppressWarnings("unused")
+public class AddIpToVmNicResponse extends BaseResponse {
+ @SerializedName(ApiConstants.ID) @Param(description="the ID of the secondary private IP addr")
+ private Long id;
+
+ @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="Secondary IP address")
+ private String ipAddr;
+
+ @SerializedName(ApiConstants.NIC_ID) @Param(description="the ID of the nic")
+ private Long nicId;
+
+ @SerializedName(ApiConstants.NETWORK_ID) @Param(description="the ID of the network")
+ private Long nwId;
+
+ @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) @Param(description="the ID of the vm")
+ private Long vmId;
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public Long getNicId() {
+ return nicId;
+ }
+
+ public void setNicId(Long nicId) {
+ this.nicId = nicId;
+ }
+
+ public Long getNwId() {
+ return nwId;
+ }
+
+ public void setNwId(Long nwId) {
+ this.nwId = nwId;
+ }
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ public void setVmId(Long vmId) {
+ this.vmId = vmId;
+ }
+
+ public Long setId(Long id) {
+ return id;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java b/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
index 251b2dd..cede84f 100644
--- a/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
@@ -82,6 +82,10 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR
@SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) @Param(description="virutal machine id the ip address is assigned to (not null only for static nat Ip)")
private String virtualMachineId;
+ @SerializedName("vmipaddress") @Param(description="virutal machine (dnat) ip address (not null only for static nat Ip)")
+ private String virtualMachineIp;
+
+
@SerializedName("virtualmachinename") @Param(description="virutal machine name the ip address is assigned to (not null only for static nat Ip)")
private String virtualMachineName;
@@ -185,6 +189,10 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR
this.virtualMachineId = virtualMachineId;
}
+ public void setVirtualMachineIp(String virtualMachineIp) {
+ this.virtualMachineIp = virtualMachineIp;
+ }
+
public void setVirtualMachineName(String virtualMachineName) {
this.virtualMachineName = virtualMachineName;
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/response/NicResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/NicResponse.java b/api/src/org/apache/cloudstack/api/response/NicResponse.java
index a7d1a0d..a1ceaf6 100644
--- a/api/src/org/apache/cloudstack/api/response/NicResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/NicResponse.java
@@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.api.response;
+import java.util.List;
+
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
@@ -75,7 +77,10 @@ public class NicResponse extends BaseResponse {
@SerializedName(ApiConstants.IP6_ADDRESS) @Param(description="the IPv6 address of network")
private String ip6Address;
-
+
+ @SerializedName("secondaryip") @Param(description="the Secondary ipv4 addr of nic")
+ private List<NicSecondaryIpResponse> secondaryIps;
+
public String getId() {
return id;
}
@@ -167,4 +172,9 @@ public class NicResponse extends BaseResponse {
return false;
return true;
}
+
+ public void setSecondaryIps(List<NicSecondaryIpResponse> ipList) {
+ this.secondaryIps = ipList;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java b/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java
new file mode 100644
index 0000000..3464a63
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java
@@ -0,0 +1,85 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+@SuppressWarnings("unused")
+public class NicSecondaryIpResponse extends BaseResponse {
+ @SerializedName(ApiConstants.ID) @Param(description="the ID of the secondary private IP addr")
+ private Long id;
+
+ @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="Secondary IP address")
+ private String ipAddr;
+
+ @SerializedName(ApiConstants.NIC_ID) @Param(description="the ID of the nic")
+ private Long nicId;
+
+ @SerializedName(ApiConstants.NETWORK_ID) @Param(description="the ID of the network")
+ private Long nwId;
+
+ @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) @Param(description="the ID of the vm")
+ private Long vmId;
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getIpAddr() {
+ return ipAddr;
+ }
+
+ public void setIpAddr(String ipAddr) {
+ this.ipAddr = ipAddr;
+ }
+
+ public Long getNicId() {
+ return nicId;
+ }
+
+ public void setNicId(Long nicId) {
+ this.nicId = nicId;
+ }
+
+ public Long getNwId() {
+ return nwId;
+ }
+
+ public void setNwId(Long nwId) {
+ this.nwId = nwId;
+ }
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ public void setVmId(Long vmId) {
+ this.vmId = vmId;
+ }
+
+ public Long setId(Long id) {
+ return id;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/api/test/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java
----------------------------------------------------------------------
diff --git a/api/test/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java b/api/test/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java
new file mode 100644
index 0000000..106589d
--- /dev/null
+++ b/api/test/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java
@@ -0,0 +1,132 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.test;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.cloudstack.api.ResponseGenerator;
+import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd;
+import org.apache.cloudstack.api.command.user.vm.RemoveIpFromVmNicCmd;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+
+
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.NetworkService;
+import com.cloud.user.Account;
+
+public class AddIpToVmNicTest extends TestCase {
+
+ private AddIpToVmNicCmd addIpToVmNicCmd;
+ private RemoveIpFromVmNicCmd removeIpFromVmNicCmd;
+ private ResponseGenerator responseGenerator;
+ private SuccessResponse successResponseGenerator;
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ addIpToVmNicCmd = new AddIpToVmNicCmd() {
+ };
+ removeIpFromVmNicCmd = new RemoveIpFromVmNicCmd();
+ }
+
+ @Test
+ public void testCreateSuccess() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
+
+ NetworkService networkService = Mockito.mock(NetworkService.class);
+ AddIpToVmNicCmd ipTonicCmd = Mockito.mock(AddIpToVmNicCmd.class);
+
+ Mockito.when(
+ networkService.allocateSecondaryGuestIP(Mockito.any(Account.class), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyString())).thenReturn("10.1.1.2");
+
+ ipTonicCmd._networkService = networkService;
+ responseGenerator = Mockito.mock(ResponseGenerator.class);
+
+ NicSecondaryIpResponse ipres = Mockito.mock(NicSecondaryIpResponse.class);
+ Mockito.when(responseGenerator.createSecondaryIPToNicResponse(Mockito.anyString(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(ipres);
+
+ ipTonicCmd._responseGenerator = responseGenerator;
+ ipTonicCmd.execute();
+ }
+
+ @Test
+ public void testCreateFailure() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
+
+ NetworkService networkService = Mockito.mock(NetworkService.class);
+ AddIpToVmNicCmd ipTonicCmd = Mockito.mock(AddIpToVmNicCmd.class);
+
+ Mockito.when(
+ networkService.allocateSecondaryGuestIP(Mockito.any(Account.class), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyString())).thenReturn(null);
+
+ ipTonicCmd._networkService = networkService;
+
+ try {
+ ipTonicCmd.execute();
+ } catch (InsufficientAddressCapacityException e) {
+ throw new InvalidParameterValueException("Allocating guest ip for nic failed");
+ }
+ }
+
+ @Test
+ public void testRemoveIpFromVmNicSuccess() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
+
+ NetworkService networkService = Mockito.mock(NetworkService.class);
+ RemoveIpFromVmNicCmd removeIpFromNic = Mockito.mock(RemoveIpFromVmNicCmd.class);
+
+ Mockito.when(
+ networkService.releaseSecondaryIpFromNic(Mockito.anyInt())).thenReturn(true);
+
+ removeIpFromNic._networkService = networkService;
+ successResponseGenerator = Mockito.mock(SuccessResponse.class);
+
+ removeIpFromNic.execute();
+ }
+
+ @Test
+ public void testRemoveIpFromVmNicFailure() throws InsufficientAddressCapacityException {
+ NetworkService networkService = Mockito.mock(NetworkService.class);
+ RemoveIpFromVmNicCmd removeIpFromNic = Mockito.mock(RemoveIpFromVmNicCmd.class);
+
+ Mockito.when(
+ networkService.releaseSecondaryIpFromNic(Mockito.anyInt())).thenReturn(false);
+
+ removeIpFromNic._networkService = networkService;
+ successResponseGenerator = Mockito.mock(SuccessResponse.class);
+
+ try {
+ removeIpFromNic.execute();
+ } catch (InvalidParameterValueException exception) {
+ Assert.assertEquals("Failed to remove secondary ip address for the nic",
+ exception.getLocalizedMessage());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index f03e8d5..bbb3d30 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -326,6 +326,11 @@ addNicToVirtualMachine=15
removeNicFromVirtualMachine=15
updateDefaultNicForVirtualMachine=15
+####
+addIpToNic=15;
+removeIpFromNic=15;
+listNics=15;
+
#### SSH key pair commands
registerSSHKeyPair=15
createSSHKeyPair=15
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java
index ffee22f..95879ee 100755
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@ -201,6 +201,7 @@ import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.InstanceGroup;
import com.cloud.vm.InstanceGroupVO;
import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
@@ -209,6 +210,8 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VmStats;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
import com.cloud.vm.dao.VMInstanceDao;
@@ -319,6 +322,7 @@ public class ApiDBUtils {
static HostDetailsDao _hostDetailsDao;
static VMSnapshotDao _vmSnapshotDao;
static ClusterDetailsDao _clusterDetailsDao;
+ static NicSecondaryIpDao _nicSecondaryIpDao;
@Inject private ManagementServer ms;
@Inject public AsyncJobManager asyncMgr;
@@ -421,6 +425,7 @@ public class ApiDBUtils {
@Inject private HostDetailsDao hostDetailsDao;
@Inject private ClusterDetailsDao clusterDetailsDao;
@Inject private VMSnapshotDao vmSnapshotDao;
+ @Inject private NicSecondaryIpDao nicSecondaryIpDao;
@PostConstruct
void init() {
_ms = ms;
@@ -521,6 +526,7 @@ public class ApiDBUtils {
_hostDetailsDao = hostDetailsDao;
_clusterDetailsDao = clusterDetailsDao;
_vmSnapshotDao = vmSnapshotDao;
+ _nicSecondaryIpDao = nicSecondaryIpDao;
// Note: stats collector should already have been initialized by this time, otherwise a null instance is returned
_statsCollector = StatsCollector.getInstance();
}
@@ -1519,4 +1525,8 @@ public class ApiDBUtils {
public static Map<String, String> findHostDetailsById(long hostId){
return _hostDetailsDao.findDetails(hostId);
}
+
+ public static List<NicSecondaryIpVO> findNicSecondaryIps(long nicId) {
+ return _nicSecondaryIpDao.listByNicId(nicId);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index eafee8a..fbfc955 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -19,6 +19,7 @@ package com.cloud.api;
import com.cloud.api.query.ViewResponseHelper;
import com.cloud.api.query.vo.*;
import com.cloud.api.response.ApiResponseSerializer;
+
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
@@ -52,6 +53,7 @@ import org.apache.cloudstack.api.response.LoadBalancerResponse;
import org.apache.cloudstack.api.response.NetworkACLResponse;
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.NicResponse;
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.PrivateGatewayResponse;
@@ -180,10 +182,14 @@ import com.cloud.utils.StringUtils;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.InstanceGroup;
+import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
@@ -551,6 +557,9 @@ public class ApiResponseHelper implements ResponseGenerator {
}
}
}
+ if (ipAddr.getVmIp() != null) {
+ ipResponse.setVirtualMachineIp(ipAddr.getVmIp());
+ }
if (ipAddr.getAssociatedWithNetworkId() != null) {
Network ntwk = ApiDBUtils.findNetworkById(ipAddr.getAssociatedWithNetworkId());
@@ -3435,4 +3444,51 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setTimeout(tmDetails.get("timeout"));
return response;
}
+
+ public NicSecondaryIpResponse createSecondaryIPToNicResponse(String ipAddr, Long nicId, Long networkId) {
+ NicSecondaryIpResponse response = new NicSecondaryIpResponse();
+ response.setIpAddr(ipAddr);
+ response.setNicId(nicId);
+ response.setNwId(networkId);
+ response.setObjectName("nicsecondaryip");
+ return response;
+ }
+
+ public NicResponse createNicResponse(Nic result) {
+ NicResponse response = new NicResponse();
+ response.setId(result.getUuid());
+ response.setIpaddress(result.getIp4Address());
+
+ if (result.getSecondaryIp()) {
+ List<NicSecondaryIpVO> secondaryIps = ApiDBUtils.findNicSecondaryIps(result.getId());
+ if (secondaryIps != null) {
+ List<NicSecondaryIpResponse> ipList = new ArrayList<NicSecondaryIpResponse>();
+ for (NicSecondaryIpVO ip: secondaryIps) {
+ NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
+ ipRes.setId(ip.getId());
+ ipRes.setIpAddr(ip.getIp4Address());
+ ipList.add(ipRes);
+ }
+ response.setSecondaryIps(ipList);
+ }
+ }
+
+ response.setGateway(result.getGateway());
+ response.setId(result.getUuid());
+ response.setGateway(result.getGateway());
+ response.setNetmask(result.getNetmask());
+ response.setMacAddress(result.getMacAddress());
+ if (result.getBroadcastUri() != null) {
+ response.setBroadcastUri(result.getBroadcastUri().toString());
+ }
+ if (result.getIsolationUri() != null) {
+ response.setIsolationUri(result.getIsolationUri().toString());
+ }
+ if (result.getIp6Address() != null) {
+ response.setId(result.getIp6Address());
+ }
+
+ response.setIsDefault(result.isDefaultNic());
+ return response;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/NetworkManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java
index 2904183..8b6bf9a 100755
--- a/server/src/com/cloud/network/NetworkManager.java
+++ b/server/src/com/cloud/network/NetworkManager.java
@@ -49,6 +49,7 @@ import com.cloud.user.User;
import com.cloud.utils.Pair;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
@@ -331,4 +332,15 @@ public interface NetworkManager {
int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state);
LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network);
+
+
+ boolean isSecondaryIpSetForNic(long nicId);
+
+ public String allocateGuestIP(Account ipOwner, boolean isSystem, long zoneId, Long networkId, String requestedIp)
+ throws InsufficientAddressCapacityException;
+
+ boolean removeVmSecondaryIps(long vmId);
+
+ List<? extends Nic> listVmNics(Long vmId, Long nicId);
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index f527b73..a575183 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -140,8 +140,19 @@ import com.cloud.utils.fsm.StateMachine2;
import com.cloud.utils.net.Ip;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.*;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@@ -240,6 +251,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
UsageEventDao _usageEventDao;
@Inject
NetworkModel _networkModel;
+ @Inject
+ NicSecondaryIpDao _nicSecondaryIpDao;
@Inject
UserIpv6AddressDao _ipv6Dao;
@Inject
@@ -1750,6 +1763,14 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
guru.deallocate(network, profile, vm);
_nicDao.remove(nic.getId());
s_logger.debug("Removed nic id=" + nic.getId());
+ //remove the secondary ip addresses corresponding to to this nic
+ List<NicSecondaryIpVO> secondaryIps = _nicSecondaryIpDao.listByNicId(nic.getId());
+ if (secondaryIps != null) {
+ for (NicSecondaryIpVO ip : secondaryIps) {
+ _nicSecondaryIpDao.remove(ip.getId());
+ }
+ s_logger.debug("Removed nic " + nic.getId() + " secondary ip addreses");
+ }
}
@Override
@@ -2792,6 +2813,33 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
Random _rand = new Random(System.currentTimeMillis());
+ public List<? extends Nic> listVmNics(Long vmId, Long nicId) {
+ List<NicVO> result = null;
+ if (nicId == null) {
+ result = _nicDao.listByVmId(vmId);
+ } else {
+ result = _nicDao.listByVmIdAndNicId(vmId, nicId);
+ }
+ return result;
+ }
+
+ public String allocateGuestIP(Account ipOwner, boolean isSystem, long zoneId, Long networkId, String requestedIp)
+ throws InsufficientAddressCapacityException {
+ String ipaddr = null;
+ Account caller = UserContext.current().getCaller();
+ long callerUserId = UserContext.current().getCallerUserId();
+ // check permissions
+ DataCenter zone = _configMgr.getZone(zoneId);
+ Network network = _networksDao.findById(networkId);
+
+ _accountMgr.checkAccess(caller, null, false, network);
+
+ //return acquireGuestIpAddress(network, requestedIp);
+ ipaddr = acquireGuestIpAddress(network, requestedIp);
+ return ipaddr;
+ }
+
+
@Override
@DB
public String acquireGuestIpAddress(Network network, String requestedIp) {
@@ -2802,7 +2850,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
Set<Long> availableIps = _networkModel.getAvailableIps(network, requestedIp);
- if (availableIps.isEmpty()) {
+ if (availableIps == null || availableIps.isEmpty()) {
return null;
}
@@ -3032,9 +3080,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
throw new InvalidParameterValueException("Source ip address of the rule id=" + firewallStaticNatRule.getId() + " is not static nat enabled");
}
- String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), firewallStaticNatRule.getNetworkId());
+ //String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), firewallStaticNatRule.getNetworkId());
ruleVO.setState(FirewallRule.State.Revoke);
- staticNatRules.add(new StaticNatRuleImpl(ruleVO, dstIp));
+ staticNatRules.add(new StaticNatRuleImpl(ruleVO, ip.getVmIp()));
}
try {
@@ -3598,4 +3646,26 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
}
return rules.size();
}
+
+ @Override
+ public boolean isSecondaryIpSetForNic(long nicId) {
+ NicVO nic = _nicDao.findById(nicId);
+ return nic.getSecondaryIp();
+ }
+
+ @Override
+ public boolean removeVmSecondaryIps(long vmId) {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ List <NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByVmId(vmId);
+ if (ipList != null) {
+ for (NicSecondaryIpVO ip: ipList) {
+ _nicSecondaryIpDao.remove(ip.getId());
+ }
+ s_logger.debug("Revoving nic secondary ip entry ...");
+ }
+ txn.commit();
+ return true;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/NetworkModelImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
index ac1bc87..0525888 100644
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -109,6 +109,7 @@ import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.VMInstanceDao;
@Component
@@ -170,6 +171,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
PrivateIpDao _privateIpDao;
@Inject
UserIpv6AddressDao _ipv6Dao;
+ @Inject
+ NicSecondaryIpDao _nicSecondaryIpDao;;
private final HashMap<String, NetworkOfferingVO> _systemNetworks = new HashMap<String, NetworkOfferingVO>(5);
@@ -1624,6 +1627,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
public Set<Long> getAvailableIps(Network network, String requestedIp) {
String[] cidr = network.getCidr().split("/");
List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
+ List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(network.getId());
+ ips.addAll(secondaryIps);
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]));
Set<Long> usedIps = new TreeSet<Long>();
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index 1708224..4c61aec 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -37,23 +37,28 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
+import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
+import org.bouncycastle.util.IPAddress;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.Domain;
@@ -65,6 +70,8 @@ import com.cloud.event.UsageEventUtils;
import com.cloud.event.dao.EventDao;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.*;
+import com.cloud.host.Host;
+import com.cloud.host.dao.HostDao;
import com.cloud.network.IpAddress.State;
import com.cloud.vm.Nic;
import com.cloud.network.Network.Capability;
@@ -82,7 +89,9 @@ import com.cloud.network.element.VirtualRouterElement;
import com.cloud.network.element.VpcVirtualRouterElement;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.PortForwardingRuleVO;
import com.cloud.network.rules.RulesManager;
import com.cloud.network.vpc.PrivateIpVO;
import com.cloud.network.vpc.VpcManager;
@@ -112,6 +121,8 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.*;
import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import java.util.*;
@@ -203,6 +214,16 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
@Inject
NetworkModel _networkModel;
+ @Inject
+ NicSecondaryIpDao _nicSecondaryIpDao;
+
+ @Inject
+ PortForwardingRulesDao _portForwardingDao;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ HostPodDao _hostPodDao;
+
int _cidrLimit;
boolean _allowSubdomainNetworkAccess;
@@ -449,6 +470,138 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
+ public String allocateSecondaryGuestIP (Account ipOwner, long zoneId, Long nicId, Long networkId, String requestedIp) throws InsufficientAddressCapacityException {
+
+ Long accountId = null;
+ Long domainId = null;
+ Long vmId = null;
+ String ipaddr = null;
+
+ if (networkId == null) {
+ throw new InvalidParameterValueException("Invalid network id is given");
+ }
+
+ Network network = _networksDao.findById(networkId);
+ if (network == null) {
+ throw new InvalidParameterValueException("Invalid network id is given");
+ }
+ accountId = network.getAccountId();
+ domainId = network.getDomainId();
+
+ // verify permissions
+ _accountMgr.checkAccess(ipOwner, null, true, network);
+
+ //check whether the nic belongs to user vm.
+ NicVO nicVO = _nicDao.findById(nicId);
+ if (nicVO == null) {
+ throw new InvalidParameterValueException("There is no nic for the " + nicId);
+ }
+
+ if (nicVO.getVmType() != VirtualMachine.Type.User) {
+ throw new InvalidParameterValueException("The nic is not belongs to user vm");
+ }
+
+ DataCenter dc = _dcDao.findById(network.getDataCenterId());
+ Long id = nicVO.getInstanceId();
+
+ DataCenter zone = _configMgr.getZone(zoneId);
+ if (zone == null) {
+ throw new InvalidParameterValueException("Invalid zone Id is given");
+ }
+
+ s_logger.debug("Calling the ip allocation ...");
+ if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
+ try {
+ ipaddr = _networkMgr.allocateGuestIP(ipOwner, false, zoneId, networkId, requestedIp);
+ } catch (InsufficientAddressCapacityException e) {
+ throw new InvalidParameterValueException("Allocating guest ip for nic failed");
+ }
+ } else {
+ throw new InvalidParameterValueException("AddIpToVMNic is not supported in this network...");
+ }
+
+ if (ipaddr != null) {
+ // we got the ip addr so up the nics table and secodary ip
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ boolean nicSecondaryIpSet = nicVO.getSecondaryIp();
+ if (!nicSecondaryIpSet) {
+ nicVO.setSecondaryIp(true);
+ // commit when previously set ??
+ s_logger.debug("Setting nics table ...");
+ _nicDao.update(nicId, nicVO);
+ }
+
+ s_logger.debug("Setting nic_secondary_ip table ...");
+ vmId = nicVO.getInstanceId();
+ NicSecondaryIpVO secondaryIpVO = new NicSecondaryIpVO(nicId, ipaddr, vmId, accountId, domainId, networkId);
+ _nicSecondaryIpDao.persist(secondaryIpVO);
+ txn.commit();
+ }
+ return ipaddr;
+ }
+
+ @DB
+ public boolean releaseSecondaryIpFromNic (long ipAddressId) {
+ Account caller = UserContext.current().getCaller();
+ boolean success = false;
+
+ // Verify input parameters
+ NicSecondaryIpVO ipVO= _nicSecondaryIpDao.findById(ipAddressId);
+ if (ipVO == null) {
+ throw new InvalidParameterValueException("Unable to find ip address by id");
+ }
+
+ Network network = _networksDao.findById(ipVO.getNetworkId());
+
+ // verify permissions
+ _accountMgr.checkAccess(caller, null, true, network);
+
+ Long nicId = ipVO.getNicId();
+ s_logger.debug("ip id and nic id" + ipAddressId + "..." + nicId);
+ //check is this the last secondary ip for NIC
+ List<NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByNicId(nicId);
+ boolean lastIp = false;
+ if (ipList.size() == 1) {
+ // this is the last secondary ip to nic
+ lastIp = true;
+ }
+ //check PF or static NAT is configured on this ip address
+ String secondaryIp = ipVO.getIp4Address();
+ List<PortForwardingRuleVO> pfRuleList = _portForwardingDao.listByDestIpAddr(secondaryIp);
+ if (pfRuleList.size() != 0) {
+ s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule");
+ throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule");
+ }
+ //check if the secondary ip associated with any static nat rule
+ IPAddressVO publicIpVO = _ipAddressDao.findByVmIp(secondaryIp);
+ if (publicIpVO != null) {
+ s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId());
+ throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId());
+ }
+ success = removeNicSecondaryIP(ipVO, lastIp);
+ return success;
+ }
+
+ boolean removeNicSecondaryIP(NicSecondaryIpVO ipVO, boolean lastIp) {
+ Transaction txn = Transaction.currentTxn();
+ long nicId = ipVO.getNicId();
+ NicVO nic = _nicDao.findById(nicId);
+
+ txn.start();
+
+ if (lastIp) {
+ nic.setSecondaryIp(false);
+ s_logger.debug("Setting nics secondary ip to false ...");
+ _nicDao.update(nicId, nic);
+ }
+
+ s_logger.debug("Revoving nic secondary ip entry ...");
+ _nicSecondaryIpDao.remove(ipVO.getId());
+ txn.commit();
+ return true;
+ }
@Override
@DB
@@ -3025,4 +3178,21 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
public Network getNetwork(String networkUuid) {
return _networksDao.findByUuid(networkUuid);
}
+
+ @Override
+ public List<? extends Nic> listNics(ListNicsCmd cmd) {
+ Account caller = UserContext.current().getCaller();
+ Long nicId = cmd.getNicId();
+ Long vmId = cmd.getVmId();
+
+ UserVmVO userVm = _userVmDao.findById(vmId);
+
+ if (userVm == null) {
+ InvalidParameterValueException ex = new InvalidParameterValueException("Virtual mahine id does not exist");
+ ex.addProxyObject(userVm, vmId, "vmId");
+ throw ex;
+ }
+ _accountMgr.checkAccess(caller, null, true, userVm);
+ return _networkMgr.listVmNics(vmId, nicId);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/addr/PublicIp.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/addr/PublicIp.java b/server/src/com/cloud/network/addr/PublicIp.java
index 61351a6..8217e4e 100644
--- a/server/src/com/cloud/network/addr/PublicIp.java
+++ b/server/src/com/cloud/network/addr/PublicIp.java
@@ -211,18 +211,28 @@ public class PublicIp implements PublicIpAddress {
_addr.setVpcId(vpcId);
}
- @Override
- public String getIp6Gateway() {
- return _vlan.getIp6Gateway();
- }
+ @Override
+ public String getIp6Gateway() {
+ return _vlan.getIp6Gateway();
+ }
- @Override
- public String getIp6Cidr() {
- return _vlan.getIp6Cidr();
- }
+ @Override
+ public String getIp6Cidr() {
+ return _vlan.getIp6Cidr();
+ }
- @Override
- public String getIp6Range() {
- return _vlan.getIp6Range();
- }
+ @Override
+ public String getIp6Range() {
+ return _vlan.getIp6Range();
+ }
+
+ @Override
+ public String getVmIp() {
+ return _addr.getVmIp();
+ }
+
+ @Override
+ public void setVmIp(String vmIp) {
+ _addr.setVmIp(vmIp);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/dao/IPAddressDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/IPAddressDao.java b/server/src/com/cloud/network/dao/IPAddressDao.java
index 9cdb975..1052639 100755
--- a/server/src/com/cloud/network/dao/IPAddressDao.java
+++ b/server/src/com/cloud/network/dao/IPAddressDao.java
@@ -62,5 +62,8 @@ public interface IPAddressDao extends GenericDao<IPAddressVO, Long> {
long countFreePublicIPs();
- long countFreeIPsInNetwork(long networkId);
-}
+ long countFreeIPsInNetwork(long networkId);
+ IPAddressVO findByVmIp(String vmIp);
+
+ IPAddressVO findByAssociatedVmIdAndVmIp(long vmId, String vmIp);
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/dao/IPAddressDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java
index e7067d9..691e460 100755
--- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java
+++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java
@@ -80,6 +80,7 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
AllFieldsSearch.and("sourcenetwork", AllFieldsSearch.entity().getSourceNetworkId(), Op.EQ);
AllFieldsSearch.and("physicalNetworkId", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ);
AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ);
+ AllFieldsSearch.and("associatedVmIp", AllFieldsSearch.entity().getVmIp(), Op.EQ);
AllFieldsSearch.done();
VlanDbIdSearchUnallocated = createSearchBuilder();
@@ -233,6 +234,12 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
}
@Override
+ public IPAddressVO findByVmIp(String vmIp) {
+ SearchCriteria<IPAddressVO> sc = AllFieldsSearch.create();
+ sc.setParameters("associatedVmIp", vmIp);
+ return findOneBy(sc);
+ }
+ @Override
public int countIPs(long dcId, long vlanId, boolean onlyCountAllocated) {
SearchCriteria<Integer> sc = onlyCountAllocated ? AllocatedIpCount.create() : AllIpCount.create();
sc.setParameters("dc", dcId);
@@ -347,5 +354,13 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
boolean result = super.remove(id);
txn.commit();
return result;
- }
+ }
+
+ @Override
+ public IPAddressVO findByAssociatedVmIdAndVmIp(long vmId, String vmIp) {
+ SearchCriteria<IPAddressVO> sc = AllFieldsSearch.create();
+ sc.setParameters("associatedWithVmId", vmId);
+ sc.setParameters("associatedVmIp", vmIp);
+ return findOneBy(sc);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/dao/IPAddressVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/IPAddressVO.java b/server/src/com/cloud/network/dao/IPAddressVO.java
index 00da5eb..8ce8d33 100644
--- a/server/src/com/cloud/network/dao/IPAddressVO.java
+++ b/server/src/com/cloud/network/dao/IPAddressVO.java
@@ -112,6 +112,10 @@ public class IPAddressVO implements IpAddress {
@Column(name="vpc_id")
private Long vpcId;
+ @Column(name="dnat_vmip")
+ private String vmIp;
+
+
protected IPAddressVO() {
this.uuid = UUID.randomUUID().toString();
}
@@ -288,8 +292,18 @@ public class IPAddressVO implements IpAddress {
return vpcId;
}
- @Override
+ @Override
public void setVpcId(Long vpcId) {
this.vpcId = vpcId;
}
+
+ @Override
+ public String getVmIp() {
+ return vmIp;
+ }
+
+ @Override
+ public void setVmIp(String vmIp) {
+ this.vmIp = vmIp;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 531a428..9230f6e 100755
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -623,7 +623,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
Set<Long> mappedInstanceIds = new HashSet<Long>();
for (LoadBalancerVMMapVO mappedInstance : mappedInstances) {
mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId()));
- }
+ }
List<UserVm> vmsToAdd = new ArrayList<UserVm>();
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/f9d96c91/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 0e2eb63..b387ab5 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -2318,8 +2318,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) {
if (ip.isOneToOneNat()) {
- String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), guestNetworkId);
- StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), dstIp, false);
+ StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), ip.getVmIp(), false);
staticNats.add(staticNat);
}
}