Dedicate guest vlan range to account

This commit is contained in:
Likitha Shetty 2013-05-01 13:47:26 +05:30
parent b33b316755
commit c8d843241e
32 changed files with 1790 additions and 13 deletions

View File

@ -50,7 +50,8 @@ public interface AsyncJob extends Identity, InternalIdentity {
AutoScaleVmProfile,
AutoScaleVmGroup,
GlobalLoadBalancerRule,
AffinityGroup
AffinityGroup,
DedicatedGuestVlanRange
}
long getUserId();

View File

@ -390,6 +390,10 @@ public class EventTypes {
public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE";
public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE";
// Dedicated guest vlan range
public static final String EVENT_GUEST_VLAN_RANGE_DEDICATE = "GUESTVLANRANGE.DEDICATE";
public static final String EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE = "GUESTVLANRANGE.RELEASE";
static {
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
@ -690,6 +694,9 @@ public class EventTypes {
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class.getName());
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class.getName());
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class.getName());
entityEventDetails.put(EVENT_GUEST_VLAN_RANGE_DEDICATE, GuestVlan.class.getName());
entityEventDetails.put(EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, GuestVlan.class.getName());
}
public static String getEntityForEvent (String eventName) {

View File

@ -0,0 +1,31 @@
// 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.network;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface GuestVlan extends InternalIdentity, Identity {
public long getId();
public long getAccountId();
public String getGuestVlanRange();
public long getPhysicalNetworkId();
}

View File

@ -18,6 +18,8 @@ package com.cloud.network;
import java.util.List;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
@ -29,6 +31,7 @@ import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.GuestVlan;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.TrafficType;
import com.cloud.user.Account;
@ -114,6 +117,12 @@ public interface NetworkService {
boolean deletePhysicalNetworkTrafficType(Long id);
GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd);
Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd);
boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId);
Pair<List<? extends PhysicalNetworkTrafficType>, Integer> listTrafficTypes(Long physicalNetworkId);

View File

@ -85,6 +85,7 @@ public class ApiConstants {
public static final String GSLB_SERVICE_TYPE = "gslbservicetype";
public static final String GSLB_STICKY_SESSION_METHOD = "gslbstickysessionmethodname";
public static final String GUEST_CIDR_ADDRESS = "guestcidraddress";
public static final String GUEST_VLAN_RANGE = "guestvlanrange";
public static final String HA_ENABLE = "haenable";
public static final String HOST_ID = "hostid";
public static final String HOST_NAME = "hostname";
@ -221,6 +222,7 @@ public class ApiConstants {
public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
public static final String VLAN = "vlan";
public static final String VLAN_RANGE = "vlanrange";
public static final String REMOVE_VLAN="removevlan";
public static final String VLAN_ID = "vlanid";
public static final String VM_AVAILABLE = "vmavailable";

View File

@ -198,6 +198,8 @@ public interface ResponseGenerator {
IPAddressResponse createIPAddressResponse(IpAddress ipAddress);
GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan result);
GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancerRule globalLoadBalancerRule);
LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer);

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.network;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.GuestVlan;
import com.cloud.user.Account;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.*;
import org.apache.log4j.Logger;
@APICommand(name = "dedicateGuestVlanRange", description="Dedicates a guest vlan range to an account", responseObject=GuestVlanRangeResponse.class)
public class DedicateGuestVlanRangeCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DedicateGuestVlanRangeCmd.class.getName());
private static final String s_name = "dedicateguestvlanrangeresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.VLAN_RANGE, type=CommandType.STRING, required=true,
description="guest vlan range to be dedicated")
private String vlan;
@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.PHYSICAL_NETWORK_ID, type=CommandType.UUID, entityType = PhysicalNetworkResponse.class,
required=true, description="physical network ID of the vlan")
private Long physicalNetworkId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getVlan() {
return vlan;
}
public String getAccountName() {
return accountName;
}
public Long getDomainId() {
return domainId;
}
public Long getPhysicalNetworkId() {
return physicalNetworkId;
}
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 {
GuestVlan result = _networkService.dedicateGuestVlanRange(this);
if (result != null) {
GuestVlanRangeResponse response = _responseGenerator.createDedicatedGuestVlanRangeResponse(result);
response.setResponseName(getCommandName());
response.setObjectName("dedicatedguestvlanrange");
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to dedicate guest vlan range");
}
}
}

View File

@ -0,0 +1,129 @@
// 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.network;
import com.cloud.network.GuestVlan;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.*;
import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
@APICommand(name = "listDedicatedGuestVlanRanges", description="Lists dedicated guest vlan ranges", responseObject=GuestVlanRangeResponse.class)
public class ListDedicatedGuestVlanRangesCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListDedicatedGuestVlanRangesCmd.class.getName());
private static final String s_name = "listdedicatedguestvlanrangesresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=GuestVlanRangeResponse.class,
description="list dedicated guest vlan ranges by id")
private Long id;
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account with which the guest VLAN range is associated. Must be used with the domainId parameter.")
private String accountName;
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class,
description="project who will own the guest VLAN range")
private Long projectId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType = DomainResponse.class,
description="the domain ID with which the guest VLAN range is associated. If used with the account parameter, returns all guest VLAN ranges for that account in the specified domain.")
private Long domainId;
@Parameter(name=ApiConstants.GUEST_VLAN_RANGE, type=CommandType.STRING, description="the dedicated guest vlan range")
private String guestVlanRange;
@Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.UUID, entityType = PhysicalNetworkResponse.class,
description="physical network id of the guest VLAN range")
private Long physicalNetworkId;
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
description="zone of the guest VLAN 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 String getGuestVlanRange() {
return guestVlanRange;
}
public Long getPhysicalNetworkId() {
return physicalNetworkId;
}
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(){
Pair<List<? extends GuestVlan>, Integer> vlans = _networkService.listDedicatedGuestVlanRanges(this);
ListResponse<GuestVlanRangeResponse> response = new ListResponse<GuestVlanRangeResponse>();
List<GuestVlanRangeResponse> guestVlanResponses = new ArrayList<GuestVlanRangeResponse>();
for (GuestVlan vlan : vlans.first()) {
GuestVlanRangeResponse guestVlanResponse = _responseGenerator.createDedicatedGuestVlanRangeResponse(vlan);
guestVlanResponse.setObjectName("dedicatedguestvlanrange");
guestVlanResponses.add(guestVlanResponse);
}
response.setResponses(guestVlanResponses, vlans.second());
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -0,0 +1,94 @@
// 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.network;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.ResourceInUseException;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.CounterResponse;
import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
@APICommand(name = "releaseDedicatedGuestVlanRange", description = "Releases a dedicated guest vlan range to the system", responseObject = SuccessResponse.class)
public class ReleaseDedicatedGuestVlanRangeCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(ReleaseDedicatedGuestVlanRangeCmd.class.getName());
private static final String s_name = "releasededicatedguestvlanrangeresponse";
// ///////////////////////////////////////////////////
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=GuestVlanRangeResponse.class,
required=true, description="the ID of the dedicated guest vlan range")
private Long id;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
public Long getId() {
return id;
}
@Override
public AsyncJob.Type getInstanceType() {
return AsyncJob.Type.DedicatedGuestVlanRange;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public String getEventType() {
return EventTypes.EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE;
}
@Override
public String getEventDescription() {
return "Releasing a dedicated guest vlan range.";
}
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
@Override
public void execute(){
UserContext.current().setEventDetails("Dedicated guest vlan range Id: " + id);
boolean result = _networkService.releaseDedicatedGuestVlanRange(getId());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release dedicated guest vlan range");
}
}
}

View File

