CLOUDSTACK-24: multiple ip address per vm nic changes for isolated and vpc networks changes.

This commit is contained in:
Jayapal Uradi 2013-03-01 16:40:26 +05:30 committed by Abhinandan Prateek
parent 1a4ab95d2e
commit f9d96c9169
46 changed files with 1867 additions and 69 deletions

View File

@ -87,4 +87,7 @@ public interface IpAddress extends ControlledEntity, Identity, InternalIdentity
* @param vpcId
*/
void setVpcId(Long vpcId);
String getVmIp();
void setVmIp(String vmIp);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -151,4 +151,5 @@ public interface Nic extends Identity, InternalIdentity {
String getIp6Cidr();
String getIp6Address();
boolean getSecondaryIp();
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}
}

View File

@ -326,6 +326,11 @@ addNicToVirtualMachine=15
removeNicFromVirtualMachine=15
updateDefaultNicForVirtualMachine=15
####
addIpToNic=15;
removeIpFromNic=15;
listNics=15;
#### SSH key pair commands
registerSSHKeyPair=15
createSSHKeyPair=15

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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>();

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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();
@ -232,6 +233,12 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
return findOneBy(sc);
}
@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();
@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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>();

View File

@ -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);
}
}

View File

@ -78,10 +78,13 @@ import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.Ip;
import com.cloud.vm.Nic;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.UserVmVO;
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;
@Component
@ -123,6 +126,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
ResourceTagDao _resourceTagDao;
@Inject
VpcManager _vpcMgr;
@Inject
NicSecondaryIpDao _nicSecondaryDao;
@Override
public void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller) {
@ -172,7 +177,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true)
public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall)
public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, Ip vmIp, boolean openFirewall)
throws NetworkRuleConflictException {
UserContext ctx = UserContext.current();
Account caller = ctx.getCaller();
@ -192,6 +197,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
Network network = _networkModel.getNetwork(networkId);
//associate ip address to network (if needed)
boolean performedIpAssoc = false;
Nic guestNic;
if (ipAddress.getAssociatedWithNetworkId() == null) {
boolean assignToVpcNtwk = network.getVpcId() != null
&& ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
@ -244,13 +250,26 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
// Verify that vm has nic in the network
Ip dstIp = rule.getDestinationIpAddress();
Nic guestNic = _networkModel.getNicInNetwork(vmId, networkId);
guestNic = _networkModel.getNicInNetwork(vmId, networkId);
if (guestNic == null || guestNic.getIp4Address() == null) {
throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
} else {
dstIp = new Ip(guestNic.getIp4Address());
}
if (vmIp != null) {
//vm ip is passed so it can be primary or secondary ip addreess.
if (!dstIp.equals(vmIp)) {
//the vm ip is secondary ip to the nic.
// is vmIp is secondary ip or not
NicSecondaryIp secondaryIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmIp.toString(), guestNic.getId());
if (secondaryIp == null) {
throw new InvalidParameterValueException("IP Address is not in the VM nic's network ");
}
dstIp = vmIp;
}
}
//if start port and end port are passed in, and they are not equal to each other, perform the validation
boolean validatePortRange = false;
if (rule.getSourcePortStart().intValue() != rule.getSourcePortEnd().intValue()
@ -350,8 +369,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
throw new InvalidParameterValueException("Can't create ip forwarding rules for the network where elasticIP service is enabled");
}
String dstIp = _networkModel.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId);
//String dstIp = _networkModel.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId);
String dstIp = ipAddress.getVmIp();
Transaction txn = Transaction.currentTxn();
txn.start();
@ -397,14 +416,13 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
@Override
@ActionEvent(eventType = EventTypes.EVENT_ENABLE_STATIC_NAT, eventDescription = "enabling static nat")
public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm)
public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm, String vmGuestIp)
throws NetworkRuleConflictException, ResourceUnavailableException {
UserContext ctx = UserContext.current();
Account caller = ctx.getCaller();
UserContext.current().setEventDetails("Ip Id: " + ipId);
// Verify input parameters
IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
if (ipAddress == null) {
throw new InvalidParameterValueException("Unable to find ip address by id " + ipId);
@ -414,6 +432,10 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
boolean performedIpAssoc = false;
boolean isOneToOneNat = ipAddress.isOneToOneNat();
Long associatedWithVmId = ipAddress.getAssociatedWithVmId();
Nic guestNic;
NicSecondaryIpVO nicSecIp = null;
String dstIp = null;
try {
Network network = _networkModel.getNetwork(networkId);
if (network == null) {
@ -421,11 +443,11 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
}
// Check that vm has a nic in the network
Nic guestNic = _networkModel.getNicInNetwork(vmId, networkId);
guestNic = _networkModel.getNicInNetwork(vmId, networkId);
if (guestNic == null) {
throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
}
dstIp = guestNic.getIp4Address();
if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " +
@ -466,13 +488,36 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
// Check permissions
checkIpAndUserVm(ipAddress, vm, caller);
//is static nat is for vm secondary ip
//dstIp = guestNic.getIp4Address();
if (vmGuestIp != null) {
//dstIp = guestNic.getIp4Address();
if (!dstIp.equals(vmGuestIp)) {
//check whether the secondary ip set to the vm or not
boolean secondaryIpSet = _networkMgr.isSecondaryIpSetForNic(guestNic.getId());
if (!secondaryIpSet) {
throw new InvalidParameterValueException("VM ip " + vmGuestIp + " address not belongs to the vm");
}
//check the ip belongs to the vm or not
nicSecIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmGuestIp, guestNic.getId());
if (nicSecIp == null) {
throw new InvalidParameterValueException("VM ip " + vmGuestIp + " address not belongs to the vm");
}
dstIp = nicSecIp.getIp4Address();
// Set public ip column with the vm ip
}
}
// Verify ip address parameter
isIpReadyForStaticNat(vmId, ipAddress, caller, ctx.getCallerUserId());
// checking vm id is not sufficient, check for the vm ip
isIpReadyForStaticNat(vmId, ipAddress, dstIp, caller, ctx.getCallerUserId());
}
ipAddress.setOneToOneNat(true);
ipAddress.setAssociatedWithVmId(vmId);
ipAddress.setVmIp(dstIp);
if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) {
// enable static nat on the backend
s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
@ -483,6 +528,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
ipAddress.setOneToOneNat(isOneToOneNat);
ipAddress.setAssociatedWithVmId(associatedWithVmId);
ipAddress.setVmIp(null);
_ipAddressDao.update(ipAddress.getId(), ipAddress);
}
} else {
@ -490,16 +536,17 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
}
} finally {
if (performedIpAssoc) {
//if the rule is the last one for the ip address assigned to VPC, unassign it from the network
IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
_vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
if (performedIpAssoc) {
//if the rule is the last one for the ip address assigned to VPC, unassign it from the network
IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
_vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
}
}
return false;
}
protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId)
protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress,
String vmIp, Account caller, long callerUserId)
throws NetworkRuleConflictException, ResourceUnavailableException {
if (ipAddress.isSourceNat()) {
throw new InvalidParameterValueException("Can't enable static, ip address " + ipAddress + " is a sourceNat ip address");
@ -519,7 +566,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
throw new NetworkRuleConflictException("Failed to enable static for the ip address " + ipAddress + " and vm id=" + vmId + " as it's already assigned to antoher vm");
}
IPAddressVO oldIP = _ipAddressDao.findByAssociatedVmId(vmId);
//check wether the vm ip is alreday associated with any public ip address
IPAddressVO oldIP = _ipAddressDao.findByAssociatedVmIdAndVmIp(vmId, vmIp);
if (oldIP != null) {
// If elasticIP functionality is supported in the network, we always have to disable static nat on the old
@ -538,9 +586,9 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
if (!reassignStaticNat) {
throw new InvalidParameterValueException("Failed to enable static nat for the ip address id=" + ipAddress.getId() + " as vm id=" + vmId + " is already associated with ip id=" + oldIP.getId());
}
// unassign old static nat rule
s_logger.debug("Disassociating static nat for ip " + oldIP);
if (!disableStaticNat(oldIP.getId(), caller, callerUserId, true)) {
// unassign old static nat rule
s_logger.debug("Disassociating static nat for ip " + oldIP);
if (!disableStaticNat(oldIP.getId(), caller, callerUserId, true)) {
throw new CloudRuntimeException("Failed to disable old static nat rule for vm id=" + vmId + " and ip " + oldIP);
}
}
@ -890,8 +938,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
List<StaticNat> staticNats = new ArrayList<StaticNat>();
for (IPAddressVO ip : ips) {
// Get nic IP4 address
String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), networkId);
StaticNatImpl staticNat = new StaticNatImpl(ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), networkId, ip.getId(), dstIp, false);
//String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), networkId);
StaticNatImpl staticNat = new StaticNatImpl(ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), networkId, ip.getId(), ip.getVmIp(), false);
staticNats.add(staticNat);
}
@ -1209,6 +1257,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
boolean isIpSystem = ipAddress.getSystem();
ipAddress.setOneToOneNat(false);
ipAddress.setAssociatedWithVmId(null);
ipAddress.setVmIp(null);
if (isIpSystem && !releaseIpIfElastic) {
ipAddress.setSystem(false);
}
@ -1248,11 +1297,11 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
throw ex;
}
String dstIp;
if (forRevoke) {
dstIp = _networkModel.getIpInNetworkIncludingRemoved(ip.getAssociatedWithVmId(), rule.getNetworkId());
} else {
dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), rule.getNetworkId());
String dstIp = ip.getVmIp();
if (dstIp == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("VM ip address of the specified public ip is not set ");
ex.addProxyObject(ruleVO, rule.getId(), "ruleId");
throw ex;
}
return new StaticNatRuleImpl(ruleVO, dstIp);
@ -1333,12 +1382,16 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
// create new static nat rule
// Get nic IP4 address
Nic guestNic = _networkModel.getNicInNetwork(vm.getId(), networkId);
if (guestNic == null) {
throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
}
String dstIp;
if (forRevoke) {
dstIp = _networkModel.getIpInNetworkIncludingRemoved(sourceIp.getAssociatedWithVmId(), networkId);
} else {
dstIp = _networkModel.getIpInNetwork(sourceIp.getAssociatedWithVmId(), networkId);
dstIp = sourceIp.getVmIp();
if (dstIp == null) {
throw new InvalidParameterValueException("Vm ip is not set as dnat ip for this public ip");
}
StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(),
@ -1373,7 +1426,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
boolean isSystemVM = (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm);
try {
success = enableStaticNat(ip.getId(), vm.getId(), guestNetwork.getId(), isSystemVM);
success = enableStaticNat(ip.getId(), vm.getId(), guestNetwork.getId(), isSystemVM, null);
} catch (NetworkRuleConflictException ex) {
s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " +
vm + " in guest network " + guestNetwork + " due to exception ", ex);

View File

@ -41,5 +41,7 @@ public interface PortForwardingRulesDao extends GenericDao<PortForwardingRuleVO,
List<PortForwardingRuleVO> listByNetwork(long networkId);
List<PortForwardingRuleVO> listByAccount(long accountId);
List<PortForwardingRuleVO> listByDestIpAddr(String ip4Address);
}

