mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Dedicate Public IP range
This commit is contained in:
parent
68a30d41db
commit
d6ed8d7cb5
@ -35,7 +35,9 @@ import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd
|
||||
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
|
||||
@ -234,6 +236,10 @@ public interface ConfigurationService {
|
||||
|
||||
boolean deleteVlanIpRange(DeleteVlanIpRangeCmd cmd);
|
||||
|
||||
Vlan dedicatePublicIpRange(DedicatePublicIpRangeCmd cmd) throws ResourceAllocationException;
|
||||
|
||||
boolean releasePublicIpRange(ReleasePublicIpRangeCmd cmd);
|
||||
|
||||
NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd);
|
||||
|
||||
NetworkOffering updateNetworkOffering(UpdateNetworkOfferingCmd cmd);
|
||||
|
||||
@ -223,6 +223,8 @@ public class EventTypes {
|
||||
// VLANs/IP ranges
|
||||
public static final String EVENT_VLAN_IP_RANGE_CREATE = "VLAN.IP.RANGE.CREATE";
|
||||
public static final String EVENT_VLAN_IP_RANGE_DELETE = "VLAN.IP.RANGE.DELETE";
|
||||
public static final String EVENT_VLAN_IP_RANGE_DEDICATE = "VLAN.IP.RANGE.DEDICATE";
|
||||
public static final String EVENT_VLAN_IP_RANGE_RELEASE = "VLAN.IP.RANGE.RELEASE";
|
||||
|
||||
public static final String EVENT_STORAGE_IP_RANGE_CREATE = "STORAGE.IP.RANGE.CREATE";
|
||||
public static final String EVENT_STORAGE_IP_RANGE_DELETE = "STORAGE.IP.RANGE.DELETE";
|
||||
|
||||
@ -0,0 +1,116 @@
|
||||
// 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.admin.vlan;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.dc.Vlan;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "dedicatePublicIpRange", description="Dedicates a Public IP range to an account", responseObject=VlanIpRangeResponse.class)
|
||||
public class DedicatePublicIpRangeCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(DedicatePublicIpRangeCmd.class.getName());
|
||||
|
||||
private static final String s_name = "dedicatepubliciprangeresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = VlanIpRangeResponse.class,
|
||||
required=true, description="the id of the VLAN IP range")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, required=true,
|
||||
description="account who will own the VLAN")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class,
|
||||
description="project who will own the VLAN")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType = DomainResponse.class,
|
||||
required=true, description="domain ID of the account owning a VLAN")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
|
||||
required=true, description="the Zone ID of the VLAN IP range")
|
||||
private Long zoneId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, ResourceAllocationException {
|
||||
Vlan result = _configService.dedicatePublicIpRange(this);
|
||||
if (result != null) {
|
||||
VlanIpRangeResponse response = _responseGenerator.createVlanIpRangeResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate vlan ip range");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
// 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.admin.vlan;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "releasePublicIpRange", description="Releases a Public IP range back to the system pool", responseObject=SuccessResponse.class)
|
||||
public class ReleasePublicIpRangeCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ReleasePublicIpRangeCmd.class.getName());
|
||||
|
||||
private static final String s_name = "releasepubliciprangeresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = VlanIpRangeResponse.class,
|
||||
required=true, description="the id of the Public IP range")
|
||||
private Long id;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
boolean result = _configService.releasePublicIpRange(this);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release public ip range");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,6 +124,8 @@ listDiskOfferings=15
|
||||
createVlanIpRange=1
|
||||
deleteVlanIpRange=1
|
||||
listVlanIpRanges=1
|
||||
dedicatePublicIpRange=1
|
||||
releasePublicIpRange=1
|
||||
|
||||
#### address commands
|
||||
associateIpAddress=15
|
||||
|
||||
@ -30,6 +30,7 @@ import com.cloud.dc.Vlan;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Provider;
|
||||
@ -149,6 +150,10 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
|
||||
*/
|
||||
boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId, Account caller);
|
||||
|
||||
boolean releasePublicIpRange(long userId, long vlanDbId, Account caller);
|
||||
|
||||
Vlan dedicatePublicIpRange(Long vlanDbId, String accountName, Long domainId, Long zoneId, Long projectId) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* Converts a comma separated list of tags to a List
|
||||
*
|
||||
@ -210,7 +215,7 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
|
||||
|
||||
ClusterVO getCluster(long id);
|
||||
|
||||
boolean deleteAccountSpecificVirtualRanges(long accountId);
|
||||
boolean releaseAccountSpecificVirtualRanges(long accountId);
|
||||
|
||||
/**
|
||||
* Edits a pod in the database. Will not allow you to edit pods that are being used anywhere in the system.
|
||||
|
||||
@ -56,7 +56,9 @@ import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd
|
||||
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
|
||||
@ -2306,9 +2308,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
throw new InvalidParameterValueException("Gateway, netmask and zoneId have to be passed in for virtual and direct untagged networks");
|
||||
}
|
||||
|
||||
// if it's an account specific range, associate ip address list to the account
|
||||
boolean associateIpRangeToAccount = false;
|
||||
|
||||
if (forVirtualNetwork) {
|
||||
if (vlanOwner != null) {
|
||||
|
||||
@ -2316,8 +2315,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
|
||||
//check resource limits
|
||||
_resourceLimitMgr.checkResourceLimit(vlanOwner, ResourceType.public_ip, accountIpRange);
|
||||
|
||||
associateIpRangeToAccount = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2332,21 +2329,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
endIP, vlanGateway, vlanNetmask, vlanId, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
|
||||
|
||||
txn.commit();
|
||||
if (associateIpRangeToAccount) {
|
||||
_networkMgr.associateIpAddressListToAccount(userId, vlanOwner.getId(), zoneId, vlan.getId(), null);
|
||||
}
|
||||
|
||||
// Associate ips to the network
|
||||
if (associateIpRangeToAccount) {
|
||||
if (network.getState() == Network.State.Implemented) {
|
||||
s_logger.debug("Applying ip associations for vlan id=" + vlanId + " in network " + network);
|
||||
if (!_networkMgr.applyIpAssociations(network, false)) {
|
||||
s_logger.warn("Failed to apply ip associations for vlan id=1 as a part of add vlan range for account id=" + vlanOwner.getId());
|
||||
}
|
||||
} else {
|
||||
s_logger.trace("Network id=" + network.getId() + " is not Implemented, no need to apply ipAssociations");
|
||||
}
|
||||
}
|
||||
|
||||
return vlan;
|
||||
}
|
||||
@ -2698,6 +2680,156 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_DEDICATE, eventDescription = "dedicating vlan ip range", async = false)
|
||||
public Vlan dedicatePublicIpRange(DedicatePublicIpRangeCmd cmd) throws ResourceAllocationException {
|
||||
Long vlanDbId = cmd.getId();
|
||||
String accountName = cmd.getAccountName();
|
||||
Long domainId = cmd.getDomainId();
|
||||
Long zoneId = cmd.getZoneId();
|
||||
Long projectId = cmd.getProjectId();
|
||||
|
||||
Vlan vlan = dedicatePublicIpRange(vlanDbId, accountName, domainId, zoneId, projectId);
|
||||
|
||||
return vlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public Vlan dedicatePublicIpRange(Long vlanDbId, String accountName, Long domainId, Long zoneId, Long projectId) throws ResourceAllocationException {
|
||||
// Check if account is valid
|
||||
Account vlanOwner = null;
|
||||
if (projectId != null) {
|
||||
if (accountName != null) {
|
||||
throw new InvalidParameterValueException("accountName and projectId are mutually exclusive");
|
||||
}
|
||||
Project project = _projectMgr.getProject(projectId);
|
||||
if (project == null) {
|
||||
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
|
||||
}
|
||||
vlanOwner = _accountMgr.getAccount(project.getProjectAccountId());
|
||||
}
|
||||
|
||||
if ((accountName != null) && (domainId != null)) {
|
||||
vlanOwner = _accountDao.findActiveAccount(accountName, domainId);
|
||||
if (vlanOwner == null) {
|
||||
throw new InvalidParameterValueException("Please specify a valid account");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if range is valid
|
||||
VlanVO vlan = _vlanDao.findById(vlanDbId);
|
||||
if (vlan == null) {
|
||||
throw new InvalidParameterValueException("Please specify a valid Public IP range id");
|
||||
}
|
||||
|
||||
// Check if range has already been dedicated
|
||||
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanDbId);
|
||||
if (maps != null && !maps.isEmpty()) {
|
||||
throw new InvalidParameterValueException("Specified Public IP range has already been dedicated");
|
||||
}
|
||||
|
||||
// Verify that zone exists and is advanced
|
||||
DataCenterVO zone = _zoneDao.findById(zoneId);
|
||||
if (zone == null) {
|
||||
throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
|
||||
}
|
||||
if (zone.getNetworkType() == NetworkType.Basic) {
|
||||
throw new InvalidParameterValueException("Public IP range can be dedicated to an account only in the zone of type " + NetworkType.Advanced);
|
||||
}
|
||||
|
||||
// Check Public IP resource limits
|
||||
int accountPublicIpRange = _publicIpAddressDao.countIPs(zoneId, vlanDbId, false);
|
||||
_resourceLimitMgr.checkResourceLimit(vlanOwner, ResourceType.public_ip, accountPublicIpRange);
|
||||
|
||||
// Check if any of the Public IP addresses is allocated to another account
|
||||
List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
|
||||
for (IPAddressVO ip : ips) {
|
||||
Long allocatedToAccountId = ip.getAllocatedToAccountId();
|
||||
if (allocatedToAccountId != null) {
|
||||
Account accountAllocatedTo = _accountMgr.getActiveAccountById(allocatedToAccountId);
|
||||
if (!accountAllocatedTo.getAccountName().equalsIgnoreCase(accountName))
|
||||
throw new InvalidParameterValueException("Public IP address in range is already allocated to another account");
|
||||
}
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
// Create an AccountVlanMapVO entry
|
||||
AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO(vlanOwner.getId(), vlan.getId());
|
||||
_accountVlanMapDao.persist(accountVlanMapVO);
|
||||
|
||||
txn.commit();
|
||||
|
||||
return vlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_RELEASE, eventDescription = "releasing a public ip range", async = false)
|
||||
public boolean releasePublicIpRange(ReleasePublicIpRangeCmd cmd) {
|
||||
Long vlanDbId = cmd.getId();
|
||||
|
||||
VlanVO vlan = _vlanDao.findById(vlanDbId);
|
||||
if (vlan == null) {
|
||||
throw new InvalidParameterValueException("Please specify a valid IP range id.");
|
||||
}
|
||||
|
||||
return releasePublicIpRange(vlanDbId, UserContext.current().getCallerUserId(), UserContext.current().getCaller());
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public boolean releasePublicIpRange(long vlanDbId, long userId, Account caller) {
|
||||
VlanVO vlan = _vlanDao.findById(vlanDbId);
|
||||
|
||||
List<AccountVlanMapVO> acctVln = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanDbId);
|
||||
// Verify range is dedicated
|
||||
if (acctVln == null || acctVln.isEmpty()) {
|
||||
throw new InvalidParameterValueException("Can't release Public IP range " + vlanDbId + " as it not dedicated to any account");
|
||||
}
|
||||
|
||||
// Check if range has any allocated public IPs
|
||||
long allocIpCount = _publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true);
|
||||
boolean success = true;
|
||||
if (allocIpCount > 0) {
|
||||
try {
|
||||
vlan = _vlanDao.acquireInLockTable(vlanDbId, 30);
|
||||
if (vlan == null) {
|
||||
throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId);
|
||||
}
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("lock vlan " + vlanDbId + " is acquired");
|
||||
}
|
||||
List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
|
||||
for (IPAddressVO ip : ips) {
|
||||
// Disassociate allocated IP's that are not in use
|
||||
if ( !ip.isOneToOneNat() && !(ip.isSourceNat() && _networkModel.getNetwork(ip.getAssociatedWithNetworkId()) != null) &&
|
||||
!(_firewallDao.countRulesByIpId(ip.getId()) > 0) ) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Releasing Public IP addresses" + ip +" of vlan " + vlanDbId + " as part of Public IP" +
|
||||
" range release to the system pool");
|
||||
}
|
||||
success = success && _networkMgr.disassociatePublicIpAddress(ip.getId(), userId, caller);
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
s_logger.warn("Some Public IP addresses that were not in use failed to be released as a part of" +
|
||||
" vlan " + vlanDbId + "release to the system pool");
|
||||
}
|
||||
} finally {
|
||||
_vlanDao.releaseFromLockTable(vlanDbId);
|
||||
}
|
||||
}
|
||||
|
||||
// A Public IP range can only be dedicated to one account at a time
|
||||
if (_accountVlanMapDao.remove(acctVln.get(0).getId())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> csvTagsToList(String tags) {
|
||||
List<String> tagsList = new ArrayList<String>();
|
||||
@ -3957,14 +4089,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public boolean deleteAccountSpecificVirtualRanges(long accountId) {
|
||||
public boolean releaseAccountSpecificVirtualRanges(long accountId) {
|
||||
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId);
|
||||
boolean result = true;
|
||||
if (maps != null && !maps.isEmpty()) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
for (AccountVlanMapVO map : maps) {
|
||||
if (!deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), map.getVlanDbId(),
|
||||
if (!releasePublicIpRange(map.getVlanDbId(), _accountMgr.getSystemUser().getId(),
|
||||
_accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) {
|
||||
result = false;
|
||||
}
|
||||
@ -3972,10 +4104,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
if (result) {
|
||||
txn.commit();
|
||||
} else {
|
||||
s_logger.error("Failed to delete account specific virtual ip ranges for account id=" + accountId);
|
||||
s_logger.error("Failed to release account specific virtual ip ranges for account id=" + accountId);
|
||||
}
|
||||
} else {
|
||||
s_logger.trace("Account id=" + accountId + " has no account specific virtual ip ranges, nothing to delete");
|
||||
s_logger.trace("Account id=" + accountId + " has no account specific virtual ip ranges, nothing to release");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -188,6 +188,7 @@ import com.cloud.vm.ReservationContextImpl;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.*;
|
||||
import com.cloud.vm.VirtualMachine.Type;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
@ -348,7 +349,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
}
|
||||
|
||||
@DB
|
||||
public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse,
|
||||
public PublicIp fetchNewPublicIp(long dcId, Long podId, List<Long> vlanDbIds, Account owner, VlanType vlanUse,
|
||||
Long guestNetworkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem, Long vpcId)
|
||||
throws InsufficientAddressCapacityException {
|
||||
StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in ");
|
||||
@ -364,9 +365,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
errorMessage.append(" zone id=" + dcId);
|
||||
}
|
||||
|
||||
if (vlanDbId != null) {
|
||||
sc.addAnd("vlanId", SearchCriteria.Op.EQ, vlanDbId);
|
||||
errorMessage.append(", vlanId id=" + vlanDbId);
|
||||
if ( vlanDbIds != null && !vlanDbIds.isEmpty() ) {
|
||||
sc.setParameters("vlanId", vlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + vlanDbIds.toArray());
|
||||
}
|
||||
|
||||
sc.setParameters("dc", dcId);
|
||||
@ -526,14 +527,14 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
}
|
||||
|
||||
// If account has Account specific ip ranges, try to allocate ip from there
|
||||
Long vlanId = null;
|
||||
List<Long> vlanIds = new ArrayList<Long>();
|
||||
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ownerId);
|
||||
if (maps != null && !maps.isEmpty()) {
|
||||
vlanId = maps.get(0).getVlanDbId();
|
||||
vlanIds.add(maps.get(0).getVlanDbId());
|
||||
}
|
||||
|
||||
|
||||
ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, guestNtwkId,
|
||||
ip = fetchNewPublicIp(dcId, null, vlanIds, owner, VlanType.VirtualNetwork, guestNtwkId,
|
||||
isSourceNat, false, null, false, vpcId);
|
||||
IPAddressVO publicIp = ip.ip();
|
||||
|
||||
@ -669,6 +670,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
VlanType vlanType = VlanType.VirtualNetwork;
|
||||
boolean assign = false;
|
||||
boolean allocateFromDedicatedRange = false;
|
||||
|
||||
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) {
|
||||
// zone is of type DataCenter. See DataCenterVO.java.
|
||||
@ -702,8 +704,32 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
txn.start();
|
||||
|
||||
ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null,
|
||||
false, assign, null, isSystem, null);
|
||||
// If account has dedicated Public IP ranges, allocate IP from the dedicated range
|
||||
List<Long> vlanDbIds = new ArrayList<Long>();
|
||||
List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ipOwner.getId());
|
||||
for (AccountVlanMapVO map : maps) {
|
||||
vlanDbIds.add(map.getVlanDbId());
|
||||
}
|
||||
if (vlanDbIds != null && !vlanDbIds.isEmpty()) {
|
||||
allocateFromDedicatedRange = true;
|
||||
}
|
||||
|
||||
try {
|
||||
if (allocateFromDedicatedRange) {
|
||||
ip = fetchNewPublicIp(zone.getId(), null, vlanDbIds, ipOwner, vlanType, null,
|
||||
false, assign, null, isSystem, null);
|
||||
}
|
||||
} catch(InsufficientAddressCapacityException e) {
|
||||
s_logger.warn("All IPs dedicated to account " + ipOwner.getId() + " has been acquired." +
|
||||
" Now acquiring from the system pool");
|
||||
txn.close();
|
||||
allocateFromDedicatedRange = false;
|
||||
}
|
||||
|
||||
if (!allocateFromDedicatedRange) {
|
||||
ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null,
|
||||
isSystem, null);
|
||||
}
|
||||
|
||||
if (ip == null) {
|
||||
|
||||
@ -1070,7 +1096,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
AssignIpAddressSearch = _ipAddressDao.createSearchBuilder();
|
||||
AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ);
|
||||
AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
|
||||
AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.EQ);
|
||||
AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.IN);
|
||||
SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
|
||||
vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
|
||||
vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ);
|
||||
|
||||
@ -697,15 +697,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
throw new IllegalArgumentException("only ip addresses that belong to a virtual network may be disassociated.");
|
||||
}
|
||||
|
||||
// Check for account wide pool. It will have an entry for account_vlan_map.
|
||||
if (_accountVlanMapDao.findAccountVlanMap(ipVO.getAllocatedToAccountId(), ipVO.getVlanId()) != null) {
|
||||
//see IPaddressVO.java
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Sepcified IP address uuid belongs to" +
|
||||
" Account wide IP pool and cannot be disassociated");
|
||||
ex.addProxyObject("user_ip_address", ipAddressId, "ipAddressId");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// don't allow releasing system ip address
|
||||
if (ipVO.getSystem()) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Can't release system IP address with specified id");
|
||||
|
||||
@ -2090,6 +2090,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
cmdList.add(CreateVlanIpRangeCmd.class);
|
||||
cmdList.add(DeleteVlanIpRangeCmd.class);
|
||||
cmdList.add(ListVlanIpRangesCmd.class);
|
||||
cmdList.add(DedicatePublicIpRangeCmd.class);
|
||||
cmdList.add(ReleasePublicIpRangeCmd.class);
|
||||
cmdList.add(AssignVMCmd.class);
|
||||
cmdList.add(MigrateVMCmd.class);
|
||||
cmdList.add(RecoverVMCmd.class);
|
||||
|
||||
@ -683,13 +683,13 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
accountCleanupNeeded = true;
|
||||
}
|
||||
|
||||
// delete account specific Virtual vlans (belong to system Public Network) - only when networks are cleaned
|
||||
// release account specific Virtual vlans (belong to system Public Network) - only when networks are cleaned
|
||||
// up successfully
|
||||
if (networksDeleted) {
|
||||
if (!_configMgr.deleteAccountSpecificVirtualRanges(accountId)) {
|
||||
if (!_configMgr.releaseAccountSpecificVirtualRanges(accountId)) {
|
||||
accountCleanupNeeded = true;
|
||||
} else {
|
||||
s_logger.debug("Account specific Virtual IP ranges " + " are successfully deleted as a part of account id=" + accountId + " cleanup.");
|
||||
s_logger.debug("Account specific Virtual IP ranges " + " are successfully released as a part of account id=" + accountId + " cleanup.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,400 @@
|
||||
package com.cloud.configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import com.cloud.configuration.Resource.ResourceType;
|
||||
import com.cloud.dc.AccountVlanMapVO;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.Vlan;
|
||||
import com.cloud.dc.VlanVO;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
import com.cloud.dc.dao.AccountVlanMapDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.dao.FirewallRulesDao;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.net.Ip;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
|
||||
public class ConfigurationManagerTest {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(ConfigurationManagerTest.class);
|
||||
|
||||
ConfigurationManagerImpl configurationMgr = new ConfigurationManagerImpl();
|
||||
|
||||
DedicatePublicIpRangeCmd dedicatePublicIpRangesCmd = new DedicatePublicIpRangeCmdExtn();
|
||||
Class<?> _dedicatePublicIpRangeClass = dedicatePublicIpRangesCmd.getClass().getSuperclass();
|
||||
|
||||
ReleasePublicIpRangeCmd releasePublicIpRangesCmd = new ReleasePublicIpRangeCmdExtn();
|
||||
Class<?> _releasePublicIpRangeClass = releasePublicIpRangesCmd.getClass().getSuperclass();
|
||||
|
||||
@Mock AccountManager _accountMgr;
|
||||
@Mock ProjectManager _projectMgr;
|
||||
@Mock ResourceLimitService _resourceLimitMgr;
|
||||
@Mock NetworkManager _networkMgr;
|
||||
@Mock AccountDao _accountDao;
|
||||
@Mock VlanDao _vlanDao;
|
||||
@Mock AccountVlanMapDao _accountVlanMapDao;
|
||||
@Mock IPAddressDao _publicIpAddressDao;
|
||||
@Mock DataCenterDao _zoneDao;
|
||||
@Mock FirewallRulesDao _firewallDao;
|
||||
|
||||
VlanVO vlan = new VlanVO();
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
configurationMgr._accountMgr = _accountMgr;
|
||||
configurationMgr._projectMgr = _projectMgr;
|
||||
configurationMgr._resourceLimitMgr = _resourceLimitMgr;
|
||||
configurationMgr._networkMgr = _networkMgr;
|
||||
configurationMgr._accountDao = _accountDao;
|
||||
configurationMgr._vlanDao = _vlanDao;
|
||||
configurationMgr._accountVlanMapDao = _accountVlanMapDao;
|
||||
configurationMgr._publicIpAddressDao = _publicIpAddressDao;
|
||||
configurationMgr._zoneDao = _zoneDao;
|
||||
configurationMgr._firewallDao = _firewallDao;
|
||||
|
||||
Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString());
|
||||
when(configurationMgr._accountMgr.getAccount(anyLong())).thenReturn(account);
|
||||
when(configurationMgr._accountDao.findActiveAccount(anyString(), anyLong())).thenReturn(account);
|
||||
when(configurationMgr._accountMgr.getActiveAccountById(anyLong())).thenReturn(account);
|
||||
|
||||
when(configurationMgr._publicIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(1);
|
||||
|
||||
doNothing().when(configurationMgr._resourceLimitMgr).checkResourceLimit(any(Account.class),
|
||||
any(ResourceType.class), anyLong());
|
||||
|
||||
when(configurationMgr._accountVlanMapDao.persist(any(AccountVlanMapVO.class))).thenReturn(new AccountVlanMapVO());
|
||||
|
||||
when(configurationMgr._vlanDao.acquireInLockTable(anyLong(), anyInt())).thenReturn(vlan);
|
||||
|
||||
UserContext.registerContext(1, account, null, true);
|
||||
|
||||
Field dedicateIdField = _dedicatePublicIpRangeClass.getDeclaredField("id");
|
||||
dedicateIdField.setAccessible(true);
|
||||
dedicateIdField.set(dedicatePublicIpRangesCmd, 1L);
|
||||
|
||||
Field accountNameField = _dedicatePublicIpRangeClass.getDeclaredField("accountName");
|
||||
accountNameField.setAccessible(true);
|
||||
accountNameField.set(dedicatePublicIpRangesCmd, "accountname");
|
||||
|
||||
Field projectIdField = _dedicatePublicIpRangeClass.getDeclaredField("projectId");
|
||||
projectIdField.setAccessible(true);
|
||||
projectIdField.set(dedicatePublicIpRangesCmd, null);
|
||||
|
||||
Field domainIdField = _dedicatePublicIpRangeClass.getDeclaredField("domainId");
|
||||
domainIdField.setAccessible(true);
|
||||
domainIdField.set(dedicatePublicIpRangesCmd, 1L);
|
||||
|
||||
Field zoneIdField = _dedicatePublicIpRangeClass.getDeclaredField("zoneId");
|
||||
zoneIdField.setAccessible(true);
|
||||
zoneIdField.set(dedicatePublicIpRangesCmd, 1L);
|
||||
|
||||
Field releaseIdField = _releasePublicIpRangeClass.getDeclaredField("id");
|
||||
releaseIdField.setAccessible(true);
|
||||
releaseIdField.set(releasePublicIpRangesCmd, 1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDedicatePublicIpRange() throws Exception {
|
||||
|
||||
s_logger.info("Running tests for DedicatePublicIpRange API");
|
||||
|
||||
/*
|
||||
* TEST 1: given valid parameters DedicatePublicIpRange should succeed
|
||||
*/
|
||||
runDedicatePublicIpRangePostiveTest();
|
||||
|
||||
/*
|
||||
* TEST 2: given invalid public ip range DedicatePublicIpRange should fail
|
||||
*/
|
||||
runDedicatePublicIpRangeInvalidRange();
|
||||
/*
|
||||
* TEST 3: given public IP range that is already dedicated to a different account DedicatePublicIpRange should fail
|
||||
*/
|
||||
runDedicatePublicIpRangeDedicatedRange();
|
||||
|
||||
/*
|
||||
* TEST 4: given zone is of type Basic DedicatePublicIpRange should fail
|
||||
*/
|
||||
runDedicatePublicIpRangeInvalidZone();
|
||||
|
||||
/*
|
||||
* TEST 5: given range is already allocated to a different account DedicatePublicIpRange should fail
|
||||
*/
|
||||
runDedicatePublicIpRangeIPAdressAllocated();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleasePublicIpRange() throws Exception {
|
||||
|
||||
s_logger.info("Running tests for DedicatePublicIpRange API");
|
||||
|
||||
/*
|
||||
* TEST 1: given valid parameters and no allocated public ip's in the range ReleasePublicIpRange should succeed
|
||||
*/
|
||||
runReleasePublicIpRangePostiveTest1();
|
||||
|
||||
/*
|
||||
* TEST 2: given valid parameters ReleasePublicIpRange should succeed
|
||||
*/
|
||||
runReleasePublicIpRangePostiveTest2();
|
||||
|
||||
/*
|
||||
* TEST 3: given range doesn't exist
|
||||
*/
|
||||
runReleasePublicIpRangeInvalidIpRange();
|
||||
|
||||
/*
|
||||
* TEST 4: given range is not dedicated to any account
|
||||
*/
|
||||
runReleaseNonDedicatedPublicIpRange();
|
||||
}
|
||||
|
||||
void runDedicatePublicIpRangePostiveTest() throws Exception {
|
||||
Transaction txn = Transaction.open("runDedicatePublicIpRangePostiveTest");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
|
||||
|
||||
when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByAccount(anyLong())).thenReturn(null);
|
||||
|
||||
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
|
||||
null, null, NetworkType.Advanced, null, null, true, true, null, null);
|
||||
when(configurationMgr._zoneDao.findById(anyLong())).thenReturn(dc);
|
||||
|
||||
List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
|
||||
IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
|
||||
ipAddressList.add(ipAddress);
|
||||
when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
|
||||
|
||||
try {
|
||||
Vlan result = configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
|
||||
Assert.assertNotNull(result);
|
||||
} catch (Exception e) {
|
||||
s_logger.info("exception in testing runDedicatePublicIpRangePostiveTest message: " + e.toString());
|
||||
} finally {
|
||||
txn.close("runDedicatePublicIpRangePostiveTest");
|
||||
}
|
||||
}
|
||||
|
||||
void runDedicatePublicIpRangeInvalidRange() throws Exception {
|
||||
Transaction txn = Transaction.open("runDedicatePublicIpRangeInvalidRange");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(null);
|
||||
try {
|
||||
configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e.getMessage().contains("Please specify a valid Public IP range id"));
|
||||
} finally {
|
||||
txn.close("runDedicatePublicIpRangeInvalidRange");
|
||||
}
|
||||
}
|
||||
|
||||
void runDedicatePublicIpRangeDedicatedRange() throws Exception {
|
||||
Transaction txn = Transaction.open("runDedicatePublicIpRangeDedicatedRange");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
|
||||
|
||||
// public ip range is already dedicated
|
||||
List<AccountVlanMapVO> accountVlanMaps = new ArrayList<AccountVlanMapVO>();
|
||||
AccountVlanMapVO accountVlanMap = new AccountVlanMapVO(1, 1);
|
||||
accountVlanMaps.add(accountVlanMap);
|
||||
when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(accountVlanMaps);
|
||||
|
||||
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
|
||||
null, null, NetworkType.Advanced, null, null, true, true, null, null);
|
||||
when(configurationMgr._zoneDao.findById(anyLong())).thenReturn(dc);
|
||||
|
||||
List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
|
||||
IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
|
||||
ipAddressList.add(ipAddress);
|
||||
when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
|
||||
|
||||
try {
|
||||
configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e.getMessage().contains("Public IP range has already been dedicated"));
|
||||
} finally {
|
||||
txn.close("runDedicatePublicIpRangePublicIpRangeDedicated");
|
||||
}
|
||||
}
|
||||
|
||||
void runDedicatePublicIpRangeInvalidZone() throws Exception {
|
||||
Transaction txn = Transaction.open("runDedicatePublicIpRangeInvalidZone");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
|
||||
|
||||
when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(null);
|
||||
|
||||
// public ip range belongs to zone of type basic
|
||||
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
|
||||
null, null, NetworkType.Basic, null, null, true, true, null, null);
|
||||
when(configurationMgr._zoneDao.findById(anyLong())).thenReturn(dc);
|
||||
|
||||
List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
|
||||
IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
|
||||
ipAddressList.add(ipAddress);
|
||||
when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
|
||||
|
||||
try {
|
||||
configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e.getMessage().contains("Public IP range can be dedicated to an account only in the zone of type Advanced"));
|
||||
} finally {
|
||||
txn.close("runDedicatePublicIpRangeInvalidZone");
|
||||
}
|
||||
}
|
||||
|
||||
void runDedicatePublicIpRangeIPAdressAllocated() throws Exception {
|
||||
Transaction txn = Transaction.open("runDedicatePublicIpRangeIPAdressAllocated");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
|
||||
|
||||
when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByAccount(anyLong())).thenReturn(null);
|
||||
|
||||
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
|
||||
null, null, NetworkType.Advanced, null, null, true, true, null, null);
|
||||
when(configurationMgr._zoneDao.findById(anyLong())).thenReturn(dc);
|
||||
|
||||
// one of the ip addresses of the range is allocated to different account
|
||||
List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
|
||||
IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
|
||||
ipAddress.setAllocatedToAccountId(1L);
|
||||
ipAddressList.add(ipAddress);
|
||||
when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
|
||||
|
||||
try {
|
||||
configurationMgr.dedicatePublicIpRange(dedicatePublicIpRangesCmd);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e.getMessage().contains("Public IP address in range is already allocated to another account"));
|
||||
} finally {
|
||||
txn.close("runDedicatePublicIpRangeIPAdressAllocated");
|
||||
}
|
||||
}
|
||||
|
||||
void runReleasePublicIpRangePostiveTest1() throws Exception {
|
||||
Transaction txn = Transaction.open("runReleasePublicIpRangePostiveTest1");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
|
||||
|
||||
List<AccountVlanMapVO> accountVlanMaps = new ArrayList<AccountVlanMapVO>();
|
||||
AccountVlanMapVO accountVlanMap = new AccountVlanMapVO(1, 1);
|
||||
accountVlanMaps.add(accountVlanMap);
|
||||
when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(accountVlanMaps);
|
||||
|
||||
// no allocated ip's
|
||||
when(configurationMgr._publicIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(0);
|
||||
|
||||
when(configurationMgr._accountVlanMapDao.remove(anyLong())).thenReturn(true);
|
||||
try {
|
||||
Boolean result = configurationMgr.releasePublicIpRange(releasePublicIpRangesCmd);
|
||||
Assert.assertTrue(result);
|
||||
} catch (Exception e) {
|
||||
s_logger.info("exception in testing runReleasePublicIpRangePostiveTest1 message: " + e.toString());
|
||||
} finally {
|
||||
txn.close("runReleasePublicIpRangePostiveTest1");
|
||||
}
|
||||
}
|
||||
|
||||
void runReleasePublicIpRangePostiveTest2() throws Exception {
|
||||
Transaction txn = Transaction.open("runReleasePublicIpRangePostiveTest2");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
|
||||
|
||||
List<AccountVlanMapVO> accountVlanMaps = new ArrayList<AccountVlanMapVO>();
|
||||
AccountVlanMapVO accountVlanMap = new AccountVlanMapVO(1, 1);
|
||||
accountVlanMaps.add(accountVlanMap);
|
||||
when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(accountVlanMaps);
|
||||
|
||||
when(configurationMgr._publicIpAddressDao.countIPs(anyLong(), anyLong(), anyBoolean())).thenReturn(1);
|
||||
|
||||
List<IPAddressVO> ipAddressList = new ArrayList<IPAddressVO>();
|
||||
IPAddressVO ipAddress = new IPAddressVO(new Ip("75.75.75.75"), 1, 0xaabbccddeeffL, 10, false);
|
||||
ipAddressList.add(ipAddress);
|
||||
when(configurationMgr._publicIpAddressDao.listByVlanId(anyLong())).thenReturn(ipAddressList);
|
||||
|
||||
when(configurationMgr._firewallDao.countRulesByIpId(anyLong())).thenReturn(0L);
|
||||
|
||||
when(configurationMgr._networkMgr.disassociatePublicIpAddress(anyLong(), anyLong(), any(Account.class))).thenReturn(true);
|
||||
|
||||
when(configurationMgr._vlanDao.releaseFromLockTable(anyLong())).thenReturn(true);
|
||||
|
||||
when(configurationMgr._accountVlanMapDao.remove(anyLong())).thenReturn(true);
|
||||
try {
|
||||
Boolean result = configurationMgr.releasePublicIpRange(releasePublicIpRangesCmd);
|
||||
Assert.assertTrue(result);
|
||||
} catch (Exception e) {
|
||||
s_logger.info("exception in testing runReleasePublicIpRangePostiveTest2 message: " + e.toString());
|
||||
} finally {
|
||||
txn.close("runReleasePublicIpRangePostiveTest2");
|
||||
}
|
||||
}
|
||||
|
||||
void runReleasePublicIpRangeInvalidIpRange() throws Exception {
|
||||
Transaction txn = Transaction.open("runReleasePublicIpRangeInvalidIpRange");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(null);
|
||||
try {
|
||||
configurationMgr.releasePublicIpRange(releasePublicIpRangesCmd);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e.getMessage().contains("Please specify a valid IP range id"));
|
||||
} finally {
|
||||
txn.close("runReleasePublicIpRangeInvalidIpRange");
|
||||
}
|
||||
}
|
||||
|
||||
void runReleaseNonDedicatedPublicIpRange() throws Exception {
|
||||
Transaction txn = Transaction.open("runReleaseNonDedicatedPublicIpRange");
|
||||
|
||||
when(configurationMgr._vlanDao.findById(anyLong())).thenReturn(vlan);
|
||||
|
||||
when(configurationMgr._accountVlanMapDao.listAccountVlanMapsByVlan(anyLong())).thenReturn(null);
|
||||
try {
|
||||
configurationMgr.releasePublicIpRange(releasePublicIpRangesCmd);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e.getMessage().contains("as it not dedicated to any account"));
|
||||
} finally {
|
||||
txn.close("runReleaseNonDedicatedPublicIpRange");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class DedicatePublicIpRangeCmdExtn extends DedicatePublicIpRangeCmd {
|
||||
public long getEntityOwnerId() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public class ReleasePublicIpRangeCmdExtn extends ReleasePublicIpRangeCmd {
|
||||
public long getEntityOwnerId() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,7 +40,9 @@ import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd
|
||||
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
|
||||
@ -544,7 +546,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
|
||||
* @see com.cloud.configuration.ConfigurationManager#deleteAccountSpecificVirtualRanges(long)
|
||||
*/
|
||||
@Override
|
||||
public boolean deleteAccountSpecificVirtualRanges(long accountId) {
|
||||
public boolean releaseAccountSpecificVirtualRanges(long accountId) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
@ -613,5 +615,33 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vlan dedicatePublicIpRange(DedicatePublicIpRangeCmd cmd)
|
||||
throws ResourceAllocationException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releasePublicIpRange(ReleasePublicIpRangeCmd cmd) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releasePublicIpRange(long userId, long vlanDbId,
|
||||
Account caller) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vlan dedicatePublicIpRange(Long vlanDbId, String accountName,
|
||||
Long domainId, Long zoneId, Long projectId)
|
||||
throws ResourceAllocationException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
149
test/integration/component/test_public_ip_range.py
Normal file
149
test/integration/component/test_public_ip_range.py
Normal file
@ -0,0 +1,149 @@
|
||||
# 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.
|
||||
""" P1 tests for Dedicating Public IP addresses
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.integration.lib.utils import *
|
||||
from marvin.integration.lib.base import *
|
||||
from marvin.integration.lib.common import *
|
||||
import datetime
|
||||
|
||||
class Services:
|
||||
"""Test Dedicating Public IP addresses
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"domain": {
|
||||
"name": "Domain",
|
||||
},
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "password",
|
||||
},
|
||||
"gateway": "10.102.196.1",
|
||||
"netmask": "255.255.255.0",
|
||||
"forvirtualnetwork": "true",
|
||||
"startip": "10.102.196.70",
|
||||
"endip": "10.102.196.73",
|
||||
"zoneid": "1",
|
||||
"podid": "",
|
||||
"vlan": "101",
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
}
|
||||
|
||||
class TesDedicatePublicIPRange(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.api_client = super(TesDedicatePublicIPRange, cls).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
# Get Zone, Domain
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
|
||||
# Create Account, VMs etc
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
cls._cleanup = [
|
||||
#cls.account,
|
||||
]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags = ["publiciprange", "dedicate"])
|
||||
def test_createPublicIpRange(self):
|
||||
"""Test create public IP range
|
||||
"""
|
||||
|
||||
|
||||
# Validate the following:
|
||||
# 1. Create public IP range.
|
||||
# 2. Created IP range should be present, verify with listVlanIpRanges
|
||||
|
||||
self.debug("Creating Public IP range")
|
||||
self.public_ip_range = PublicIpRange.create(
|
||||
self.api_client,
|
||||
self.services
|
||||
)
|
||||
list_public_ip_range_response = PublicIpRange.list(
|
||||
self.apiclient,
|
||||
id=self.public_ip_range.vlan.id
|
||||
)
|
||||
self.debug(
|
||||
"Verify listPublicIpRanges response for public ip ranges: %s" \
|
||||
% self.public_ip_range.vlan.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_public_ip_range_response, list),
|
||||
True,
|
||||
"Check for list Public IP range response"
|
||||
)
|
||||
public_ip_response = list_public_ip_range_response[0]
|
||||
self.assertEqual(
|
||||
public_ip_response.id,
|
||||
self.public_ip_range.vlan.id,
|
||||
"Check public ip range response id is in listVlanIpRanges"
|
||||
)
|
||||
self.debug("Dedicating Public IP range");
|
||||
self.debug("Vlan id %s" % self.public_ip_range.vlan.id);
|
||||
self.debug("Zone id %s" % self.zone.id);
|
||||
self.debug("Account name %s" % self.account.account.name);
|
||||
self.debug("Domain id %s" % self.account.account.domainid);
|
||||
dedicate_public_ip_range_response = PublicIpRange.dedicate(
|
||||
self.apiclient,
|
||||
self.public_ip_range.vlan.id,
|
||||
zoneid=self.zone.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
return
|
||||
@ -1882,6 +1882,17 @@ class PublicIpRange:
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listVlanIpRanges(cmd))
|
||||
|
||||
@classmethod
|
||||
def dedicate(cls, apiclient, id, zoneid, account=None, domainid=None, projectid=None):
|
||||
"""Dedicate VLAN IP range"""
|
||||
|
||||
cmd = dedicatePublicIpRange.dedicatePublicIpRangeCmd()
|
||||
cmd.id = id
|
||||
cmd.account = account
|
||||
cmd.domainid = domainid
|
||||
cmd.projectid = projectid
|
||||
cmd.zoneid = zoneid
|
||||
return PublicIpRange(apiclient.dedicatePublicIpRange(cmd).__dict__)
|
||||
|
||||
class SecondaryStorage:
|
||||
"""Manage Secondary storage"""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user