@ -0,0 +1,94 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.network.GuestVlan;
@EntityReference(value=GuestVlan.class)
@SuppressWarnings("unused")
public class GuestVlanRangeResponse extends BaseResponse implements ControlledEntityResponse {
@SerializedName(ApiConstants.ID) @Param(description="the ID of the guest VLAN range")
private String id;
@SerializedName(ApiConstants.ACCOUNT) @Param(description="the account of the guest VLAN range")
private String accountName;
@SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain ID of the guest VLAN range")
private String domainId;
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the guest VLAN range")
private String domainName;
@SerializedName(ApiConstants.GUEST_VLAN_RANGE) @Param(description="the guest VLAN range")
private String guestVlanRange;
@SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the guest vlan range")
private String projectId;
@SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the guest vlan range")
private String projectName;
@SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Param(description="the physical network of the guest vlan range")
private Long physicalNetworkId;
@SerializedName(ApiConstants.ZONE_ID) @Param(description="the zone of the guest vlan range")
private Long zoneId;
public void setId(String id) {
this.id = id;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public void setDomainId(String domainId) {
this.domainId = domainId;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public void setGuestVlanRange(String guestVlanRange) {
this.guestVlanRange = guestVlanRange;
}
public void setProjectId(String projectId) {
this.projectId = projectId;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public void setPhysicalNetworkId(Long physicalNetworkId) {
this.physicalNetworkId = physicalNetworkId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
}

View File

@ -165,6 +165,7 @@
<bean id="accountDaoImpl" class="com.cloud.user.dao.AccountDaoImpl" />
<bean id="accountDetailsDaoImpl" class="com.cloud.user.AccountDetailsDaoImpl" />
<bean id="accountJoinDaoImpl" class="com.cloud.api.query.dao.AccountJoinDaoImpl" />
<bean id="accountGuestVlanMapDaoImpl" class="com.cloud.network.dao.AccountGuestVlanMapDaoImpl" />
<bean id="accountVlanMapDaoImpl" class="com.cloud.dc.dao.AccountVlanMapDaoImpl" />
<bean id="agentUpgradeDaoImpl" class="com.cloud.maint.dao.AgentUpgradeDaoImpl" />
<bean id="alertDaoImpl" class="com.cloud.alert.dao.AlertDaoImpl" />

View File

@ -130,6 +130,8 @@ import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.dao.AccountGuestVlanMapDao;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
@ -309,6 +311,7 @@ public class ApiDBUtils {
static GuestOSDao _guestOSDao;
static GuestOSCategoryDao _guestOSCategoryDao;
static HostDao _hostDao;
static AccountGuestVlanMapDao _accountGuestVlanMapDao;
static IPAddressDao _ipAddressDao;
static LoadBalancerDao _loadBalancerDao;
static SecurityGroupDao _securityGroupDao;
@ -416,6 +419,7 @@ public class ApiDBUtils {
@Inject private GuestOSDao guestOSDao;
@Inject private GuestOSCategoryDao guestOSCategoryDao;
@Inject private HostDao hostDao;
@Inject private AccountGuestVlanMapDao accountGuestVlanMapDao;
@Inject private IPAddressDao ipAddressDao;
@Inject private LoadBalancerDao loadBalancerDao;
@Inject private SecurityGroupDao securityGroupDao;
@ -512,6 +516,7 @@ public class ApiDBUtils {
_templateMgr = templateMgr;
_accountDao = accountDao;
_accountGuestVlanMapDao = accountGuestVlanMapDao;
_accountVlanMapDao = accountVlanMapDao;
_clusterDao = clusterDao;
_capacityDao = capacityDao;
@ -945,6 +950,15 @@ public class ApiDBUtils {
}
}
public static Long getAccountIdForGuestVlan(long vlanDbId) {
List<AccountGuestVlanMapVO> accountGuestVlanMaps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByVlan(vlanDbId);
if (accountGuestVlanMaps.isEmpty()) {
return null;
} else {
return accountGuestVlanMaps.get(0).getAccountId();
}
}
public static HypervisorType getVolumeHyperType(long volumeId) {
return _volumeDao.getHypervisorType(volumeId);
}

View File

@ -180,7 +180,9 @@ import com.cloud.event.Event;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.hypervisor.HypervisorCapabilities;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.IpAddress;
import com.cloud.network.GuestVlan;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
@ -2725,6 +2727,25 @@ public class ApiResponseHelper implements ResponseGenerator {
return response;
}
@Override
public GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan vlan) {
GuestVlanRangeResponse guestVlanRangeResponse = new GuestVlanRangeResponse();
guestVlanRangeResponse.setId(vlan.getUuid());
Long accountId= ApiDBUtils.getAccountIdForGuestVlan(vlan.getId());
Account owner = ApiDBUtils.findAccountById(accountId);
if (owner != null) {
populateAccount(guestVlanRangeResponse, owner.getId());
populateDomain(guestVlanRangeResponse, owner.getDomainId());
}
guestVlanRangeResponse.setGuestVlanRange(vlan.getGuestVlanRange());
guestVlanRangeResponse.setPhysicalNetworkId(vlan.getPhysicalNetworkId());
PhysicalNetworkVO physicalNetwork = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
guestVlanRangeResponse.setZoneId(physicalNetwork.getDataCenterId());
return guestVlanRangeResponse;
}
@Override
public ServiceResponse createNetworkServiceResponse(Service service) {
ServiceResponse response = new ServiceResponse();

View File

@ -56,6 +56,9 @@ public class DataCenterVnetVO implements InternalIdentity {
@Column(name="reservation_id")
protected String reservationId;
@Column(name="account_vnet_map_id")
protected Long accountGuestVlanMapId;
public Date getTakenAt() {
return takenAt;
@ -103,6 +106,14 @@ public class DataCenterVnetVO implements InternalIdentity {
public long getPhysicalNetworkId() {
return physicalNetworkId;
}
public void setAccountGuestVlanMapId(Long accountGuestVlanMapId) {
this.accountGuestVlanMapId = accountGuestVlanMapId;
}
public Long getAccountGuestVlanMapId() {
return accountGuestVlanMapId;
}
protected DataCenterVnetVO() {
}

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.dc.dao;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
@ -33,6 +34,8 @@ import com.cloud.dc.DataCenterLinkLocalIpAddressVO;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DataCenterVnetVO;
import com.cloud.dc.PodVlanVO;
import com.cloud.network.dao.AccountGuestVlanMapDao;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.org.Grouping;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
@ -68,6 +71,7 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
@Inject protected DataCenterVnetDao _vnetAllocDao = null;
@Inject protected PodVlanDao _podVlanAllocDao = null;
@Inject protected DcDetailsDao _detailsDao = null;
@Inject protected AccountGuestVlanMapDao _accountGuestVlanMapDao = null;
protected long _prefix;
protected Random _rand = new Random(System.currentTimeMillis());
@ -189,11 +193,20 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
@Override
public String allocateVnet(long dataCenterId, long physicalNetworkId, long accountId, String reservationId) {
DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId);
ArrayList<Long> dedicatedVlanDbIds = new ArrayList<Long>();
List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(accountId);
for (AccountGuestVlanMapVO map : maps) {
dedicatedVlanDbIds.add(map.getId());
}
if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId, dedicatedVlanDbIds);
if (vo != null)
return vo.getVnet();
}
DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId, null);
if (vo == null) {
return null;
}
return vo.getVnet();
}

View File

@ -37,8 +37,13 @@ public interface DataCenterVnetDao extends GenericDao<DataCenterVnetVO, Long> {
public void lockRange(long dcId, long physicalNetworkId, Integer start, Integer end);
public DataCenterVnetVO take(long physicalNetworkId, long accountId, String reservationId);
public DataCenterVnetVO take(long physicalNetworkId, long accountId, String reservationId, List<Long> vlanDbIds);
public void release(String vnet, long physicalNetworkId, long accountId, String reservationId);
public void releaseDedicatedGuestVlans(Long dedicatedGuestVlanRangeId);
public int countVnetsAllocatedToAccount(long dcId, long accountId);
public int countVnetsDedicatedToAccount(long dcId, long accountId);
}

View File

@ -20,15 +20,22 @@ import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.exception.InvalidParameterValueException;
import org.springframework.stereotype.Component;
import com.cloud.dc.DataCenterVnetVO;
import com.cloud.network.dao.AccountGuestVlanMapDao;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
@ -43,7 +50,9 @@ import com.cloud.utils.exception.CloudRuntimeException;
@Component
@DB(txn=false)
public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long> implements DataCenterVnetDao {
private final SearchBuilder<DataCenterVnetVO> FreeVnetSearch;
private final SearchBuilder<DataCenterVnetVO> FreeDedicatedVnetSearch;
private final SearchBuilder<DataCenterVnetVO> VnetDcSearch;
private final SearchBuilder<DataCenterVnetVO> VnetDcSearchAllocated;
private final SearchBuilder<DataCenterVnetVO> DcSearchAllocated;
@ -51,6 +60,12 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
private final GenericSearchBuilder<DataCenterVnetVO, Integer> countZoneVlans;
private final GenericSearchBuilder<DataCenterVnetVO, Integer> countAllocatedZoneVlans;
private final SearchBuilder<DataCenterVnetVO> SearchRange;
private final SearchBuilder<DataCenterVnetVO> DedicatedGuestVlanRangeSearch;
private final GenericSearchBuilder<DataCenterVnetVO, Integer> countVnetsAllocatedToAccount;
protected GenericSearchBuilder<DataCenterVnetVO, Integer> countVnetsDedicatedToAccount;
protected SearchBuilder<AccountGuestVlanMapVO> AccountGuestVlanMapSearch;
@Inject protected AccountGuestVlanMapDao _accountGuestVlanMapDao;
public List<DataCenterVnetVO> listAllocatedVnets(long physicalNetworkId) {
SearchCriteria<DataCenterVnetVO> sc = DcSearchAllocated.create();
@ -141,9 +156,15 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
}
@DB
public DataCenterVnetVO take(long physicalNetworkId, long accountId, String reservationId) {
SearchCriteria<DataCenterVnetVO> sc = FreeVnetSearch.create();
sc.setParameters("physicalNetworkId", physicalNetworkId);
public DataCenterVnetVO take(long physicalNetworkId, long accountId, String reservationId, List<Long> vlanDbIds) {
SearchCriteria<DataCenterVnetVO> sc;
if (vlanDbIds != null) {
sc = FreeDedicatedVnetSearch.create();
sc.setParameters("accountGuestVlanMapId", vlanDbIds.toArray());
} else {
sc = FreeVnetSearch.create();
}
sc.setParameters("physicalNetworkId", physicalNetworkId);
Date now = new Date();
Transaction txn = Transaction.currentTxn();
txn.start();
@ -160,6 +181,7 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
return vo;
}
public void release(String vnet, long physicalNetworkId, long accountId, String reservationId) {
SearchCriteria<DataCenterVnetVO> sc = VnetDcSearchAllocated.create();
sc.setParameters("vnet", vnet);
@ -178,6 +200,51 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
update(vo.getId(), vo);
}
@Override
public void releaseDedicatedGuestVlans(Long dedicatedGuestVlanRangeId) {
SearchCriteria<DataCenterVnetVO> sc = DedicatedGuestVlanRangeSearch.create();
sc.setParameters("dedicatedGuestVlanRangeId", dedicatedGuestVlanRangeId);
List<DataCenterVnetVO> vnets = listBy(sc);
for(DataCenterVnetVO vnet : vnets) {
vnet.setAccountGuestVlanMapId(null);
update(vnet.getId(), vnet);
}
}
@Override
public int countVnetsAllocatedToAccount(long dcId, long accountId) {
SearchCriteria<Integer> sc = countVnetsAllocatedToAccount.create();
sc.setParameters("dc", dcId);
sc.setParameters("accountId", accountId);
return customSearch(sc, null).get(0);
}
@Override
public int countVnetsDedicatedToAccount(long dcId, long accountId) {
SearchCriteria<Integer> sc = countVnetsDedicatedToAccount.create();
sc.setParameters("dc", dcId);
sc.setParameters("accountId", accountId);
return customSearch(sc, null).get(0);
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
boolean result = super.configure(name, params);
countVnetsDedicatedToAccount = createSearchBuilder(Integer.class);
countVnetsDedicatedToAccount.and("dc", countVnetsDedicatedToAccount.entity().getDataCenterId(), SearchCriteria.Op.EQ);
countVnetsDedicatedToAccount.and("accountGuestVlanMapId", countVnetsDedicatedToAccount.entity().getAccountGuestVlanMapId(), Op.NNULL);
AccountGuestVlanMapSearch = _accountGuestVlanMapDao.createSearchBuilder();
AccountGuestVlanMapSearch.and("accountId", AccountGuestVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
countVnetsDedicatedToAccount.join("AccountGuestVlanMapSearch", AccountGuestVlanMapSearch, countVnetsDedicatedToAccount.entity().getAccountGuestVlanMapId(),
AccountGuestVlanMapSearch.entity().getId(), JoinBuilder.JoinType.INNER);
countVnetsDedicatedToAccount.select(null, Func.COUNT, countVnetsDedicatedToAccount.entity().getId());
countVnetsDedicatedToAccount.done();
AccountGuestVlanMapSearch.done();
return result;
}
public DataCenterVnetDaoImpl() {
super();
DcSearchAllocated = createSearchBuilder();
@ -202,7 +269,15 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
FreeVnetSearch.and("dc", FreeVnetSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
FreeVnetSearch.and("physicalNetworkId", FreeVnetSearch.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
FreeVnetSearch.and("taken", FreeVnetSearch.entity().getTakenAt(), SearchCriteria.Op.NULL);
FreeVnetSearch.and("accountGuestVlanMapId", FreeVnetSearch.entity().getAccountGuestVlanMapId(), SearchCriteria.Op.NULL);
FreeVnetSearch.done();
FreeDedicatedVnetSearch = createSearchBuilder();
FreeDedicatedVnetSearch.and("dc", FreeDedicatedVnetSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
FreeDedicatedVnetSearch.and("physicalNetworkId", FreeDedicatedVnetSearch.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
FreeDedicatedVnetSearch.and("taken", FreeDedicatedVnetSearch.entity().getTakenAt(), SearchCriteria.Op.NULL);
FreeDedicatedVnetSearch.and("accountGuestVlanMapId", FreeDedicatedVnetSearch.entity().getAccountGuestVlanMapId(), SearchCriteria.Op.IN);
FreeDedicatedVnetSearch.done();
VnetDcSearch = createSearchBuilder();
VnetDcSearch.and("vnet", VnetDcSearch.entity().getVnet(), SearchCriteria.Op.EQ);
@ -229,6 +304,15 @@ public class DataCenterVnetDaoImpl extends GenericDaoBase<DataCenterVnetVO, Long
VnetDcSearchAllocated.and("account", VnetDcSearchAllocated.entity().getAccountId(), SearchCriteria.Op.EQ);
VnetDcSearchAllocated.and("reservation", VnetDcSearchAllocated.entity().getReservationId(), SearchCriteria.Op.EQ);
VnetDcSearchAllocated.done();
DedicatedGuestVlanRangeSearch = createSearchBuilder();
DedicatedGuestVlanRangeSearch.and("dedicatedGuestVlanRangeId", DedicatedGuestVlanRangeSearch.entity().getAccountGuestVlanMapId(), SearchCriteria.Op.EQ);
DedicatedGuestVlanRangeSearch.done();
countVnetsAllocatedToAccount = createSearchBuilder(Integer.class);
countVnetsAllocatedToAccount.and("dc", countVnetsAllocatedToAccount.entity().getDataCenterId(), SearchCriteria.Op.EQ);
countVnetsAllocatedToAccount.and("accountId", countVnetsAllocatedToAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
countVnetsAllocatedToAccount.select(null, Func.COUNT, countVnetsAllocatedToAccount.entity().getId());
countVnetsAllocatedToAccount.done();
}
}

View File

@ -31,6 +31,7 @@ import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterVnetDao;
import com.cloud.dc.dao.PodVlanMapDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DataCenterDeployment;
@ -156,6 +157,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
PodVlanMapDao _podVlanMapDao;
@Inject
ConfigurationServer _configServer;
@Inject
AccountGuestVlanMapDao _accountGuestVlanMapDao;
@Inject
DataCenterVnetDao _datacenterVnetDao;
List<NetworkGuru> _networkGurus;
public List<NetworkGuru> getNetworkGurus() {
@ -1998,8 +2003,29 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
// For Isolated networks, don't allow to create network with vlan that already exists in the zone
if (ntwkOff.getGuestType() == GuestType.Isolated) {
if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) {
throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
}
throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
} else {
DataCenterVnetVO dcVnet = _datacenterVnetDao.findVnet(zoneId, vlanId.toString()).get(0);
// Fail network creation if specified vlan is dedicated to a different account
if (dcVnet.getAccountGuestVlanMapId() != null) {
Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
if (map.getAccountId() != owner.getAccountId()) {
throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
}
// Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
} else {
List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
if (maps != null && !maps.isEmpty()) {
int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" +
" to the vlan range dedicated to the owner "+ owner.getAccountName());
}
}
}
}
} else {
// don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
// shared network with same Vlan ID in the zone
@ -2008,7 +2034,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " +
vlanId + " already exists " + "in zone " + zoneId);
}
}
}
}
// If networkDomain is not specified, take it from the global configuration

View File

@ -85,6 +85,8 @@ import com.cloud.vm.dao.*;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
@ -203,6 +205,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
HostPodDao _hostPodDao;
@Inject
DataCenterVnetDao _datacneter_vnet;
@Inject
AccountGuestVlanMapDao _accountGuestVlanMapDao;
int _cidrLimit;
boolean _allowSubdomainNetworkAccess;
@ -2534,6 +2538,19 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
txn.close();
throw new InvalidParameterValueException("Some of the vnets from this range are allocated, can only remove a range which has no allocated vnets");
}
// If the range is partially dedicated to an account fail the request
List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(network.getId());
for (AccountGuestVlanMapVO map : maps) {
String[] vlans = map.getGuestVlanRange().split("-");
Integer dedicatedStartVlan = Integer.parseInt(vlans[0]);
Integer dedicatedEndVlan = Integer.parseInt(vlans[1]);
if ((start >= dedicatedStartVlan && start <= dedicatedEndVlan) || (end >= dedicatedStartVlan && end <= dedicatedEndVlan)) {
txn.close();
throw new InvalidParameterValueException("Vnet range " + map.getGuestVlanRange() + " is dedicated" +
" to an account. The specified range " + start + "-" + end + " overlaps with the dedicated range " +
" Please release the overlapping dedicated range before deleting the range");
}
}
for (i=0; i<existingRanges.size(); i++){
if (existingRanges.get(i).first()<= start & existingRanges.get(i).second()>= end){
temp = existingRanges.get(i).second();
@ -2564,6 +2581,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
_physicalNetworkDao.update(network.getId(), network);
txn.commit();
_physicalNetworkDao.releaseFromLockTable(network.getId());
return true;
}
@ -2700,6 +2718,260 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_GUEST_VLAN_RANGE_DEDICATE, eventDescription = "dedicating guest vlan range", async = false)
public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
String vlan = cmd.getVlan();
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
Long physicalNetworkId = cmd.getPhysicalNetworkId();
Long projectId = cmd.getProjectId();
int startVlan, endVlan;
String updatedVlanRange = null;
long guestVlanMapId = 0;
long guestVlanMapAccountId = 0;
// Verify 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("Unable to find account by name " + accountName);
}
}
// Verify physical network isolation type is VLAN
PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
if (physicalNetwork == null ) {
throw new InvalidParameterValueException("Unable to find physical network by id " + physicalNetworkId);
} else if (physicalNetwork.getIsolationMethods() == null || !physicalNetwork.getIsolationMethods().contains("VLAN")) {
throw new InvalidParameterValueException("Cannot dedicate guest vlan range. " +
"Physical isolation type of network " + physicalNetworkId + " is not VLAN");
}
// Get the start and end vlan
String[] vlanRange = vlan.split("-");
if (vlanRange.length != 2) {
throw new InvalidParameterValueException("Invalid format for parameter value vlan " + vlan + " .Vlan should be specified as 'startvlan-endvlan'");
}
try {
startVlan = Integer.parseInt(vlanRange[0]);
endVlan = Integer.parseInt(vlanRange[1]);
} catch (NumberFormatException e) {
s_logger.warn("Unable to parse guest vlan range:", e);
throw new InvalidParameterValueException("Please provide valid guest vlan range");
}
// Verify guest vlan range exists in the system
List <Pair <Integer,Integer>> existingRanges = physicalNetwork.getVnet();
Boolean exists = false;
if (!existingRanges.isEmpty()) {
for (int i=0 ; i < existingRanges.size(); i++){
int existingStartVlan = existingRanges.get(i).first();
int existingEndVlan = existingRanges.get(i).second();
if (startVlan >= existingStartVlan && endVlan <= existingEndVlan) {
exists = true;
break;
}
}
if (!exists) {
throw new InvalidParameterValueException("Unable to find guest vlan by range " + vlan);
}
}
// Verify guest vlans in the range don't belong to a network of a different account
for (int i = startVlan; i <= endVlan; i++) {
List<DataCenterVnetVO> allocatedVlans = _datacneter_vnet.listAllocatedVnetsInRange(physicalNetwork.getDataCenterId(), physicalNetwork.getId(), startVlan, endVlan);
if (allocatedVlans != null && !allocatedVlans.isEmpty()){
for (DataCenterVnetVO allocatedVlan : allocatedVlans) {
if (allocatedVlan.getAccountId() != vlanOwner.getAccountId()) {
throw new InvalidParameterValueException("Guest vlan from this range " + allocatedVlan.getVnet() + " is allocated to a different account." +
" Can only dedicate a range which has no allocated vlans or has vlans allocated to the same account ");
}
}
}
}
List<AccountGuestVlanMapVO> guestVlanMaps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(physicalNetworkId);
for (AccountGuestVlanMapVO guestVlanMap : guestVlanMaps) {
List<Integer> vlanTokens = getVlanFromRange(guestVlanMap.getGuestVlanRange());
int dedicatedStartVlan = vlanTokens.get(0).intValue();
int dedicatedEndVlan = vlanTokens.get(1).intValue();
guestVlanMapId = guestVlanMap.getId();
guestVlanMapAccountId = guestVlanMap.getAccountId();
// Verify if range is already dedicated
if (startVlan >= dedicatedStartVlan && endVlan <= dedicatedEndVlan) {
if (guestVlanMap.getAccountId() != vlanOwner.getAccountId()) {
throw new InvalidParameterValueException("Vlan range is already dedicated to another account. Cannot dedicate guest vlan range " + vlan);
} else {
s_logger.debug("Vlan range " + vlan +" is already dedicated to the specified account" + accountName);
return guestVlanMap;
}
}
// Verify if range overlaps with an existing range
if (startVlan < dedicatedStartVlan & endVlan+1 >= dedicatedStartVlan & endVlan <= dedicatedEndVlan) { // extend to the left
updatedVlanRange = startVlan + "-" + dedicatedEndVlan;
break;
} else if (startVlan >= dedicatedStartVlan & startVlan-1 <= dedicatedEndVlan & endVlan > dedicatedEndVlan) { // extend to right
updatedVlanRange = dedicatedStartVlan + "-" + endVlan;
break;
} else if (startVlan < dedicatedStartVlan & endVlan > dedicatedEndVlan){ // extend to the left and right
updatedVlanRange = startVlan + "-" + endVlan;
break;
}
}
AccountGuestVlanMapVO accountGuestVlanMapVO;
if (updatedVlanRange != null) {
if (guestVlanMapAccountId != vlanOwner.getAccountId()) {
throw new InvalidParameterValueException("Vlan range is partially dedicated to another account. Cannot dedicate guest vlan range " + vlan);
}
accountGuestVlanMapVO = _accountGuestVlanMapDao.findById(guestVlanMapId);
accountGuestVlanMapVO.setGuestVlanRange(updatedVlanRange);
_accountGuestVlanMapDao.update(guestVlanMapId, accountGuestVlanMapVO);
} else {
Transaction txn = Transaction.currentTxn();
accountGuestVlanMapVO = new AccountGuestVlanMapVO(vlanOwner.getAccountId(), physicalNetworkId);
accountGuestVlanMapVO.setGuestVlanRange(startVlan + "-" + endVlan);
_accountGuestVlanMapDao.persist(accountGuestVlanMapVO);
txn.commit();
}
// For every guest vlan set the corresponding account guest vlan map id
for (int i = startVlan; i <= endVlan; i++) {
List<DataCenterVnetVO> dataCenterVnet = _datacneter_vnet.findVnet(physicalNetwork.getDataCenterId(),((Integer)i).toString());
dataCenterVnet.get(0).setAccountGuestVlanMapId(accountGuestVlanMapVO.getId());
_datacneter_vnet.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0));
}
return accountGuestVlanMapVO;
}
private List<Integer> getVlanFromRange(String vlanRange) {
// Get the start and end vlan
String[] vlanTokens = vlanRange.split("-");
List<Integer> tokens = new ArrayList<Integer>();
try {
int startVlan = Integer.parseInt(vlanTokens[0]);
int endVlan = Integer.parseInt(vlanTokens[1]);
tokens.add(startVlan);
tokens.add(endVlan);
} catch (NumberFormatException e) {
s_logger.warn("Unable to parse guest vlan range:", e);
throw new InvalidParameterValueException("Please provide valid guest vlan range");
}
return tokens;
}
@Override
public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
Long id = cmd.getId();
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
Long projectId = cmd.getProjectId();
String guestVlanRange = cmd.getGuestVlanRange();
Long physicalNetworkId = cmd.getPhysicalNetworkId();
Long zoneId = cmd.getZoneId();
Long accountId = null;
if (accountName != null && domainId != null) {
if (projectId != null) {
throw new InvalidParameterValueException("Account and projectId can't be specified together");
}
Account account = _accountDao.findActiveAccount(accountName, domainId);
if (account == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account " + accountName);
ex.addProxyObject("domain", domainId, "domainId");
throw ex;
} else {
accountId = account.getId();
}
}
// set project information
if (projectId != null) {
Project project = _projectMgr.getProject(projectId);
if (project == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project by id " + projectId);
ex.addProxyObject(project, projectId, "projectId");
throw ex;
}
accountId = project.getProjectAccountId();
}
SearchBuilder<AccountGuestVlanMapVO> sb = _accountGuestVlanMapDao.createSearchBuilder();
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
sb.and("guestVlanRange", sb.entity().getGuestVlanRange(), SearchCriteria.Op.EQ);
sb.and("physicalNetworkId", sb.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
if (zoneId != null) {
SearchBuilder<PhysicalNetworkVO> physicalnetworkSearch = _physicalNetworkDao.createSearchBuilder();
physicalnetworkSearch.and("zoneId", physicalnetworkSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
sb.join("physicalnetworkSearch", physicalnetworkSearch, sb.entity().getPhysicalNetworkId(), physicalnetworkSearch.entity().getId(), JoinBuilder.JoinType.INNER);
}
SearchCriteria<AccountGuestVlanMapVO> sc = sb.create();
if (id != null) {
sc.setParameters("id", id);
}
if (accountId != null) {
sc.setParameters("accountId", accountId);
}
if (guestVlanRange != null) {
sc.setParameters("guestVlanRange", guestVlanRange);
}
if (physicalNetworkId != null) {
sc.setParameters("physicalNetworkId", physicalNetworkId);
}
if (zoneId != null) {
sc.setJoinParameters("physicalnetworkSearch", "zoneId", zoneId);
}
Filter searchFilter = new Filter(AccountGuestVlanMapVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
Pair<List<AccountGuestVlanMapVO>, Integer> result = _accountGuestVlanMapDao.searchAndCount(sc, searchFilter);
return new Pair<List<? extends GuestVlan>, Integer>(result.first(), result.second());
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, eventDescription = "releasing" +
" dedicated guest vlan range", async = true)
@DB
public boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId) {
// Verify dedicated range exists
AccountGuestVlanMapVO dedicatedGuestVlan = _accountGuestVlanMapDao.findById(dedicatedGuestVlanRangeId);
if (dedicatedGuestVlan == null) {
throw new InvalidParameterValueException("Dedicated guest vlan with specified" +
" id doesn't exist in the system");
}
// Remove dedication for the guest vlan
_datacneter_vnet.releaseDedicatedGuestVlans(dedicatedGuestVlan.getId());
if (_accountGuestVlanMapDao.remove(dedicatedGuestVlanRangeId)) {
return true;
} else {
return false;
}
}
@Override
public List<? extends Service> listNetworkServices(String providerName) {

View File

@ -0,0 +1,34 @@
// 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.network.dao;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.utils.db.GenericDao;
import java.util.List;
public interface AccountGuestVlanMapDao extends GenericDao<AccountGuestVlanMapVO, Long> {
public List<AccountGuestVlanMapVO> listAccountGuestVlanMapsByAccount(long accountId);
public List<AccountGuestVlanMapVO> listAccountGuestVlanMapsByVlan(long guestVlanId);
public List<AccountGuestVlanMapVO> listAccountGuestVlanMapsByPhysicalNetwork(long physicalNetworkId);
public int removeByAccountId(long accountId);
}

View File

@ -0,0 +1,83 @@
// 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.network.dao;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.dao.AccountGuestVlanMapDao;
import java.util.List;
import javax.ejb.Local;
import org.springframework.stereotype.Component;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@Component
@Local(value={AccountGuestVlanMapDao.class})
@DB(txn=false)
public class AccountGuestVlanMapDaoImpl extends GenericDaoBase<AccountGuestVlanMapVO, Long> implements AccountGuestVlanMapDao {
protected SearchBuilder<AccountGuestVlanMapVO> AccountSearch;
protected SearchBuilder<AccountGuestVlanMapVO> GuestVlanSearch;
protected SearchBuilder<AccountGuestVlanMapVO> PhysicalNetworkSearch;
@Override
public List<AccountGuestVlanMapVO> listAccountGuestVlanMapsByAccount(long accountId) {
SearchCriteria<AccountGuestVlanMapVO> sc = AccountSearch.create();
sc.setParameters("accountId", accountId);
return listIncludingRemovedBy(sc);
}
@Override
public List<AccountGuestVlanMapVO> listAccountGuestVlanMapsByVlan(long guestVlanId) {
SearchCriteria<AccountGuestVlanMapVO> sc = GuestVlanSearch.create();
sc.setParameters("guestVlanId", guestVlanId);
return listIncludingRemovedBy(sc);
}
@Override
public List<AccountGuestVlanMapVO> listAccountGuestVlanMapsByPhysicalNetwork(long physicalNetworkId) {
SearchCriteria<AccountGuestVlanMapVO> sc = GuestVlanSearch.create();
sc.setParameters("physicalNetworkId", physicalNetworkId);
return listIncludingRemovedBy(sc);
}
@Override
public int removeByAccountId(long accountId) {
SearchCriteria<AccountGuestVlanMapVO> sc = AccountSearch.create();
sc.setParameters("accountId", accountId);
return expunge(sc);
}
public AccountGuestVlanMapDaoImpl() {
super();
AccountSearch = createSearchBuilder();
AccountSearch.and("accountId", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
AccountSearch.done();
GuestVlanSearch = createSearchBuilder();
GuestVlanSearch.and("guestVlanId", GuestVlanSearch.entity().getId(), SearchCriteria.Op.EQ);
GuestVlanSearch.done();
PhysicalNetworkSearch = createSearchBuilder();
PhysicalNetworkSearch.and("physicalNetworkId", PhysicalNetworkSearch.entity().getId(), SearchCriteria.Op.EQ);
PhysicalNetworkSearch.done();
}
}

View File

@ -0,0 +1,94 @@
// 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.network.dao;
import com.cloud.network.GuestVlan;
import javax.persistence.*;
import java.util.UUID;
@Entity
@Table(name="account_vnet_map")
public class AccountGuestVlanMapVO implements GuestVlan {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private long id;
@Column(name="account_id")
private long accountId;
@Column(name="uuid")
private String uuid;
@Column(name="vnet_range")
private String guestVlanRange;
@Column(name="physical_network_id")
private long physicalNetworkId;
public AccountGuestVlanMapVO(long accountId,long physicalNetworkId) {
this.accountId = accountId;
this.physicalNetworkId = physicalNetworkId;
this.guestVlanRange = null;
this.uuid = UUID.randomUUID().toString();
}
public AccountGuestVlanMapVO() {
}
@Override
public long getId() {
return id;
}
@Override
public long getAccountId() {
return accountId;
}
@Override
public String getGuestVlanRange() {
return guestVlanRange;
}
public void setGuestVlanRange(String guestVlanRange) {
this.guestVlanRange = guestVlanRange;
}
@Override
public String getUuid() {
return this.uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@Override
public long getPhysicalNetworkId() {
return this.physicalNetworkId;
}
public void setPhysicalNetworkId(long physicalNetworkId) {
this.physicalNetworkId = physicalNetworkId;
}
}

View File

@ -2258,6 +2258,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(UpdateNetworkServiceProviderCmd.class);
cmdList.add(UpdatePhysicalNetworkCmd.class);
cmdList.add(UpdateStorageNetworkIpRangeCmd.class);
cmdList.add(DedicateGuestVlanRangeCmd.class);
cmdList.add(ListDedicatedGuestVlanRangesCmd.class);
cmdList.add(ReleaseDedicatedGuestVlanRangeCmd.class);
cmdList.add(CreateDiskOfferingCmd.class);
cmdList.add(CreateServiceOfferingCmd.class);
cmdList.add(DeleteDiskOfferingCmd.class);

View File

@ -59,6 +59,7 @@ import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.configuration.dao.ResourceCountDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterVnetDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
@ -76,6 +77,8 @@ import com.cloud.network.IpAddress;
import com.cloud.network.NetworkManager;
import com.cloud.network.VpnUserVO;
import com.cloud.network.as.AutoScaleManager;
import com.cloud.network.dao.AccountGuestVlanMapDao;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDao;
@ -222,6 +225,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
@Inject VolumeManager volumeMgr;
@Inject
private AffinityGroupDao _affinityGroupDao;
@Inject
private AccountGuestVlanMapDao _accountGuestVlanMapDao;
@Inject
private DataCenterVnetDao _dataCenterVnetDao;
private List<UserAuthenticator> _userAuthenticators;
List<UserAuthenticator> _userPasswordEncoders;
@ -699,6 +706,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
}
}
// release account specific guest vlans
List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(accountId);
for (AccountGuestVlanMapVO map : maps) {
_dataCenterVnetDao.releaseDedicatedGuestVlans(map.getId());
}
int vlansReleased = _accountGuestVlanMapDao.removeByAccountId(accountId);
s_logger.info("deleteAccount: Released " + vlansReleased + " dedicated guest vlan ranges from account " + accountId);
return true;
} catch (Exception ex) {
s_logger.warn("Failed to cleanup account " + account + " due to ", ex);

View File

@ -0,0 +1,378 @@
// 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.network;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.lang.reflect.Field;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
import org.apache.cloudstack.api.command.admin.network.ReleaseDedicatedGuestVlanRangeCmd;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import com.cloud.dc.DataCenterVnetVO;
import com.cloud.dc.dao.DataCenterVnetDao;
import com.cloud.network.dao.AccountGuestVlanMapDao;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.projects.ProjectManager;
import com.cloud.user.Account;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.UserContext;
import com.cloud.utils.db.Transaction;
import junit.framework.Assert;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.doNothing;
public class DedicateGuestVlanRangesTest {
private static final Logger s_logger = Logger.getLogger(DedicateGuestVlanRangesTest.class);
NetworkServiceImpl networkService = new NetworkServiceImpl();
DedicateGuestVlanRangeCmd dedicateGuestVlanRangesCmd = new DedicateGuestVlanRangeCmdExtn();
Class<?> _dedicateGuestVlanRangeClass = dedicateGuestVlanRangesCmd.getClass().getSuperclass();
ReleaseDedicatedGuestVlanRangeCmd releaseDedicatedGuestVlanRangesCmd = new ReleaseDedicatedGuestVlanRangeCmdExtn();
Class<?> _releaseGuestVlanRangeClass = releaseDedicatedGuestVlanRangesCmd.getClass().getSuperclass();
ListDedicatedGuestVlanRangesCmd listDedicatedGuestVlanRangesCmd = new ListDedicatedGuestVlanRangesCmdExtn();
Class<?> _listDedicatedGuestVlanRangeClass = listDedicatedGuestVlanRangesCmd.getClass().getSuperclass();
@Mock AccountManager _accountMgr;
@Mock AccountDao _accountDao;
@Mock ProjectManager _projectMgr;
@Mock PhysicalNetworkDao _physicalNetworkDao;
@Mock DataCenterVnetDao _dataCenterVnetDao;
@Mock AccountGuestVlanMapDao _accountGuestVlanMapDao;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
networkService._accountMgr = _accountMgr;
networkService._accountDao = _accountDao;
networkService._projectMgr = _projectMgr;
networkService._physicalNetworkDao = _physicalNetworkDao;
networkService._datacneter_vnet = _dataCenterVnetDao;
networkService._accountGuestVlanMapDao = _accountGuestVlanMapDao;
Account account = (Account) new AccountVO("testaccount", 1, "networkdomain", (short) 0, UUID.randomUUID().toString());
when(networkService._accountMgr.getAccount(anyLong())).thenReturn(account);
when(networkService._accountDao.findActiveAccount(anyString(), anyLong())).thenReturn(account);
UserContext.registerContext(1, account, null, true);
Field accountNameField = _dedicateGuestVlanRangeClass.getDeclaredField("accountName");
accountNameField.setAccessible(true);
accountNameField.set(dedicateGuestVlanRangesCmd, "accountname");
Field projectIdField = _dedicateGuestVlanRangeClass.getDeclaredField("projectId");
projectIdField.setAccessible(true);
projectIdField.set(dedicateGuestVlanRangesCmd, null);
Field domainIdField = _dedicateGuestVlanRangeClass.getDeclaredField("domainId");
domainIdField.setAccessible(true);
domainIdField.set(dedicateGuestVlanRangesCmd, 1L);
Field physicalNetworkIdField = _dedicateGuestVlanRangeClass.getDeclaredField("physicalNetworkId");
physicalNetworkIdField.setAccessible(true);
physicalNetworkIdField.set(dedicateGuestVlanRangesCmd, 1L);
Field releaseIdField = _releaseGuestVlanRangeClass.getDeclaredField("id");
releaseIdField.setAccessible(true);
releaseIdField.set(releaseDedicatedGuestVlanRangesCmd, 1L);
}
@Test
public void testDedicateGuestVlanRange() throws Exception {
s_logger.info("Running tests for DedicateGuestVlanRange API");
/*
* TEST 1: given valid parameters DedicateGuestVlanRange should succeed
*/
runDedicateGuestVlanRangePostiveTest();
/*
* TEST 2: given invalid format for vlan range DedicateGuestVlanRange should fail
*/
runDedicateGuestVlanRangeInvalidFormat();
/*
* TEST 3: given vlan range that doesn't exist in the system request should fail
*/
runDedicateGuestVlanRangeInvalidRangeValue();
/*
* TEST 4: given vlan range has vlans that are allocated to a different account request should fail
*/
runDedicateGuestVlanRangeAllocatedVlans();
/*
* TEST 5: given vlan range is already dedicated to another account request should fail
*/
runDedicateGuestVlanRangeDedicatedRange();
/*
* TEST 6: given vlan range is partially dedicated to a different account request should fail
*/
runDedicateGuestVlanRangePartiallyDedicated();
}
@Test
public void testReleaseDedicatedGuestVlanRange() throws Exception {
s_logger.info("Running tests for ReleaseDedicatedGuestVlanRange API");
/*
* TEST 1: given valid parameters ReleaseDedicatedGuestVlanRange should succeed
*/
runReleaseDedicatedGuestVlanRangePostiveTest();
/*
* TEST 2: given range doesn't exist request should fail
*/
runReleaseDedicatedGuestVlanRangeInvalidRange();
}
void runDedicateGuestVlanRangePostiveTest() throws Exception {
Transaction txn = Transaction.open("runDedicateGuestVlanRangePostiveTest");
Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan");
dedicateVlanField.setAccessible(true);
dedicateVlanField.set(dedicateGuestVlanRangesCmd, "2-5");
PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO(1L, 1L, "2-5", "200", 1L, null, "testphysicalnetwork");
physicalNetwork.addIsolationMethod("VLAN");
AccountGuestVlanMapVO accountGuestVlanMapVO = new AccountGuestVlanMapVO(1L,1L);
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
when(networkService._datacneter_vnet.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
when(networkService._accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(anyLong())).thenReturn(null);
when(networkService._accountGuestVlanMapDao.persist(any(AccountGuestVlanMapVO.class))).thenReturn(accountGuestVlanMapVO);
when(networkService._datacneter_vnet.update(anyLong(), any(DataCenterVnetVO.class))).thenReturn(true);
List<DataCenterVnetVO> dataCenterVnetList = new ArrayList<DataCenterVnetVO>();
DataCenterVnetVO dataCenterVnetVO = new DataCenterVnetVO("2-5", 1L, 1L);
dataCenterVnetList.add(dataCenterVnetVO);
when(networkService._datacneter_vnet.findVnet(anyLong(), anyString())).thenReturn(dataCenterVnetList);
try {
GuestVlan result = networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
Assert.assertNotNull(result);
} catch (Exception e) {
s_logger.info("exception in testing runDedicateGuestVlanRangePostiveTest message: " + e.toString());
} finally {
txn.close("runDedicateGuestRangePostiveTest");
}
}
void runDedicateGuestVlanRangeInvalidFormat() throws Exception {
Transaction txn = Transaction.open("runDedicateGuestVlanRangeInvalidFormat");
Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan");
dedicateVlanField.setAccessible(true);
dedicateVlanField.set(dedicateGuestVlanRangesCmd, "2");
PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO(1L, 1L, "2-5", "200", 1L, null, "testphysicalnetwork");
physicalNetwork.addIsolationMethod("VLAN");
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
try {
networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains("Invalid format for parameter value vlan"));
} finally {
txn.close("runDedicateGuestVlanRangeInvalidFormat");
}
}
void runDedicateGuestVlanRangeInvalidRangeValue() throws Exception {
Transaction txn = Transaction.open("runDedicateGuestVlanRangeInvalidRangeValue");
Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan");
dedicateVlanField.setAccessible(true);
dedicateVlanField.set(dedicateGuestVlanRangesCmd, "2-5");
PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO(1L, 1L, "6-10", "200", 1L, null, "testphysicalnetwork");
physicalNetwork.addIsolationMethod("VLAN");
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
try {
networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains("Unable to find guest vlan by range"));
} finally {
txn.close("runDedicateGuestVlanRangeInvalidRangeValue");
}
}
void runDedicateGuestVlanRangeAllocatedVlans() throws Exception {
Transaction txn = Transaction.open("runDedicateGuestVlanRangeAllocatedVlans");
Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan");
dedicateVlanField.setAccessible(true);
dedicateVlanField.set(dedicateGuestVlanRangesCmd, "2-5");
PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO(1L, 1L, "2-5", "200", 1L, null, "testphysicalnetwork");
physicalNetwork.addIsolationMethod("VLAN");
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
List<DataCenterVnetVO> dataCenterList = new ArrayList<DataCenterVnetVO>();
DataCenterVnetVO dataCenter = new DataCenterVnetVO("2-5", 1L, 1L);
dataCenter.setAccountId(1L);
dataCenterList.add(dataCenter);
when(networkService._datacneter_vnet.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(dataCenterList);
try {
networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains("is allocated to a different account"));
} finally {
txn.close("runDedicateGuestVlanRangeAllocatedVlans");
}
}
void runDedicateGuestVlanRangeDedicatedRange() throws Exception {
Transaction txn = Transaction.open("runDedicateGuestVlanRangeDedicatedRange");
Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan");
dedicateVlanField.setAccessible(true);
dedicateVlanField.set(dedicateGuestVlanRangesCmd, "2-5");
PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO(1L, 1L, "2-5", "200", 1L, null, "testphysicalnetwork");
physicalNetwork.addIsolationMethod("VLAN");
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
when(networkService._datacneter_vnet.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
List<AccountGuestVlanMapVO> guestVlanMaps = new ArrayList<AccountGuestVlanMapVO>();
AccountGuestVlanMapVO accountGuestVlanMap = new AccountGuestVlanMapVO(1L, 1L);
accountGuestVlanMap.setGuestVlanRange("2-5");
guestVlanMaps.add(accountGuestVlanMap);
when(networkService._accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(anyLong())).thenReturn(guestVlanMaps);
try {
networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated to another account"));
} finally {
txn.close("runDedicateGuestVlanRangeDedicatedRange");
}
}
void runDedicateGuestVlanRangePartiallyDedicated() throws Exception {
Transaction txn = Transaction.open("runDedicateGuestVlanRangePartiallyDedicated");
Field dedicateVlanField = _dedicateGuestVlanRangeClass.getDeclaredField("vlan");
dedicateVlanField.setAccessible(true);
dedicateVlanField.set(dedicateGuestVlanRangesCmd, "2-5");
PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO(1L, 1L, "2-5", "200", 1L, null, "testphysicalnetwork");
physicalNetwork.addIsolationMethod("VLAN");
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
when(networkService._datacneter_vnet.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
List<AccountGuestVlanMapVO> guestVlanMaps = new ArrayList<AccountGuestVlanMapVO>();
AccountGuestVlanMapVO accountGuestVlanMap = new AccountGuestVlanMapVO(2L, 1L);
accountGuestVlanMap.setGuestVlanRange("4-8");
guestVlanMaps.add(accountGuestVlanMap);
when(networkService._accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(anyLong())).thenReturn(guestVlanMaps);
try {
networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains("Vlan range is partially dedicated to another account"));
} finally {
txn.close("runDedicateGuestVlanRangePartiallyDedicated");
}
}
void runReleaseDedicatedGuestVlanRangePostiveTest() throws Exception {
Transaction txn = Transaction.open("runReleaseDedicatedGuestVlanRangePostiveTest");
AccountGuestVlanMapVO accountGuestVlanMap = new AccountGuestVlanMapVO(1L, 1L);
when(networkService._accountGuestVlanMapDao.findById(anyLong())).thenReturn(accountGuestVlanMap);
doNothing().when(networkService._datacneter_vnet).releaseDedicatedGuestVlans(anyLong());
when(networkService._accountGuestVlanMapDao.remove(anyLong())).thenReturn(true);
try {
Boolean result = networkService.releaseDedicatedGuestVlanRange(releaseDedicatedGuestVlanRangesCmd.getId());
Assert.assertTrue(result);
} catch (Exception e) {
s_logger.info("exception in testing runReleaseGuestVlanRangePostiveTest1 message: " + e.toString());
} finally {
txn.close("runReleaseDedicatedGuestVlanRangePostiveTest");
}
}
void runReleaseDedicatedGuestVlanRangeInvalidRange() throws Exception {
Transaction txn = Transaction.open("runReleaseDedicatedGuestVlanRangeInvalidRange");
when(networkService._accountGuestVlanMapDao.findById(anyLong())).thenReturn(null);
try {
networkService.releaseDedicatedGuestVlanRange(releaseDedicatedGuestVlanRangesCmd.getId());
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains("Dedicated guest vlan with specified id doesn't exist in the system"));
} finally {
txn.close("runReleaseDedicatedGuestVlanRangeInvalidRange");
}
}
public class DedicateGuestVlanRangeCmdExtn extends DedicateGuestVlanRangeCmd {
public long getEntityOwnerId() {
return 1;
}
}
public class ReleaseDedicatedGuestVlanRangeCmdExtn extends ReleaseDedicatedGuestVlanRangeCmd {
public long getEntityOwnerId() {
return 1;
}
}
public class ListDedicatedGuestVlanRangesCmdExtn extends ListDedicatedGuestVlanRangesCmd {
public long getEntityOwnerId() {
return 1;
}
}
}