View File

@ -32,6 +32,7 @@ import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.vm.dao.NicSecondaryIpVO;
@Component
@Local(value=PortForwardingRulesDao.class)
@ -55,6 +56,7 @@ public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRul
AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
AllFieldsSearch.and("vmId", AllFieldsSearch.entity().getVirtualMachineId(), Op.EQ);
AllFieldsSearch.and("purpose", AllFieldsSearch.entity().getPurpose(), Op.EQ);
AllFieldsSearch.and("dstIp", AllFieldsSearch.entity().getDestinationIpAddress(), Op.EQ);
AllFieldsSearch.done();
ApplicationSearch = createSearchBuilder();
@ -149,5 +151,11 @@ public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRul
return listBy(sc);
}
@Override
public List<PortForwardingRuleVO> listByDestIpAddr(String ip4Address) {
SearchCriteria<PortForwardingRuleVO> sc = AllFieldsSearch.create();
sc.setParameters("address", ip4Address);
return listBy(sc);
}
}

View File

@ -2165,6 +2165,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(CreateVMSnapshotCmd.class);
cmdList.add(RevertToSnapshotCmd.class);
cmdList.add(DeleteVMSnapshotCmd.class);
cmdList.add(AddIpToVmNicCmd.class);
cmdList.add(RemoveIpFromVmNicCmd.class);
cmdList.add(ListNicsCmd.class);
return cmdList;
}

