Dedicate Public IP address range to an account

This commit is contained in:
Likitha Shetty 2013-04-08 22:44:45 +05:30
parent 95cbb790f3
commit 8f865c5a90
15 changed files with 1017 additions and 49 deletions

View File

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

View File

@ -226,6 +226,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";
@ -545,6 +547,8 @@ public class EventTypes {
// VLANs/IP ranges
entityEventDetails.put(EVENT_VLAN_IP_RANGE_CREATE, Vlan.class.getName());
entityEventDetails.put(EVENT_VLAN_IP_RANGE_DELETE,Vlan.class.getName());
entityEventDetails.put(EVENT_VLAN_IP_RANGE_DEDICATE, Vlan.class.getName());
entityEventDetails.put(EVENT_VLAN_IP_RANGE_RELEASE,Vlan.class.getName());
entityEventDetails.put(EVENT_STORAGE_IP_RANGE_CREATE, StorageNetworkIpRange.class.getName());
entityEventDetails.put(EVENT_STORAGE_IP_RANGE_DELETE, StorageNetworkIpRange.class.getName());

View File

@ -0,0 +1,108 @@
// 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;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public String getAccountName() {
return accountName;
}
public Long getDomainId() {
return domainId;
}
public Long getProjectId() {
return projectId;
}
/////////////////////////////////////////////////////
/////////////// 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");
}
}
}

View File

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

View File

@ -124,6 +124,8 @@ listDiskOfferings=15
createVlanIpRange=1
deleteVlanIpRange=1
listVlanIpRanges=1
dedicatePublicIpRange=1
releasePublicIpRange=1
#### address commands
associateIpAddress=15

View File

@ -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;
@ -150,6 +151,8 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
*/
boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId, Account caller);
boolean releasePublicIpRange(long userId, long vlanDbId, Account caller);
/**
* Converts a comma separated list of tags to a List
*
@ -211,7 +214,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.

View File

@ -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,149 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
}
@Override
@DB
@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 projectId = cmd.getProjectId();
// 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
Long zoneId = vlan.getDataCenterId();
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 +4082,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 +4097,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;
}

View File

@ -348,7 +348,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 +364,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 +526,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 +669,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 +703,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) {
@ -1082,7 +1107,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);

View File

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

View File

@ -59,6 +59,7 @@ import org.apache.cloudstack.api.command.admin.storage.*;
import org.apache.cloudstack.api.command.admin.systemvm.*;
import org.apache.cloudstack.api.command.admin.usage.*;
import org.apache.cloudstack.api.command.admin.user.*;
import org.apache.cloudstack.api.command.admin.vlan.*;
import org.apache.cloudstack.api.command.admin.vpc.*;
import org.apache.cloudstack.api.command.user.autoscale.*;
import org.apache.cloudstack.api.command.user.firewall.*;
@ -2037,6 +2038,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);

View File

@ -690,13 +690,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.");
}
}

View File

@ -0,0 +1,413 @@
// 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.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(Vlan.VlanType.VirtualNetwork, "vlantag", "vlangateway","vlannetmask", 1L, "iprange", 1L, 1L, null, null, null);
@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 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;
}
}
}

View File

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

View File

@ -0,0 +1,173 @@
# 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",
"password": "password",
},
"gateway": "10.102.197.1",
"netmask": "255.255.255.0",
"forvirtualnetwork": "true",
"startip": "10.102.197.70",
"endip": "10.102.197.73",
"zoneid": "1",
"podid": "",
"vlan": "101",
}
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
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", "release"])
def test_dedicatePublicIpRange(self):
"""Test public IP range dedication
"""
# Validate the following:
# 1. Create a Public IP range
# 2. Created IP range should be present, verify with listVlanIpRanges
# 3. Dedicate the created IP range to user account
# 4. Verify IP range is dedicated, verify with listVlanIpRanges
# 5. Release the dedicated Public IP range back to the system
# 6. Verify IP range has been released, verify with listVlanIpRanges
# 7. Delete the Public IP range
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");
dedicate_public_ip_range_response = PublicIpRange.dedicate(
self.apiclient,
self.public_ip_range.vlan.id,
account=self.account.account.name,
domainid=self.account.account.domainid
)
list_public_ip_range_response = PublicIpRange.list(
self.apiclient,
id=self.public_ip_range.vlan.id
)
public_ip_response = list_public_ip_range_response[0]
self.assertEqual(
public_ip_response.account,
self.account.account.name,
"Check account name is in listVlanIpRanges as the account public ip range is dedicated to"
)
self.debug("Releasing Public IP range");
self.public_ip_range.release(self.apiclient)
list_public_ip_range_response = PublicIpRange.list(
self.apiclient,
id=self.public_ip_range.vlan.id
)
public_ip_response = list_public_ip_range_response[0]
self.assertEqual(
public_ip_response.account,
"system",
"Check account name is system account in listVlanIpRanges"
)
self.debug("Deleting Public IP range");
self.public_ip_range.delete(self.apiclient)
return

19
tools/marvin/marvin/integration/lib/base.py Normal file → Executable file
View File

@ -1873,7 +1873,7 @@ class PublicIpRange:
"""Delete VlanIpRange"""
cmd = deleteVlanIpRange.deleteVlanIpRangeCmd()
cmd.id = self.id
cmd.id = self.vlan.id
apiclient.deleteVlanIpRange(cmd)
@classmethod
@ -1884,6 +1884,23 @@ class PublicIpRange:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listVlanIpRanges(cmd))
@classmethod
def dedicate(cls, apiclient, id, 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
return PublicIpRange(apiclient.dedicatePublicIpRange(cmd).__dict__)
def release(self, apiclient):
"""Release VLAN IP range"""
cmd = releasePublicIpRange.releasePublicIpRangeCmd()
cmd.id = self.vlan.id
return apiclient.releasePublicIpRange(cmd)
class SecondaryStorage:
"""Manage Secondary storage"""