View File

@ -29,6 +29,7 @@ import com.cloud.network.Networks.TrafficType;
import com.cloud.network.addr.PublicIp;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.GuestVlan;
import com.cloud.network.element.LoadBalancingServiceProvider;
import com.cloud.network.element.StaticNatServiceProvider;
import com.cloud.network.element.UserDataServiceProvider;
@ -46,6 +47,8 @@ import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.*;
import com.cloud.vm.VirtualMachine.Type;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
@ -326,6 +329,24 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
}
@Override
public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
// TODO Auto-generated method stub
return null;
}
@Override
public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId) {
// TODO Auto-generated method stub
return true;
}
@Override
public List<? extends Service> listNetworkServices(String providerName) {
// TODO Auto-generated method stub
return null;

View File

@ -28,6 +28,7 @@ import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.addr.PublicIp;
import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.NetworkVO;
@ -50,6 +51,8 @@ import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.*;
import com.cloud.vm.VirtualMachine.Type;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
@ -338,9 +341,24 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
return false;
}
@Override
public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
// TODO Auto-generated method stub
return null;
}
@Override
public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId) {
// TODO Auto-generated method stub
return true;
}
/* (non-Javadoc)
* @see com.cloud.network.NetworkService#listNetworkServices(java.lang.String)

View File

@ -72,6 +72,7 @@ import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkService;
import com.cloud.network.StorageNetworkManager;
import com.cloud.network.dao.AccountGuestVlanMapDaoImpl;
import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
import com.cloud.network.dao.FirewallRulesDaoImpl;
import com.cloud.network.dao.IPAddressDaoImpl;
@ -136,7 +137,7 @@ import com.cloud.vm.dao.VMInstanceDaoImpl;
FirewallRulesCidrsDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkTrafficTypeDaoImpl.class,
PhysicalNetworkServiceProviderDaoImpl.class, LoadBalancerDaoImpl.class, NetworkServiceMapDaoImpl.class,
PrimaryDataStoreDaoImpl.class, StoragePoolDetailsDaoImpl.class, AffinityGroupServiceImpl.class,
ComponentContext.class, AffinityGroupProcessor.class, UserVmVO.class, EventUtils.class, UserVmVO.class
ComponentContext.class, AffinityGroupProcessor.class, UserVmVO.class, EventUtils.class, UserVmVO.class, AccountGuestVlanMapDaoImpl.class
}, includeFilters = { @Filter(value = AffinityApiTestConfiguration.Library.class, type = FilterType.CUSTOM) }, useDefaultFilters = false)
public class AffinityApiTestConfiguration {

View File

@ -53,6 +53,7 @@ import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkService;
import com.cloud.network.StorageNetworkManager;
import com.cloud.network.dao.AccountGuestVlanMapDaoImpl;
import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
import com.cloud.network.dao.FirewallRulesDaoImpl;
import com.cloud.network.dao.IPAddressDaoImpl;
@ -146,7 +147,8 @@ import com.cloud.vm.dao.VMInstanceDaoImpl;
LoadBalancerDaoImpl.class,
NetworkServiceMapDaoImpl.class,
PrimaryDataStoreDaoImpl.class,
StoragePoolDetailsDaoImpl.class
StoragePoolDetailsDaoImpl.class,
AccountGuestVlanMapDaoImpl.class
},
includeFilters={@Filter(value=ChildTestConfiguration.Library.class, type=FilterType.CUSTOM)},
useDefaultFilters=false

View File

@ -1115,6 +1115,7 @@ CREATE VIEW `cloud`.`account_view` AS
and async_job.instance_type = 'Account'
and async_job.job_status = 0;
alter table `cloud_usage`.`usage_network_offering` add column nic_id bigint(20) unsigned NOT NULL;
ALTER TABLE `cloud`.`data_center_details` MODIFY value varchar(1024);
ALTER TABLE `cloud`.`cluster_details` MODIFY value varchar(255);
@ -1126,3 +1127,19 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'manage
alter table cloud.vpc_gateways add column source_nat boolean default false;
alter table cloud.private_ip_address add column source_nat boolean default false;
CREATE TABLE `cloud`.`account_vnet_map` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
`uuid` varchar(255) UNIQUE,
`vnet_range` varchar(255) NOT NULL COMMENT 'dedicated guest vlan range',
`account_id` bigint unsigned NOT NULL COMMENT 'account id. foreign key to account table',
`physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id. foreign key to the the physical network table',
PRIMARY KEY (`id`),
CONSTRAINT `fk_account_vnet_map__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network` (`id`) ON DELETE CASCADE,
INDEX `i_account_vnet_map__physical_network_id`(`physical_network_id`),
CONSTRAINT `fk_account_vnet_map__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE,
INDEX `i_account_vnet_map__account_id`(`account_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `cloud`.`op_dc_vnet_alloc` ADD COLUMN account_vnet_map_id bigint unsigned;
ALTER TABLE `cloud`.`op_dc_vnet_alloc` ADD CONSTRAINT `fk_op_dc_vnet_alloc__account_vnet_map_id` FOREIGN KEY `fk_op_dc_vnet_alloc__account_vnet_map_id` (`account_vnet_map_id`) REFERENCES `account_vnet_map` (`id`);

View File

@ -0,0 +1,157 @@
# 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 Guest Vlan Ranges
"""
#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 Guest Vlan Ranges
"""
def __init__(self):
self.services = {
"domain": {
"name": "Domain",
},
"account": {
"email": "test@test.com",
"firstname": "Test",
"lastname": "User",
"username": "test",
"password": "password",
},
"name": "testphysicalnetwork"
}
class TesDedicateGuestVlanRange(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.api_client = super(TesDedicateGuestVlanRange, 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=["simulator", "advanced", "guestvlanrange", "dedicate", "release"])
def test_dedicateGuestVlanRange(self):
"""Test guest vlan range dedication
"""
"""Assume a physical network is available
"""
# Validate the following:
# 1. List the available physical network using ListPhysicalNetwork
# 2. Add a Guest Vlan range to the available physical network using UpdatePhysicalNetwork
# 3. Dedicate the created guest vlan range to user account using DedicateGuestVlanRange
# 4. Verify vlan range is dedicated with listDedicatedGuestVlanRanges
# 5. Release the dedicated guest vlan range back to the system
# 6. Verify guest vlan range has been released, verify with listDedicatedGuestVlanRanges
# 7. Remove the added guest vlan range using UpdatePhysicalNetwork
self.debug("Listing available physical network")
list_physical_network_response = PhysicalNetwork.list(
self.apiclient
)
self.assertEqual(
isinstance(list_physical_network_response, list),
True,
"Check for list guest vlan range response"
)
physical_network_response = list_physical_network_response[0]
self.debug("Adding guest vlan range")
addGuestVlanRangeResponse = physical_network_response.update(self.apiclient, id=physical_network_response.id, vlan="387-390")
self.debug("Dedicating guest vlan range");
dedicate_guest_vlan_range_response = PhysicalNetwork.dedicate(
self.apiclient,
"387-390",
physicalnetworkid=physical_network_response.id,
account=self.account.name,
domainid=self.account.domainid
)
list_dedicated_guest_vlan_range_response = PhysicalNetwork.listDedicated(
self.apiclient,
id=dedicate_guest_vlan_range_response.id
)
dedicated_guest_vlan_response = list_dedicated_guest_vlan_range_response[0]
self.assertEqual(
dedicated_guest_vlan_response.account,
self.account.name,
"Check account name is in listDedicatedGuestVlanRanges as the account the range is dedicated to"
)
self.debug("Releasing guest vlan range");
dedicated_guest_vlan_response.release(self.apiclient)
list_dedicated_guest_vlan_range_response = PhysicalNetwork.listDedicated(
self.apiclient,
id=dedicate_guest_vlan_range_response.id
)
dedicated_guest_vlan_response = list_dedicated_guest_vlan_range_response[0]
self.assertEqual(
dedicated_guest_vlan_response.account,
"system",
"Check account name is system account in listDedicatedGuestVlanRanges"
)
self.debug("Removing guest vlan range")
removeGuestVlanRangeResponse = physical_network_response.update(self.apiclient, id=physical_network_response.id, removevlan="387-390")

View File

@ -2178,6 +2178,33 @@ class PhysicalNetwork:
cmd.traffictype = type
return apiclient.addTrafficType(cmd)
@classmethod
def dedicate(cls, apiclient, vlanrange, physicalnetworkid, account=None, domainid=None, projectid=None):
"""Dedicate guest vlan range"""
cmd = dedicateGuestVlanRange.dedicateGuestVlanRangeCmd()
cmd.vlanrange = vlanrange
cmd.physicalnetworkid = physicalnetworkid
cmd.account = account
cmd.domainid = domainid
cmd.projectid = projectid
return PhysicalNetwork(apiclient.dedicateGuestVlanRange(cmd).__dict__)
def release(self, apiclient):
"""Release guest vlan range"""
cmd = releaseDedicatedGuestVlanRange.releaseDedicatedGuestVlanRangeCmd()
cmd.id = self.id
return apiclient.releaseDedicatedGuestVlanRange(cmd)
@classmethod
def listDedicated(cls, apiclient, **kwargs):
"""Lists all dedicated guest vlan ranges"""
cmd = listDedicatedGuestVlanRanges.listDedicatedGuestVlanRangesCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return map(lambda pn : PhysicalNetwork(pn.__dict__), apiclient.listDedicatedGuestVlanRanges(cmd))
@classmethod
def list(cls, apiclient, **kwargs):
"""Lists all physical networks"""