View File

@ -122,6 +122,9 @@ public class NicVO implements Nic {
@Column(name = "uuid")
String uuid = UUID.randomUUID().toString();
@Column(name = "secondary_ip")
boolean secondaryIp;
public NicVO(String reserver, Long instanceId, long configurationId, VirtualMachine.Type vmType) {
this.reserver = reserver;
this.instanceId = instanceId;
@ -349,4 +352,12 @@ public class NicVO implements Nic {
public void setIp6Cidr(String ip6Cidr) {
this.ip6Cidr = ip6Cidr;
}
public boolean getSecondaryIp() {
return secondaryIp;
}
public void setSecondaryIp(boolean secondaryIp) {
this.secondaryIp = secondaryIp;
}
}

View File

@ -360,6 +360,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
protected ProjectManager _projectMgr;
@Inject
protected ResourceManager _resourceMgr;
@Inject
protected NetworkServiceMapDao _ntwkSrvcDao;
@Inject
@ -1359,6 +1360,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
+ " as a part of vm id=" + vmId
+ " expunge because resource is unavailable", e);
}
//remove vm secondary ip addresses
if (_networkMgr.removeVmSecondaryIps(vmId)) {
s_logger.debug("Removed vm " + vmId + " secondary ip address of the VM Nics as a part of expunge process");
} else {
success = false;
s_logger.warn("Fail to remove secondary ip address of vm " + vmId + " Nics as a part of expunge process");
}
return success;
}

View File

@ -58,4 +58,6 @@ public interface NicDao extends GenericDao<NicVO, Long> {
NicVO findByNetworkIdInstanceIdAndBroadcastUri(long networkId, long instanceId, String broadcastUri);
NicVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, long instanceId, String ip4Address);
List<NicVO> listByVmIdAndNicId(Long vmId, Long nicId);
}

View File

@ -53,8 +53,10 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.EQ);
AllFieldsSearch.and("isDefault", AllFieldsSearch.entity().isDefaultNic(), Op.EQ);
AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ);
AllFieldsSearch.and("secondaryip", AllFieldsSearch.entity().getSecondaryIp(), Op.EQ);
AllFieldsSearch.and("nicid", AllFieldsSearch.entity().getId(), Op.EQ);
AllFieldsSearch.done();
IpSearch = createSearchBuilder(String.class);
IpSearch.select(null, Func.DISTINCT, IpSearch.entity().getIp4Address());
IpSearch.and("network", IpSearch.entity().getNetworkId(), Op.EQ);
@ -202,4 +204,12 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
sc.setParameters("address", ip4Address);
return findOneBy(sc);
}
@Override
public List<NicVO> listByVmIdAndNicId(Long vmId, Long nicId) {
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
sc.setParameters("instance", vmId);
sc.setParameters("nicid", nicId);
return listBy(sc);
}
}

View File

@ -0,0 +1,53 @@
// 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.dao;
import java.util.List;
import com.cloud.utils.db.GenericDao;
public interface NicSecondaryIpDao extends GenericDao<NicSecondaryIpVO, Long> {
List<NicSecondaryIpVO> listByVmId(long instanceId);
List<String> listSecondaryIpAddressInNetwork(long networkConfigId);
List<NicSecondaryIpVO> listByNetworkId(long networkId);
NicSecondaryIpVO findByInstanceIdAndNetworkId(long networkId, long instanceId);
// void removeNicsForInstance(long instanceId);
// void removeSecondaryIpForNic(long nicId);
NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId);
/**
* @param networkId
* @param instanceId
* @return
*/
List<NicSecondaryIpVO> getSecondaryIpAddressesForVm(long vmId);
List<NicSecondaryIpVO> listByNicId(long nicId);
List<NicSecondaryIpVO> listByNicIdAndVmid(long nicId, long vmId);
NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId);
NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId,
Long vmId, String vmIp);
List<String> getSecondaryIpAddressesForNic(long nicId);
}

View File

@ -0,0 +1,138 @@
// 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.dao;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Local;
import org.springframework.stereotype.Component;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
@Component
@Local(value=NicSecondaryIpDao.class)
public class NicSecondaryIpDaoImpl extends GenericDaoBase<NicSecondaryIpVO, Long> implements NicSecondaryIpDao {
private final SearchBuilder<NicSecondaryIpVO> AllFieldsSearch;
private final GenericSearchBuilder<NicSecondaryIpVO, String> IpSearch;
protected NicSecondaryIpDaoImpl() {
super();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getVmId(), Op.EQ);
AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.EQ);
AllFieldsSearch.and("nicId", AllFieldsSearch.entity().getNicId(), Op.EQ);
AllFieldsSearch.done();
IpSearch = createSearchBuilder(String.class);
IpSearch.select(null, Func.DISTINCT, IpSearch.entity().getIp4Address());
IpSearch.and("network", IpSearch.entity().getNetworkId(), Op.EQ);
IpSearch.and("address", IpSearch.entity().getIp4Address(), Op.NNULL);
IpSearch.done();
}
@Override
public List<NicSecondaryIpVO> listByVmId(long instanceId) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", instanceId);
return listBy(sc);
}
@Override
public List<NicSecondaryIpVO> listByNicId(long nicId) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("nicId", nicId);
return listBy(sc);
}
@Override
public List<String> listSecondaryIpAddressInNetwork(long networkId) {
SearchCriteria<String> sc = IpSearch.create();
sc.setParameters("network", networkId);
return customSearch(sc, null);
}
@Override
public List<NicSecondaryIpVO> listByNetworkId(long networkId) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
return listBy(sc);
}
@Override
public List<NicSecondaryIpVO> listByNicIdAndVmid(long nicId, long vmId) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("nicId", nicId);
sc.setParameters("instanceId", vmId);
return listBy(sc);
}
@Override
public List<NicSecondaryIpVO> getSecondaryIpAddressesForVm(long vmId) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("instanceId", vmId);
return listBy(sc);
}
@Override
public List<String> getSecondaryIpAddressesForNic(long nicId) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("nicId", nicId);
List<NicSecondaryIpVO> results = search(sc, null);
List<String> ips = new ArrayList<String>(results.size());
for (NicSecondaryIpVO result : results) {
ips.add(result.getIp4Address());
}
return ips;
}
@Override
public NicSecondaryIpVO findByInstanceIdAndNetworkId(long networkId, long instanceId) {
// TODO Auto-generated method stub
return null;
}
@Override
public NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId) {
// TODO Auto-generated method stub
return null;
}
@Override
public NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("address", ip4Address);
sc.setParameters("nicId", nicId);
return findOneBy(sc);
}
@Override
public NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(
long networkId, Long vmId, String vmIp) {
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("instanceId", vmId);
sc.setParameters("address", vmIp);
return findOneBy(sc);
}
}

View File

@ -0,0 +1,160 @@
// 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.dao;
import java.util.Date;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.utils.db.GenericDao;
import com.cloud.vm.NicSecondaryIp;
@Entity
@Table(name = "nic_secondary_ips")
public class NicSecondaryIpVO implements NicSecondaryIp {
public NicSecondaryIpVO(Long nicId, String ipaddr, Long vmId,
Long accountId, Long domainId, Long networkId) {
this.nicId = nicId;
this.vmId = vmId;
this.ip4Address = ipaddr;
this.accountId = accountId;
this.domainId = domainId;
this.networkId = networkId;
}
protected NicSecondaryIpVO() {
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
long id;
@Column(name = "nicId")
long nicId;
@Column(name="domain_id", updatable=false)
long domainId;
@Column(name="account_id", updatable=false)
private Long accountId;
@Column(name = "ip4_address")
String ip4Address;
@Column(name = "ip6_address")
String ip6Address;
@Column(name = "network_id")
long networkId;
@Column(name = GenericDao.CREATED_COLUMN)
Date created;
@Column(name = "uuid")
String uuid = UUID.randomUUID().toString();
@Column(name = "vmId")
Long vmId;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getNicId() {
return nicId;
}
public void setNicId(long nicId) {
this.nicId = nicId;
}
public long getDomainId() {
return domainId;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
public long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public String getIp4Address() {
return ip4Address;
}
public void setIp4Address(String ip4Address) {
this.ip4Address = ip4Address;
}
public String getIp6Address() {
return ip6Address;
}
public void setIp6Address(String ip6Address) {
this.ip6Address = ip6Address;
}
public long getNetworkId() {
return networkId;
}
public void setNetworkId(long networkId) {
this.networkId = networkId;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public long getVmId() {
return vmId;
}
public void setVmId(Long vmId) {
this.vmId = vmId;
}
}

View File

@ -29,6 +29,7 @@ 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.springframework.stereotype.Component;
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Vlan.VlanType;
@ -64,6 +65,7 @@ import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
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;
@ -824,4 +826,49 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isSecondaryIpSetForNic(long nicId) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean releaseSecondaryIpFromNic(long ipAddressId) {
// TODO Auto-generated method stub
return false;
}
@Override
public String allocateSecondaryGuestIP(Account account, long zoneId,
Long nicId, Long networkId, String ipaddress) {
// TODO Auto-generated method stub
return null;
}
@Override
public String allocateGuestIP(Account ipOwner, boolean isSystem,
long zoneId, Long networkId, String requestedIp)
throws InsufficientAddressCapacityException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean removeVmSecondaryIps(long vmId) {
// TODO Auto-generated method stub
return false;
}
@Override
public List<? extends Nic> listVmNics(Long vmId, Long nicId) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<? extends Nic> listNics(ListNicsCmd listNicsCmd) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -39,6 +39,7 @@ import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.net.Ip;
import com.cloud.vm.VirtualMachine;
@Local(value = {RulesManager.class, RulesService.class})
@ -53,14 +54,6 @@ public class MockRulesManagerImpl extends ManagerBase implements RulesManager, R
return null;
}
@Override
public PortForwardingRule createPortForwardingRule(PortForwardingRule rule,
Long vmId, boolean openFirewall)
throws NetworkRuleConflictException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean revokePortForwardingRule(long ruleId, boolean apply) {
// TODO Auto-generated method stub
@ -83,7 +76,7 @@ public class MockRulesManagerImpl extends ManagerBase implements RulesManager, R
@Override
public boolean enableStaticNat(long ipAddressId, long vmId, long networkId,
boolean isSystemVm) throws NetworkRuleConflictException,
boolean isSystemVm, String ipAddr) throws NetworkRuleConflictException,
ResourceUnavailableException {
// TODO Auto-generated method stub
return false;
@ -310,4 +303,12 @@ public class MockRulesManagerImpl extends ManagerBase implements RulesManager, R
return "MockRulesManagerImpl";
}
@Override
public PortForwardingRule createPortForwardingRule(PortForwardingRule rule,
Long vmId, Ip vmIp, boolean openFirewall)
throws NetworkRuleConflictException {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -29,6 +29,7 @@ import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementors
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 org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@ -80,6 +81,7 @@ import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
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;
@ -1317,4 +1319,75 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isSecondaryIpSetForNic(long nicId) {
// TODO Auto-generated method stub
return false;
}
@Override
public String allocateSecondaryGuestIP(Account account, long zoneId,
Long nicId, Long networkId, String ipaddress) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean releaseSecondaryIpFromNic(long ipAddressId) {
// TODO Auto-generated method stub
return false;
}
@Override
public String allocateGuestIP(Account ipOwner, boolean isSystem,
long zoneId, Long networkId, String requestedIp)
throws InsufficientAddressCapacityException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean removeVmSecondaryIps(long vmId) {
// TODO Auto-generated method stub
return false;
}
@Override
public List<? extends Nic> listVmNics(Long vmId, Long nicId) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<? extends Nic> listNics(ListNicsCmd listNicsCmd) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -112,3 +112,24 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'UserV
-- Re-enable foreign key checking, at the end of the upgrade path
SET foreign_key_checks = 1;
CREATE TABLE nic_secondary_ips (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
`uuid` varchar(40),
`vmId` bigint unsigned COMMENT 'vm instance id',
`nicId` bigint unsigned NOT NULL,
`ip4_address` char(40) COMMENT 'ip4 address',
`ip6_address` char(40) COMMENT 'ip6 address',
`network_id` bigint unsigned NOT NULL COMMENT 'network configuration id',
`created` datetime NOT NULL COMMENT 'date created',
`account_id` bigint unsigned NOT NULL COMMENT 'owner. foreign key to account table',
`domain_id` bigint unsigned NOT NULL COMMENT 'the domain that the owner belongs to',
PRIMARY KEY (`id`),
CONSTRAINT `fk_nic_secondary_ip__vmId` FOREIGN KEY `fk_nic_secondary_ip__vmId`(`vmId`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_nic_secondary_ip__networks_id` FOREIGN KEY `fk_nic_secondary_ip__networks_id`(`network_id`) REFERENCES `networks`(`id`),
CONSTRAINT `uc_nic_secondary_ip__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `cloud`.`nics` ADD COLUMN secondary_ip SMALLINT DEFAULT '0' COMMENT 'secondary ips configured for the nic';
ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN dnat_vmip VARCHAR(40);