CLOUDSTACK-10024: Network migration support

Co-Authored-By: Frank Maximus frank.maximus@nuagenetworks.net
Co-Authored-By: Raf Smeets raf.smeets@nuagenetworks.net

New API’s:

* migrateNetwork
* migrateVpc
This commit is contained in:
Sigert Goeminne 2017-04-26 15:32:31 +02:00 committed by Frank Maximus
parent 12f526bbfe
commit d49765619d
85 changed files with 5297 additions and 511 deletions

View File

@ -130,6 +130,7 @@ public class EventTypes {
public static final String EVENT_NETWORK_CREATE = "NETWORK.CREATE";
public static final String EVENT_NETWORK_DELETE = "NETWORK.DELETE";
public static final String EVENT_NETWORK_UPDATE = "NETWORK.UPDATE";
public static final String EVENT_NETWORK_MIGRATE = "NETWORK.MIGRATE";
public static final String EVENT_FIREWALL_OPEN = "FIREWALL.OPEN";
public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE";
public static final String EVENT_FIREWALL_UPDATE = "FIREWALL.UPDATE";

View File

@ -36,6 +36,7 @@ import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.vpc.Vpc;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.user.User;
@ -82,6 +83,24 @@ public interface NetworkService {
Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, Long networkOfferingId,
Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String newUUID, boolean updateInSequence, boolean forced);
/**
* Migrate a network from one physical network to another physical network
* @param networkId of the network that needs to be migrated
* @param networkOfferingId new network offering id for the network
* @param resume if previous migration failed try to resume of just fail directly because anomaly is detected
* @return the migrated network
*/
Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume);
/**
* Migrate a vpc from on physical network to another physical network
* @param vpcId the id of the vpc that needs to be migrated
* @param vpcNetworkofferingId the new vpc offering id
* @param resume if previous migration failed try to resume of just fail directly because anomaly is detected
* @return the migrated vpc
*/
Vpc migrateVpcNetwork(long vpcId, long vpcNetworkofferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume);
PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List<String> isolationMethods, String broadcastDomainRange, Long domainId,
List<String> tags, String name);

View File

@ -246,6 +246,7 @@ public class Networks {
* encode a string into a BroadcastUri
* @param candidate the input string
* @return an URI containing an appropriate (possibly given) scheme and the value
*
*/
public static URI fromString(String candidate) {
try {

View File

@ -38,7 +38,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
}
public enum Detail {
InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits
InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits, RelatedNetworkOffering
}
public final static String SystemPublicNetwork = "System-Public-Network";

View File

@ -58,7 +58,9 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
LBStickinessPolicy(false, true),
LBHealthCheckPolicy(false, true),
SnapshotPolicy(false, true),
GuestOs(false, true);
GuestOs(false, true),
NetworkOffering(false, true),
VpcOffering(true, false);
ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) {

View File

@ -32,6 +32,8 @@ public interface NicSecondaryIp extends ControlledEntity, Identity, InternalIden
long getNicId();
void setNicId(long nicId);
String getIp4Address();
String getIp6Address();

View File

@ -332,6 +332,7 @@ public class ApiConstants {
public static final String COUNT = "count";
public static final String TRAFFIC_TYPE = "traffictype";
public static final String NETWORK_OFFERING_ID = "networkofferingid";
public static final String TIER_NETWORK_OFFERINGS = "tiernetworkofferings";
public static final String NETWORK_IDS = "networkids";
public static final String NETWORK_ID = "networkid";
public static final String NIC_ID = "nicid";
@ -375,6 +376,7 @@ public class ApiConstants {
public static final String ZONE_TOKEN = "zonetoken";
public static final String DHCP_PROVIDER = "dhcpprovider";
public static final String RESULT = "success";
public static final String RESUME = "resume";
public static final String LUN_ID = "lunId";
public static final String IQN = "iqn";
public static final String AGGREGATE_NAME = "aggregatename";

View File

@ -0,0 +1,155 @@
// 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 org.apache.log4j.Logger;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.context.CallContext;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.Network;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.user.User;
@APICommand(name = "migrateNetwork", description = "moves a network to another physical network", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {Network.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class MigrateNetworkCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(MigrateNetworkCmd.class.getName());
private static final String s_name = "migratenetworkresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@ACL(accessType = AccessType.OperateEntry)
@Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType = NetworkResponse.class,
required=true, description="the ID of the network")
protected Long id;
@Parameter(name = ApiConstants.NETWORK_OFFERING_ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, description = "network offering ID")
private Long networkOfferingId;
@Parameter(name = ApiConstants.RESUME, type = CommandType.BOOLEAN, description = "true if previous network migration cmd failed")
private Boolean resume;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public Long getNetworkOfferingId() {
return networkOfferingId;
}
public Boolean getResume() {
return resume != null ? resume : false;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
Network network = _networkService.getNetwork(id);
if (network == null) {
throw new InvalidParameterValueException("Networkd id=" + id + " doesn't exist");
} else {
return _networkService.getNetwork(id).getAccountId();
}
}
@Override
public void execute() {
User callerUser = _accountService.getActiveUser(CallContext.current().getCallingUserId());
Account callerAccount = _accountService.getActiveAccountById(callerUser.getAccountId());
Network network = _networkService.getNetwork(id);
if (network == null) {
throw new InvalidParameterValueException("Couldn't find network by id");
}
Network result =
_networkService.migrateGuestNetwork(getId(), getNetworkOfferingId(), callerAccount, callerUser, getResume());
if (result != null) {
NetworkResponse response = _responseGenerator.createNetworkResponse(ResponseView.Restricted, result);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update network");
}
}
@Override
public String getEventDescription() {
StringBuilder eventMsg = new StringBuilder("Migrating network: " + getId());
if (getNetworkOfferingId() != null) {
Network network = _networkService.getNetwork(getId());
if (network == null) {
throw new InvalidParameterValueException("Network id=" + id + " doesn't exist");
}
if (network.getNetworkOfferingId() != getNetworkOfferingId()) {
NetworkOffering oldOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
NetworkOffering newOff = _entityMgr.findById(NetworkOffering.class, getNetworkOfferingId());
if (newOff == null) {
throw new InvalidParameterValueException("Network offering id supplied is invalid");
}
eventMsg.append(". Original network offering id: " + oldOff.getUuid() + ", new network offering id: " + newOff.getUuid());
}
}
return eventMsg.toString();
}
@Override
public String getEventType() {
return EventTypes.EVENT_NETWORK_MIGRATE;
}
@Override
public String getSyncObjType() {
return BaseAsyncCmd.networkSyncObject;
}
@Override
public Long getSyncObjId() {
return id;
}
}

View File

@ -0,0 +1,144 @@
// 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 org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.VpcOfferingResponse;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.Map;
import com.cloud.event.EventTypes;
import com.cloud.network.vpc.Vpc;
import com.cloud.user.Account;
import com.cloud.user.User;
@APICommand(name = "migrateVPC", description = "moves a vpc to another physical network", responseObject = VpcResponse.class, responseView = ResponseObject.ResponseView.Restricted, entityType = {Vpc.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class MigrateVPCCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(MigrateVPCCmd.class.getName());
private static final String s_name = "migratevpcresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@ACL(accessType = SecurityChecker.AccessType.OperateEntry)
@Parameter(name= ApiConstants.VPC_ID, type=CommandType.UUID, entityType = VpcResponse.class,
required=true, description = "the ID of the vpc")
protected Long id;
@Parameter(name = ApiConstants.VPC_OFF_ID, type = CommandType.UUID, entityType = VpcOfferingResponse.class, required=true, description = "vpc offering ID")
private Long vpcOfferingId;
@Parameter(name = ApiConstants.TIER_NETWORK_OFFERINGS, type = CommandType.MAP, description = "network offering ids for each network in the vpc. Example: tierNetworkOfferings[0].networkId=networkId1&tierNetworkOfferings[0].networkOfferingId=newNetworkofferingId1&tierNetworkOfferings[1].networkId=networkId2&tierNetworkOfferings[1].networkOfferingId=newNetworkofferingId2")
private Map<Integer, HashMap<String, String>> tierNetworkOfferings;
@Parameter(name = ApiConstants.RESUME, type = CommandType.BOOLEAN, description = "true if previous network migration cmd failed")
private Boolean resume;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public Long getVpcOfferingId() {
return vpcOfferingId;
}
public Boolean getResume() {
return resume == null ? false : resume;
}
public Map<String, String> getTierNetworkOfferings() {
HashMap<String, String> flatMap = new HashMap<>();
if (tierNetworkOfferings == null) {
return flatMap;
}
for (HashMap<String, String> map : tierNetworkOfferings.values()) {
flatMap.put(map.get("networkid"), map.get("networkofferingid"));
}
return flatMap;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public void execute() {
User callerUser = _accountService.getActiveUser(CallContext.current().getCallingUserId());
Account callerAccount = _accountService.getActiveAccountById(callerUser.getAccountId());
Vpc result =
_networkService.migrateVpcNetwork(getId(), getVpcOfferingId(), getTierNetworkOfferings(), callerAccount, callerUser, getResume());
if (result != null) {
VpcResponse response = _responseGenerator.createVpcResponse(ResponseObject.ResponseView.Restricted, result);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate vpc");
}
}
@Override
public String getEventDescription() { return "Migrating vpc: " + getId() + " to new vpc offering (" + vpcOfferingId + ")"; }
@Override
public String getEventType() {
return EventTypes.EVENT_NETWORK_MIGRATE;
}
@Override
public String getSyncObjType() {
return BaseAsyncCmd.networkSyncObject;
}
@Override
public Long getSyncObjId() {
return id;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
}

View File

@ -69,6 +69,9 @@ public class UpdateNetworkOfferingCmd extends BaseCmd {
description = "maximum number of concurrent connections supported by the network offering")
private Integer maxConnections;
@Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "the tags for the network offering.", length = 4096)
private String tags;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -105,6 +108,10 @@ public class UpdateNetworkOfferingCmd extends BaseCmd {
return keepAliveEnabled;
}
public String getTags() {
return tags;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -0,0 +1,29 @@
//
// 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.agent.api;
public class ReplugNicAnswer extends Answer {
public ReplugNicAnswer() {
}
public ReplugNicAnswer(ReplugNicCommand cmd, boolean success, String result) {
super(cmd, success, result);
}
}

View File

@ -0,0 +1,70 @@
//
// 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.agent.api;
import java.util.Map;
import com.cloud.agent.api.to.NicTO;
import com.cloud.vm.VirtualMachine;
public class ReplugNicCommand extends Command {
NicTO nic;
String instanceName;
VirtualMachine.Type vmType;
Map<String, String> details;
public NicTO getNic() {
return nic;
}
@Override
public boolean executeInSequence() {
return true;
}
protected ReplugNicCommand() {
}
public ReplugNicCommand(NicTO nic, String instanceName, VirtualMachine.Type vmtype) {
this.nic = nic;
this.instanceName = instanceName;
this.vmType = vmtype;
}
public ReplugNicCommand(NicTO nic, String instanceName, VirtualMachine.Type vmtype, Map<String, String> details) {
this.nic = nic;
this.instanceName = instanceName;
this.vmType = vmtype;
this.details = details;
}
public String getVmName() {
return instanceName;
}
public VirtualMachine.Type getVMType() {
return vmType;
}
public Map<String, String> getDetails() {
return this.details;
}
}

View File

@ -193,6 +193,9 @@ public interface VirtualMachineManager extends Manager {
*/
VirtualMachineTO toVmTO(VirtualMachineProfile profile);
boolean replugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException,
ResourceUnavailableException, InsufficientCapacityException;
VirtualMachine reConfigureVm(String vmUuid, ServiceOffering newServiceOffering, boolean sameHost) throws ResourceUnavailableException, ConcurrentOperationException,
InsufficientServerCapacityException;

View File

@ -129,6 +129,11 @@ public interface NetworkOrchestrationService {
Map<Integer, String> getExtraDhcpOptions(long nicId);
/**
* Returns all extra dhcp options which are set on the provided nic
* @param nicId
* @return map which maps the dhcp value on it's option code
*/
/**
* prepares vm nic change for migration
*
@ -275,4 +280,6 @@ public interface NetworkOrchestrationService {
int getResourceCount(Network network);
void finalizeUpdateInSequence(Network network, boolean success);
List<NetworkGuru> getNetworkGurus();
}

View File

@ -38,8 +38,8 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
import com.cloud.agent.api.AttachOrDettachConfigDriveCommand;
import org.apache.log4j.Logger;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.ca.CAManager;
import org.apache.cloudstack.context.CallContext;
@ -59,6 +59,7 @@ import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.framework.jobs.Outcome;
import org.apache.cloudstack.framework.jobs.dao.VmWorkJobDao;
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO;
import org.apache.cloudstack.framework.messagebus.MessageBus;
@ -70,13 +71,13 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.Listener;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.AgentControlCommand;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachOrDettachConfigDriveCommand;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.ClusterVMMetaDataSyncAnswer;
@ -89,6 +90,8 @@ import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.ReplugNicAnswer;
import com.cloud.agent.api.ReplugNicCommand;
import com.cloud.agent.api.RestoreVMSnapshotAnswer;
import com.cloud.agent.api.RestoreVMSnapshotCommand;
import com.cloud.agent.api.ScaleVmCommand;
@ -3635,6 +3638,36 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
@Override
public boolean replugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
ResourceUnavailableException, InsufficientCapacityException {
boolean result = true;
final VMInstanceVO router = _vmDao.findById(vm.getId());
if (router.getState() == State.Running) {
try {
final ReplugNicCommand replugNicCmd = new ReplugNicCommand(nic, vm.getName(), vm.getType(), vm.getDetails());
final Commands cmds = new Commands(Command.OnError.Stop);
cmds.addCommand("replugnic", replugNicCmd);
_agentMgr.send(dest.getHost().getId(), cmds);
final ReplugNicAnswer replugNicAnswer = cmds.getAnswer(ReplugNicAnswer.class);
if (replugNicAnswer == null || !replugNicAnswer.getResult()) {
s_logger.warn("Unable to replug nic for vm " + vm.getName());
result = false;
}
} catch (final OperationTimedoutException e) {
throw new AgentUnavailableException("Unable to plug nic for router " + vm.getName() + " in network " + network, dest.getHost().getId(), e);
}
} else {
s_logger.warn("Unable to apply ReplugNic, vm " + router + " is not in the right state " + router.getState());
throw new ResourceUnavailableException("Unable to apply ReplugNic on the backend," + " vm " + vm + " is not in the right state", DataCenter.class,
router.getDataCenterId());
}
return result;
}
public boolean plugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
ResourceUnavailableException, InsufficientCapacityException {
boolean result = true;
@ -3647,7 +3680,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
cmds.addCommand("plugnic", plugNicCmd);
_agentMgr.send(dest.getHost().getId(), cmds);
final PlugNicAnswer plugNicAnswer = cmds.getAnswer(PlugNicAnswer.class);
if (!(plugNicAnswer != null && plugNicAnswer.getResult())) {
if (plugNicAnswer == null || !plugNicAnswer.getResult()) {
s_logger.warn("Unable to plug nic for vm " + vm.getName());
result = false;
}
@ -3683,7 +3716,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
_agentMgr.send(dest.getHost().getId(), cmds);
final UnPlugNicAnswer unplugNicAnswer = cmds.getAnswer(UnPlugNicAnswer.class);
if (!(unplugNicAnswer != null && unplugNicAnswer.getResult())) {
if (unplugNicAnswer == null || !unplugNicAnswer.getResult()) {
s_logger.warn("Unable to unplug nic from router " + router);
result = false;
}

View File

@ -292,7 +292,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
List<NetworkGuru> networkGurus;
@Override
public List<NetworkGuru> getNetworkGurus() {
return networkGurus;
}
@ -1156,7 +1156,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Asking " + element.getName() + " to implemenet " + network);
s_logger.debug("Asking " + element.getName() + " to implement " + network);
}
if (!element.implement(network, offering, dest, context)) {
@ -2644,7 +2644,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
public void doInTransactionWithoutResult(final TransactionStatus status) {
final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, networkFinal.getGuruName());
guru.trash(networkFinal, _networkOfferingDao.findById(networkFinal.getNetworkOfferingId()));
if (!guru.trash(networkFinal, _networkOfferingDao.findById(networkFinal.getNetworkOfferingId()))) {
throw new CloudRuntimeException("Failed to trash network.");
}
if (!deleteVlansInNetwork(networkFinal.getId(), context.getCaller().getId(), callerAccount)) {
s_logger.warn("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges");

View File

@ -318,6 +318,10 @@ public class NetworkVO implements Network {
return related;
}
public void setRelated(long related) {
this.related = related;
}
@Override
public long getId() {
return id;

View File

@ -68,6 +68,10 @@ public class RouterNetworkVO implements InternalIdentity {
return guestType;
}
public void setNetworkId(long networkId) {
this.networkId = networkId;
}
@Override
public long getId() {
return id;

View File

@ -93,6 +93,10 @@ public class NetworkACLVO implements NetworkACL {
this.display = display;
}
public void setVpcId(long vpcId) {
this.vpcId = vpcId;
}
@Override
public boolean isDisplay() {
return display;

View File

@ -220,4 +220,8 @@ public class VpcGatewayVO implements VpcGateway {
public Class<?> getEntityType() {
return VpcGateway.class;
}
public void setVpcId(Long vpcId) {
this.vpcId = vpcId;
}
}

View File

@ -16,8 +16,14 @@
// under the License.
package com.cloud.network.vpc.dao;
import java.util.List;
import com.cloud.network.vpc.NetworkACLVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDao;
public interface NetworkACLDao extends GenericDao<NetworkACLVO, Long> {
@DB
List<NetworkACLVO> listByVpcId(long vpcId);
}

View File

@ -19,15 +19,29 @@ package com.cloud.network.vpc.dao;
import org.springframework.stereotype.Component;
import java.util.List;
import com.cloud.network.vpc.NetworkACLVO;
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
@DB()
public class NetworkACLDaoImpl extends GenericDaoBase<NetworkACLVO, Long> implements NetworkACLDao {
protected final SearchBuilder<NetworkACLVO> AllFieldsSearch;
protected NetworkACLDaoImpl() {
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), SearchCriteria.Op.EQ);
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), SearchCriteria.Op.EQ);
AllFieldsSearch.done();
}
@Override public List<NetworkACLVO> listByVpcId(long vpcId) {
SearchCriteria<NetworkACLVO> sc = AllFieldsSearch.create();
sc.setParameters("vpcId", vpcId);
return listBy(sc);
}
}

View File

@ -30,4 +30,6 @@ public interface VpcGatewayDao extends GenericDao<VpcGatewayVO, Long> {
List<VpcGatewayVO> listByVpcIdAndType(long vpcId, VpcGateway.Type type);
List<VpcGatewayVO> listByAclIdAndType(long aclId, VpcGateway.Type type);
List<VpcGatewayVO> listByVpcId(long vpcId);
}

View File

@ -82,4 +82,11 @@ public class VpcGatewayDaoImpl extends GenericDaoBase<VpcGatewayVO, Long> implem
sc.setParameters("type", type);
return listBy(sc);
}
@Override
public List<VpcGatewayVO> listByVpcId(long vpcId) {
SearchCriteria<VpcGatewayVO> sc = AllFieldsSearch.create();
sc.setParameters("vpcId", vpcId);
return listBy(sc);
}
}

View File

@ -97,7 +97,6 @@ public class VpcOfferingServiceMapDaoImpl extends GenericDaoBase<VpcOfferingServ
@Override
public List<String> listServicesForVpcOffering(long offId) {
SearchCriteria<String> sc = ServicesSearch.create();
;
sc.setParameters("offeringId", offId);
return customSearch(sc, null);
}

View File

@ -25,21 +25,20 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Detail;
import org.apache.cloudstack.api.ResourceDetail;
@Entity
@Table(name = "network_offering_details")
public class NetworkOfferingDetailsVO implements InternalIdentity {
public class NetworkOfferingDetailsVO implements ResourceDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "network_offering_id")
private long offeringId;
private long resourceId;
@Enumerated(value = EnumType.STRING)
@Column(name = "name")
@ -51,8 +50,8 @@ public class NetworkOfferingDetailsVO implements InternalIdentity {
public NetworkOfferingDetailsVO() {
}
public NetworkOfferingDetailsVO(long offeringId, Detail detailName, String value) {
this.offeringId = offeringId;
public NetworkOfferingDetailsVO(long resourceId, Detail detailName, String value) {
this.resourceId = resourceId;
this.name = detailName;
this.value = value;
}
@ -62,11 +61,20 @@ public class NetworkOfferingDetailsVO implements InternalIdentity {
return id;
}
public long getOfferingId() {
return offeringId;
@Override
public long getResourceId() {
return resourceId;
}
public NetworkOffering.Detail getName() {
public void setResourceId(long resourceId) {
this.resourceId = resourceId;
}
public String getName() {
return name.name();
}
public NetworkOffering.Detail getDetailName() {
return name;
}
@ -74,12 +82,13 @@ public class NetworkOfferingDetailsVO implements InternalIdentity {
return value;
}
public void setId(long id) {
this.id = id;
@Override
public boolean isDisplay() {
return false;
}
public void setOfferingId(long offeringId) {
this.offeringId = offeringId;
public void setId(long id) {
this.id = id;
}
public void setName(NetworkOffering.Detail name) {

View File

@ -223,6 +223,10 @@ public class NetworkOfferingVO implements NetworkOffering {
return tags;
}
public void setTags(String tags) {
this.tags = tags;
}
public void setName(String name) {
this.name = name;
}

View File

@ -21,9 +21,9 @@ import java.util.Map;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Detail;
import com.cloud.offerings.NetworkOfferingDetailsVO;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
public interface NetworkOfferingDetailsDao extends GenericDao<NetworkOfferingDetailsVO, Long> {
public interface NetworkOfferingDetailsDao extends ResourceDetailsDao<NetworkOfferingDetailsVO> {
Map<NetworkOffering.Detail, String> getNtwkOffDetails(long offeringId);

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.offerings.dao;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -23,27 +25,27 @@ import java.util.Map;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Detail;
import com.cloud.offerings.NetworkOfferingDetailsVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
public class NetworkOfferingDetailsDaoImpl extends GenericDaoBase<NetworkOfferingDetailsVO, Long> implements NetworkOfferingDetailsDao {
public class NetworkOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<NetworkOfferingDetailsVO> implements NetworkOfferingDetailsDao {
protected final SearchBuilder<NetworkOfferingDetailsVO> DetailSearch;
private final GenericSearchBuilder<NetworkOfferingDetailsVO, String> ValueSearch;
public NetworkOfferingDetailsDaoImpl() {
DetailSearch = createSearchBuilder();
DetailSearch.and("offeringId", DetailSearch.entity().getOfferingId(), SearchCriteria.Op.EQ);
DetailSearch.and("resourceId", DetailSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
DetailSearch.and("value", DetailSearch.entity().getValue(), SearchCriteria.Op.EQ);
DetailSearch.done();
ValueSearch = createSearchBuilder(String.class);
ValueSearch.select(null, Func.DISTINCT, ValueSearch.entity().getValue());
ValueSearch.and("offeringId", ValueSearch.entity().getOfferingId(), SearchCriteria.Op.EQ);
ValueSearch.and("resourceId", ValueSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
ValueSearch.and("name", ValueSearch.entity().getName(), Op.EQ);
ValueSearch.done();
}
@ -51,12 +53,12 @@ public class NetworkOfferingDetailsDaoImpl extends GenericDaoBase<NetworkOfferin
@Override
public Map<NetworkOffering.Detail, String> getNtwkOffDetails(long offeringId) {
SearchCriteria<NetworkOfferingDetailsVO> sc = DetailSearch.create();
sc.setParameters("offeringId", offeringId);
sc.setParameters("resourceId", offeringId);
List<NetworkOfferingDetailsVO> results = search(sc, null);
Map<NetworkOffering.Detail, String> details = new HashMap<NetworkOffering.Detail, String>(results.size());
for (NetworkOfferingDetailsVO result : results) {
details.put(result.getName(), result.getValue());
details.put(result.getDetailName(), result.getValue());
}
return details;
@ -66,7 +68,7 @@ public class NetworkOfferingDetailsDaoImpl extends GenericDaoBase<NetworkOfferin
public String getDetail(long offeringId, Detail detailName) {
SearchCriteria<String> sc = ValueSearch.create();
sc.setParameters("name", detailName);
sc.setParameters("offeringId", offeringId);
sc.setParameters("resourceId", offeringId);
List<String> results = customSearch(sc, null);
if (results.isEmpty()) {
return null;
@ -75,4 +77,7 @@ public class NetworkOfferingDetailsDaoImpl extends GenericDaoBase<NetworkOfferin
}
}
@Override public void addDetail(long resourceId, String key, String value, boolean display) {
persist(new NetworkOfferingDetailsVO(resourceId, Detail.valueOf(key), value));
}
}

View File

@ -29,15 +29,35 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
public interface ResourceTagDao extends GenericDao<ResourceTagVO, Long> {
/**
* @param resourceId
* @param resourceType
* @return
* Remove a resourceTag based on the resourceId and type
* @param resourceId the id of the resource you want to remove
* @param resourceType the resource type
* @return true if successful
*/
boolean removeByIdAndType(long resourceId, ResourceObjectType resourceType);
List<? extends ResourceTag> listBy(long resourceId, ResourceObjectType resourceType);
/**
* Find a resource tag based on the resource id, resource type and key
* @param resourceId the id of the resource you want to find
* @param resourceType the resource type (e.g. VPC)
* @param key the key value
* @return the ResourceTag matching the search criteria
*/
ResourceTag findByKey(long resourceId, ResourceObjectType resourceType, String key);
void updateResourceId(long srcId, long destId, ResourceObjectType resourceType);
Map<String, Set<ResourceTagResponse>> listTags();
/**
* remove a resource tag based on the resource id, resource type and key
* @param resourceId the id of the resource you want to remove
* @param resourceType the resource type (e.g. VPC)
* @param key the key value
*/
void removeByResourceIdAndKey(long resourceId, ResourceObjectType resourceType, String key);
List<? extends ResourceTag> listByResourceUuid(String resourceUuid);
}

View File

@ -42,6 +42,8 @@ public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> imp
AllFieldsSearch.and("resourceId", AllFieldsSearch.entity().getResourceId(), Op.EQ);
AllFieldsSearch.and("uuid", AllFieldsSearch.entity().getResourceUuid(), Op.EQ);
AllFieldsSearch.and("resourceType", AllFieldsSearch.entity().getResourceType(), Op.EQ);
AllFieldsSearch.and("key", AllFieldsSearch.entity().getKey(), Op.EQ);
AllFieldsSearch.and("resourceUuid", AllFieldsSearch.entity().getResourceUuid(), Op.EQ);
AllFieldsSearch.done();
}
@ -62,6 +64,15 @@ public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> imp
return listBy(sc);
}
@Override
public ResourceTag findByKey(long resourceId, ResourceObjectType resourceType, String key) {
SearchCriteria<ResourceTagVO> sc = AllFieldsSearch.create();
sc.setParameters("resourceId", resourceId);
sc.setParameters("resourceType", resourceType);
sc.setParameters("key", key);
return findOneBy(sc);
}
@Override public void updateResourceId(long srcId, long destId, ResourceObjectType resourceType) {
SearchCriteria<ResourceTagVO> sc = AllFieldsSearch.create();
sc.setParameters("resourceId", srcId);
@ -93,4 +104,20 @@ public class ResourceTagsDaoImpl extends GenericDaoBase<ResourceTagVO, Long> imp
}
return resourceTagMap;
}
@Override
public void removeByResourceIdAndKey(long resourceId, ResourceObjectType resourceType, String key) {
SearchCriteria<ResourceTagVO> sc = AllFieldsSearch.create();
sc.setParameters("resourceId", resourceId);
sc.setParameters("resourceType", resourceType);
sc.setParameters("key", key);
remove(sc);
}
@Override
public List<? extends ResourceTag> listByResourceUuid(String resourceUuid) {
SearchCriteria<ResourceTagVO> sc = AllFieldsSearch.create();
sc.setParameters("resourceUuid", resourceUuid);
return listBy(sc);
}
}

View File

@ -58,4 +58,5 @@ public interface NicIpAliasDao extends GenericDao<NicIpAliasVO, Long> {
List<NicIpAliasVO> listByNetworkIdAndState(long networkId, NicIpAlias.State state);
int moveIpAliases(long fromNicId, long toNicId);
}

View File

@ -172,4 +172,14 @@ public class NicIpAliasDaoImpl extends GenericDaoBase<NicIpAliasVO, Long> implem
List<NicIpAliasVO> list = listBy(sc);
return list.size();
}
@Override
public int moveIpAliases(long fromNicId, long toNicId) {
SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
sc.setParameters("nicId", fromNicId);
NicIpAliasVO update = createForUpdate();
update.setNicId(toNicId);
return update(update, sc);
}
}

View File

@ -57,4 +57,6 @@ public interface NicSecondaryIpDao extends GenericDao<NicSecondaryIpVO, Long> {
Long countByNicId(long nicId);
List<NicSecondaryIpVO> listSecondaryIpUsingKeyword(long nicId, String keyword);
int moveSecondaryIps(long fromNicId, long toNicId);
}

View File

@ -172,4 +172,15 @@ public class NicSecondaryIpDaoImpl extends GenericDaoBase<NicSecondaryIpVO, Long
sc.setParameters("address", "%" + keyword + "%");
return listBy(sc);
}
@Override
public int moveSecondaryIps(long fromNicId, long toNicId) {
NicSecondaryIpVO update = createForUpdate();
update.setNicId(toNicId);
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
sc.setParameters("nicId", fromNicId);
return update(update, sc);
}
}

View File

@ -97,6 +97,11 @@ public class NicSecondaryIpVO implements NicSecondaryIp {
return nicId;
}
@Override
public void setNicId(long nicId) {
this.nicId = nicId;
}
@Override
public long getDomainId() {
return domainId;

View File

@ -20,16 +20,19 @@
package com.cloud.hypervisor.kvm.resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.naming.ConfigurationException;
import com.google.common.base.Strings;
import org.apache.log4j.Logger;
import org.libvirt.LibvirtException;
import com.google.common.base.Strings;
import com.cloud.agent.api.to.NicTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.network.Networks;
@ -54,6 +57,8 @@ public class BridgeVifDriver extends VifDriverBase {
super.configure(params);
getPifs();
// Set the domr scripts directory
params.put("domr.scripts.dir", "scripts/network/domr/kvm");
@ -80,12 +85,125 @@ public class BridgeVifDriver extends VifDriverBase {
if (libvirtVersion == null) {
libvirtVersion = 0L;
}
}
try {
createControlNetwork();
} catch (LibvirtException e) {
throw new ConfigurationException(e.getMessage());
public void getPifs() {
final File dir = new File("/sys/devices/virtual/net");
final File[] netdevs = dir.listFiles();
final List<String> bridges = new ArrayList<String>();
for (File netdev : netdevs) {
final File isbridge = new File(netdev.getAbsolutePath() + "/bridge");
final String netdevName = netdev.getName();
s_logger.debug("looking in file " + netdev.getAbsolutePath() + "/bridge");
if (isbridge.exists()) {
s_logger.debug("Found bridge " + netdevName);
bridges.add(netdevName);
}
}
String guestBridgeName = _libvirtComputingResource.getGuestBridgeName();
String publicBridgeName = _libvirtComputingResource.getPublicBridgeName();
for (final String bridge : bridges) {
s_logger.debug("looking for pif for bridge " + bridge);
final String pif = getPif(bridge);
if (_libvirtComputingResource.isPublicBridge(bridge)) {
_pifs.put("public", pif);
}
if (guestBridgeName != null && bridge.equals(guestBridgeName)) {
_pifs.put("private", pif);
}
_pifs.put(bridge, pif);
}
// guest(private) creates bridges on a pif, if private bridge not found try pif direct
// This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
if (_pifs.get("private") == null) {
s_logger.debug("guest(private) traffic label '" + guestBridgeName + "' not found as bridge, looking for physical interface");
final File dev = new File("/sys/class/net/" + guestBridgeName);
if (dev.exists()) {
s_logger.debug("guest(private) traffic label '" + guestBridgeName + "' found as a physical device");
_pifs.put("private", guestBridgeName);
}
}
// public creates bridges on a pif, if private bridge not found try pif direct
// This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
if (_pifs.get("public") == null) {
s_logger.debug("public traffic label '" + publicBridgeName+ "' not found as bridge, looking for physical interface");
final File dev = new File("/sys/class/net/" + publicBridgeName);
if (dev.exists()) {
s_logger.debug("public traffic label '" + publicBridgeName + "' found as a physical device");
_pifs.put("public", publicBridgeName);
}
}
s_logger.debug("done looking for pifs, no more bridges");
}
private String getPif(final String bridge) {
String pif = matchPifFileInDirectory(bridge);
final File vlanfile = new File("/proc/net/vlan/" + pif);
if (vlanfile.isFile()) {
pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}");
}
return pif;
}
private String matchPifFileInDirectory(final String bridgeName) {
final File brif = new File("/sys/devices/virtual/net/" + bridgeName + "/brif");
if (!brif.isDirectory()) {
final File pif = new File("/sys/class/net/" + bridgeName);
if (pif.isDirectory()) {
// if bridgeName already refers to a pif, return it as-is
return bridgeName;
}
s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", does " + brif.getAbsolutePath() + "exist?");
return "";
}
final File[] interfaces = brif.listFiles();
for (File anInterface : interfaces) {
final String fname = anInterface.getName();
s_logger.debug("matchPifFileInDirectory: file name '" + fname + "'");
if (isInterface(fname)) {
return fname;
}
}
s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", did not find an eth*, bond*, team*, vlan*, em*, p*p*, ens*, eno*, enp*, or enx* in " + brif.getAbsolutePath());
return "";
}
private static final String [] IF_NAME_PATTERNS = {
"^eth",
"^bond",
"^vlan",
"^vx",
"^em",
"^ens",
"^eno",
"^enp",
"^team",
"^enx",
"^p\\d+p\\d+"
};
/**
* @param fname
* @return
*/
private static boolean isInterface(final String fname) {
StringBuilder commonPattern = new StringBuilder();
for (final String ifNamePattern : IF_NAME_PATTERNS) {
commonPattern.append("|(").append(ifNamePattern).append(".*)");
}
return fname.matches(commonPattern.toString());
}
@Override
@ -161,6 +279,7 @@ public class BridgeVifDriver extends VifDriverBase {
if (nic.getPxeDisable() == true) {
intf.setPxeDisable(true);
}
return intf;
}
@ -169,6 +288,16 @@ public class BridgeVifDriver extends VifDriverBase {
deleteVnetBr(iface.getBrName());
}
@Override
public void attach(LibvirtVMDef.InterfaceDef iface) {
Script.runSimpleBashScript("brctl addif " + iface.getBrName() + " " + iface.getDevName());
}
@Override
public void detach(LibvirtVMDef.InterfaceDef iface) {
Script.runSimpleBashScript("test -d /sys/class/net/" + iface.getBrName() + "/brif/" + iface.getDevName() + " && brctl delif " + iface.getBrName() + " " + iface.getDevName());
}
private String setVnetBrName(String pifName, String vnetId) {
return "br" + pifName + "-" + vnetId;
}
@ -272,10 +401,6 @@ public class BridgeVifDriver extends VifDriverBase {
}
}
private void createControlNetwork() throws LibvirtException {
createControlNetwork(_bridges.get("linklocal"));
}
private void deleteExistingLinkLocalRouteTable(String linkLocalBr) {
Script command = new Script("/bin/bash", _timeout);
command.add("-c");
@ -304,16 +429,21 @@ public class BridgeVifDriver extends VifDriverBase {
}
}
private void createControlNetwork(String privBrName) {
deleteExistingLinkLocalRouteTable(privBrName);
if (!isBridgeExists(privBrName)) {
Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
}
private void createControlNetwork() {
createControlNetwork(_bridges.get("linklocal"));
}
private boolean isBridgeExists(String bridgeName) {
File f = new File("/sys/devices/virtual/net/" + bridgeName);
@Override
public void createControlNetwork(String privBrName) {
deleteExistingLinkLocalRouteTable(privBrName);
if (!isExistingBridge(privBrName)) {
Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
}
}
@Override
public boolean isExistingBridge(String bridgeName) {
File f = new File("/sys/devices/virtual/net/" + bridgeName + "/bridge");
if (f.exists()) {
return true;
} else {

View File

@ -63,4 +63,18 @@ public class DirectVifDriver extends VifDriverBase {
// not needed, libvirt will cleanup
}
@Override
public void attach(LibvirtVMDef.InterfaceDef iface) {
}
@Override
public void detach(LibvirtVMDef.InterfaceDef iface) {
}
@Override
public void createControlNetwork(String privBrName) {
}
}

View File

@ -74,8 +74,6 @@ public class IvsVifDriver extends VifDriverBase {
if (libvirtVersion == null) {
libvirtVersion = 0L;
}
createControlNetwork(_bridges.get("linklocal"));
}
@Override
@ -145,6 +143,17 @@ public class IvsVifDriver extends VifDriverBase {
public void unplug(InterfaceDef iface) {
}
@Override
public void attach(LibvirtVMDef.InterfaceDef iface) {
Script.runSimpleBashScript("/usr/sbin/ivs-ctl add-port " + iface.getDevName());
}
@Override
public void detach(LibvirtVMDef.InterfaceDef iface) {
Script.runSimpleBashScript("/usr/sbin/ivs-ctl del-port " + iface.getDevName());
}
private void createControlNetwork() throws LibvirtException {
createControlNetwork(_bridges.get("linklocal"));
}
@ -268,7 +277,8 @@ public class IvsVifDriver extends VifDriverBase {
}
}
private void createControlNetwork(String privBrName) {
@Override
public void createControlNetwork(String privBrName) {
deleteExitingLinkLocalRouteTable(privBrName);
if (!isBridgeExists(privBrName)) {
Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);

View File

@ -47,12 +47,6 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.cloudstack.utils.hypervisor.HypervisorUtils;
import org.apache.cloudstack.utils.linux.CPUStat;
import org.apache.cloudstack.utils.linux.MemStat;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
@ -76,6 +70,15 @@ import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.google.common.base.Strings;
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
import org.apache.cloudstack.storage.to.VolumeObjectTO;
import org.apache.cloudstack.utils.hypervisor.HypervisorUtils;
import org.apache.cloudstack.utils.linux.CPUStat;
import org.apache.cloudstack.utils.linux.MemStat;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.HostVmStateReportEntry;
@ -167,7 +170,6 @@ import com.cloud.utils.ssh.SshHelper;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.PowerState;
import com.cloud.vm.VmDetailConstants;
import com.google.common.base.Strings;
/**
* LibvirtComputingResource execute requests on the computing/routing host using
@ -968,6 +970,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
final Map<String, String> bridges = new HashMap<String, String>();
params.put("libvirt.host.bridges", bridges);
params.put("libvirt.host.pifs", _pifs);
params.put("libvirt.computing.resource", this);
params.put("libvirtVersion", _hypervisorLibvirtVersion);
configureVifDrivers(params);
/*
switch (_bridgeType) {
case OPENVSWITCH:
getOvsPifs();
@ -977,6 +991,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
getPifs();
break;
}
*/
if (_pifs.get("private") == null) {
s_logger.debug("Failed to get private nic name");
@ -1027,19 +1042,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
params.put("vm.migrate.speed", String.valueOf(_migrateSpeed));
}
final Map<String, String> bridges = new HashMap<String, String>();
bridges.put("linklocal", _linkLocalBridgeName);
bridges.put("public", _publicBridgeName);
bridges.put("private", _privBridgeName);
bridges.put("guest", _guestBridgeName);
params.put("libvirt.host.bridges", bridges);
params.put("libvirt.host.pifs", _pifs);
getVifDriver(TrafficType.Control).createControlNetwork(_linkLocalBridgeName);
params.put("libvirt.computing.resource", this);
params.put("libvirtVersion", _hypervisorLibvirtVersion);
configureVifDrivers(params);
configureDiskActivityChecks(params);
final KVMStorageProcessor storageProcessor = new KVMStorageProcessor(_storagePoolMgr, this);
@ -1132,6 +1141,23 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return vifDriver;
}
public VifDriver getVifDriver(final TrafficType trafficType, final String bridgeName) {
VifDriver vifDriver = null;
for (VifDriver driver : getAllVifDrivers()) {
if (driver.isExistingBridge(bridgeName)) {
vifDriver = driver;
break;
}
}
if (vifDriver == null) {
vifDriver = getVifDriver(trafficType);
}
return vifDriver;
}
public List<VifDriver> getAllVifDrivers() {
final Set<VifDriver> vifDrivers = new HashSet<VifDriver>();
@ -1160,10 +1186,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
for (final String bridge : bridges) {
s_logger.debug("looking for pif for bridge " + bridge);
final String pif = getPif(bridge);
if (_publicBridgeName != null && bridge.equals(_publicBridgeName)) {
if (isPublicBridge(bridge)) {
_pifs.put("public", pif);
}
if (_guestBridgeName != null && bridge.equals(_guestBridgeName)) {
if (isGuestBridge(bridge)) {
_pifs.put("private", pif);
}
_pifs.put(bridge, pif);
@ -1194,6 +1220,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
s_logger.debug("done looking for pifs, no more bridges");
}
boolean isGuestBridge(String bridge) {
return _guestBridgeName != null && bridge.equals(_guestBridgeName);
}
private void getOvsPifs() {
final String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'");
s_logger.debug("cmdout was " + cmdout);
@ -1204,10 +1234,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
// Not really interested in the pif name at this point for ovs
// bridges
final String pif = bridge;
if (_publicBridgeName != null && bridge.equals(_publicBridgeName)) {
if (isPublicBridge(bridge)) {
_pifs.put("public", pif);
}
if (_guestBridgeName != null && bridge.equals(_guestBridgeName)) {
if (isGuestBridge(bridge)) {
_pifs.put("private", pif);
}
_pifs.put(bridge, pif);
@ -1215,6 +1245,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
s_logger.debug("done looking for pifs, no more bridges");
}
public boolean isPublicBridge(String bridge) {
return _publicBridgeName != null && bridge.equals(_publicBridgeName);
}
private String getPif(final String bridge) {
String pif = matchPifFileInDirectory(bridge);
final File vlanfile = new File("/proc/net/vlan/" + pif);
@ -1281,12 +1315,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return false;
}
public boolean checkNetwork(final String networkName) {
public boolean checkNetwork(final TrafficType trafficType, final String networkName) {
if (networkName == null) {
return true;
}
if (_bridgeType == BridgeType.OPENVSWITCH) {
if (getVifDriver(trafficType, networkName) instanceof OvsVifDriver) {
return checkOvsNetwork(networkName);
} else {
return checkBridgeNetwork(networkName);
@ -1421,7 +1455,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
public synchronized boolean findOrCreateTunnelNetwork(final String nwName) {
try {
if (checkNetwork(nwName)) {
if (checkNetwork(TrafficType.Guest, nwName)) {
return true;
}
// if not found, create a new one
@ -2324,7 +2358,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
vm.getDevices().addDevice(getVifDriver(nic.getType()).plug(nic, vm.getPlatformEmulator().toString(), nicAdapter).toString());
vm.getDevices().addDevice(getVifDriver(nic.getType(), nic.getName()).plug(nic, vm.getPlatformEmulator(), nicAdapter));
}
public boolean cleanupDisk(final DiskDef disk) {

View File

@ -27,7 +27,7 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@ -36,7 +36,8 @@ import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.cloud.utils.StringUtils;
import com.google.common.base.Strings;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
@ -161,6 +162,8 @@ public class LibvirtDomainXMLParser {
String mac = getAttrValue("mac", "address", nic);
String dev = getAttrValue("target", "dev", nic);
String model = getAttrValue("model", "type", nic);
String slot = StringUtils.removeStart(getAttrValue("address", "slot", nic), "0x");
InterfaceDef def = new InterfaceDef();
NodeList bandwidth = nic.getElementsByTagName("bandwidth");
Integer networkRateKBps = 0;
@ -181,6 +184,11 @@ public class LibvirtDomainXMLParser {
String scriptPath = getAttrValue("script", "path", nic);
def.defEthernet(dev, mac, NicModel.valueOf(model.toUpperCase()), scriptPath, networkRateKBps);
}
if (StringUtils.isNotBlank(slot)) {
def.setSlot(Integer.parseInt(slot, 16));
}
interfaces.add(def);
}

View File

@ -16,16 +16,17 @@
// under the License.
package com.cloud.hypervisor.kvm.resource;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import com.google.common.collect.Maps;
public class LibvirtVMDef {
private static final Logger s_logger = Logger.getLogger(LibvirtVMDef.class);
@ -890,7 +891,7 @@ public class LibvirtVMDef {
}
}
enum NicModel {
public enum NicModel {
E1000("e1000"), VIRTIO("virtio"), RTL8139("rtl8139"), NE2KPCI("ne2k_pci"), VMXNET3("vmxnet3");
String _model;
@ -925,6 +926,8 @@ public class LibvirtVMDef {
private String _virtualPortInterfaceId;
private int _vlanTag = -1;
private boolean _pxeDisable = false;
private boolean _linkStateUp = true;
private Integer _slot;
public void defBridgeNet(String brName, String targetBrName, String macAddr, NicModel model) {
defBridgeNet(brName, targetBrName, macAddr, model, 0);
@ -1012,6 +1015,10 @@ public class LibvirtVMDef {
return _networkName;
}
public void setDevName(String networkName) {
_networkName = networkName;
}
public String getMacAddress() {
return _macAddr;
}
@ -1044,6 +1051,22 @@ public class LibvirtVMDef {
return _vlanTag;
}
public void setSlot(Integer slot) {
_slot = slot;
}
public Integer getSlot() {
return _slot;
}
public void setLinkStateUp(boolean linkStateUp) {
_linkStateUp = linkStateUp;
}
public boolean isLinkStateUp() {
return _linkStateUp;
}
@Override
public String toString() {
StringBuilder netBuilder = new StringBuilder();
@ -1086,6 +1109,12 @@ public class LibvirtVMDef {
if (_vlanTag > 0 && _vlanTag < 4095) {
netBuilder.append("<vlan trunk='no'>\n<tag id='" + _vlanTag + "'/>\n</vlan>");
}
netBuilder.append("<link state='" + (_linkStateUp ? "up" : "down") +"'/>\n");
if (_slot != null) {
netBuilder.append(String.format("<address type='pci' domain='0x0000' bus='0x00' slot='0x%02x' function='0x0'/>\n", _slot));
}
netBuilder.append("</interface>\n");
return netBuilder.toString();
}

View File

@ -18,6 +18,8 @@
*/
package com.cloud.hypervisor.kvm.resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.naming.ConfigurationException;
@ -42,6 +44,8 @@ public class OvsVifDriver extends VifDriverBase {
public void configure(Map<String, Object> params) throws ConfigurationException {
super.configure(params);
getPifs();
String networkScriptsDir = (String)params.get("network.scripts.dir");
if (networkScriptsDir == null) {
networkScriptsDir = "scripts/vm/network/vnet";
@ -49,8 +53,27 @@ public class OvsVifDriver extends VifDriverBase {
String value = (String)params.get("scripts.timeout");
_timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
}
createControlNetwork(_bridges.get("linklocal"));
public void getPifs() {
final String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'");
s_logger.debug("cmdout was " + cmdout);
final List<String> bridges = Arrays.asList(cmdout.split("%"));
for (final String bridge : bridges) {
s_logger.debug("looking for pif for bridge " + bridge);
// String pif = getOvsPif(bridge);
// Not really interested in the pif name at this point for ovs
// bridges
final String pif = bridge;
if (_libvirtComputingResource.isPublicBridge(bridge)) {
_pifs.put("public", pif);
}
if (_libvirtComputingResource.isGuestBridge(bridge)) {
_pifs.put("private", pif);
}
_pifs.put(bridge, pif);
}
s_logger.debug("done looking for pifs, no more bridges");
}
@Override
@ -132,6 +155,17 @@ public class OvsVifDriver extends VifDriverBase {
// Libvirt apparently takes care of this, see BridgeVifDriver unplug
}
@Override
public void attach(LibvirtVMDef.InterfaceDef iface) {
Script.runSimpleBashScript("ovs-vsctl add-port " + iface.getBrName() + " " + iface.getDevName());
}
@Override
public void detach(LibvirtVMDef.InterfaceDef iface) {
Script.runSimpleBashScript("ovs-vsctl port-to-br " + iface.getDevName() + " && ovs-vsctl del-port " + iface.getBrName() + " " + iface.getDevName());
}
private void deleteExitingLinkLocalRouteTable(String linkLocalBr) {
Script command = new Script("/bin/bash", _timeout);
command.add("-c");
@ -156,14 +190,16 @@ public class OvsVifDriver extends VifDriverBase {
}
}
private void createControlNetwork(String privBrName) {
@Override
public void createControlNetwork(String privBrName) {
deleteExitingLinkLocalRouteTable(privBrName);
if (!isBridgeExists(privBrName)) {
if (!isExistingBridge(privBrName)) {
Script.runSimpleBashScript("ovs-vsctl add-br " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
}
}
private boolean isBridgeExists(String bridgeName) {
@Override
public boolean isExistingBridge(String bridgeName) {
Script command = new Script("/bin/sh", _timeout);
command.add("-c");
command.add("ovs-vsctl br-exists " + bridgeName);

View File

@ -36,4 +36,12 @@ public interface VifDriver {
public void unplug(LibvirtVMDef.InterfaceDef iface);
void attach(LibvirtVMDef.InterfaceDef iface);
void detach(LibvirtVMDef.InterfaceDef iface);
void createControlNetwork(String privBrName);
boolean isExistingBridge(String bridgeName);
}

View File

@ -63,4 +63,8 @@ public abstract class VifDriverBase implements VifDriver {
return LibvirtVMDef.InterfaceDef.NicModel.E1000;
}
}
public boolean isExistingBridge(String bridgeName) {
return false;
}
}

View File

@ -25,6 +25,7 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckNetworkAnswer;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.network.Networks;
import com.cloud.network.PhysicalNetworkSetupInfo;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper;
@ -38,13 +39,13 @@ public final class LibvirtCheckNetworkCommandWrapper extends CommandWrapper<Chec
String errMsg = null;
for (final PhysicalNetworkSetupInfo nic : phyNics) {
if (!libvirtComputingResource.checkNetwork(nic.getGuestNetworkName())) {
if (!libvirtComputingResource.checkNetwork(Networks.TrafficType.Guest, nic.getGuestNetworkName())) {
errMsg = "Can not find network: " + nic.getGuestNetworkName();
break;
} else if (!libvirtComputingResource.checkNetwork(nic.getPrivateNetworkName())) {
} else if (!libvirtComputingResource.checkNetwork(Networks.TrafficType.Management, nic.getPrivateNetworkName())) {
errMsg = "Can not find network: " + nic.getPrivateNetworkName();
break;
} else if (!libvirtComputingResource.checkNetwork(nic.getPublicNetworkName())) {
} else if (!libvirtComputingResource.checkNetwork(Networks.TrafficType.Public, nic.getPublicNetworkName())) {
errMsg = "Can not find network: " + nic.getPublicNetworkName();
break;
}

View File

@ -19,13 +19,6 @@
package com.cloud.hypervisor.kvm.resource.wrapper;
import java.util.List;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.PlugNicAnswer;
import com.cloud.agent.api.PlugNicCommand;
@ -36,6 +29,12 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.VifDriver;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import java.util.List;
@ResourceWrapper(handles = PlugNicCommand.class)
public final class LibvirtPlugNicCommandWrapper extends CommandWrapper<PlugNicCommand, Answer, LibvirtComputingResource> {
@ -61,7 +60,7 @@ public final class LibvirtPlugNicCommandWrapper extends CommandWrapper<PlugNicCo
}
nicnum++;
}
final VifDriver vifDriver = libvirtComputingResource.getVifDriver(nic.getType());
final VifDriver vifDriver = libvirtComputingResource.getVifDriver(nic.getType(), nic.getName());
final InterfaceDef interfaceDef = vifDriver.plug(nic, "Other PV", "");
vm.attachDevice(interfaceDef.toString());

View File

@ -19,12 +19,6 @@
package com.cloud.hypervisor.kvm.resource.wrapper;
import java.net.URISyntaxException;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
@ -37,6 +31,11 @@ import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper;
import com.cloud.storage.Volume;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import java.net.URISyntaxException;
@ResourceWrapper(handles = PrepareForMigrationCommand.class)
public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapper<PrepareForMigrationCommand, Answer, LibvirtComputingResource> {
@ -60,7 +59,7 @@ public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapp
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vm.getName());
for (final NicTO nic : nics) {
libvirtComputingResource.getVifDriver(nic.getType()).plug(nic, null, "");
libvirtComputingResource.getVifDriver(nic.getType(), nic.getName()).plug(nic, null, "");
}
/* setup disks, e.g for iso */

View File

@ -0,0 +1,133 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.hypervisor.kvm.resource.wrapper;
import java.util.List;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ReplugNicAnswer;
import com.cloud.agent.api.ReplugNicCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.VifDriver;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.ResourceWrapper;
@ResourceWrapper(handles = ReplugNicCommand.class)
public final class LibvirtReplugNicCommandWrapper extends CommandWrapper<ReplugNicCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtReplugNicCommandWrapper.class);
public enum DomainAffect {
CURRENT(0), LIVE(1), CONFIG(2), BOTH(3);
private int value;
DomainAffect(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
@Override
public Answer execute(final ReplugNicCommand command, final LibvirtComputingResource libvirtComputingResource) {
final NicTO nic = command.getNic();
final String vmName = command.getVmName();
Domain vm = null;
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
vm = libvirtComputingResource.getDomain(conn, vmName);
InterfaceDef oldPluggedNic = findPluggedNic(libvirtComputingResource, nic, vmName, conn);
final VifDriver newVifDriver = libvirtComputingResource.getVifDriver(nic.getType(), nic.getName());
final InterfaceDef interfaceDef = newVifDriver.plug(nic, "Other PV", oldPluggedNic.getModel().toString());
interfaceDef.setSlot(oldPluggedNic.getSlot());
interfaceDef.setDevName(oldPluggedNic.getDevName());
interfaceDef.setLinkStateUp(false);
oldPluggedNic.setSlot(null);
int i = 0;
do {
i++;
s_logger.debug("ReplugNic: Detaching interface" + oldPluggedNic + " (Attempt: " + i + ")");
vm.detachDevice(oldPluggedNic.toString());
} while (findPluggedNic(libvirtComputingResource, nic, vmName, conn) != null && i <= 10);
s_logger.debug("ReplugNic: Attaching interface" + interfaceDef);
vm.attachDevice(interfaceDef.toString());
interfaceDef.setLinkStateUp(true);
s_logger.debug("ReplugNic: Updating interface" + interfaceDef);
vm.updateDeviceFlags(interfaceDef.toString(), DomainAffect.LIVE.getValue());
/*
// Manual replug
for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) {
vifDriver.detach(oldPluggedNic);
}
newVifDriver.attach(interfaceDef);
*/
// We don't know which "traffic type" is associated with
// each interface at this point, so inform all vif drivers
for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) {
vifDriver.unplug(oldPluggedNic);
}
return new ReplugNicAnswer(command, true, "success");
} catch (final LibvirtException | InternalErrorException e) {
final String msg = " Plug Nic failed due to " + e.toString();
s_logger.warn(msg, e);
return new ReplugNicAnswer(command, false, msg);
} finally {
if (vm != null) {
try {
vm.free();
} catch (final LibvirtException l) {
s_logger.trace("Ignoring libvirt error.", l);
}
}
}
}
private InterfaceDef findPluggedNic(LibvirtComputingResource libvirtComputingResource, NicTO nic, String vmName, Connect conn) {
InterfaceDef oldPluggedNic = null;
final List<InterfaceDef> pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName);
for (final InterfaceDef pluggedNic : pluggedNics) {
if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
oldPluggedNic = pluggedNic;
}
}
return oldPluggedNic;
}
}

View File

@ -19,16 +19,6 @@
package com.cloud.hypervisor.kvm.resource;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
@ -48,11 +38,6 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.cloudstack.storage.command.AttachAnswer;
import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.utils.linux.CPUStat;
import org.apache.cloudstack.utils.linux.MemStat;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import org.apache.commons.lang.SystemUtils;
import org.joda.time.Duration;
import org.junit.Assert;
@ -78,6 +63,12 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.apache.cloudstack.storage.command.AttachAnswer;
import org.apache.cloudstack.storage.command.AttachCommand;
import org.apache.cloudstack.utils.linux.CPUStat;
import org.apache.cloudstack.utils.linux.MemStat;
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.BackupSnapshotCommand;
@ -178,6 +169,16 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.PowerState;
import com.cloud.vm.VirtualMachine.Type;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class LibvirtComputingResourceTest {
@ -1021,7 +1022,7 @@ public class LibvirtComputingResourceTest {
when(nicTO.getType()).thenReturn(TrafficType.Guest);
when(diskTO.getType()).thenReturn(Volume.Type.ISO);
when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver);
when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
@ -1069,7 +1070,7 @@ public class LibvirtComputingResourceTest {
when(nicTO.getType()).thenReturn(TrafficType.Guest);
when(diskTO.getType()).thenReturn(Volume.Type.ISO);
when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver);
when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
when(storagePoolManager.connectPhysicalDisksViaVmSpec(vm)).thenReturn(true);
@ -1161,7 +1162,7 @@ public class LibvirtComputingResourceTest {
when(nicTO.getType()).thenReturn(TrafficType.Guest);
when(volume.getType()).thenReturn(Volume.Type.ISO);
when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver);
when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
try {
when(libvirtComputingResource.getVolumePath(conn, volume)).thenThrow(URISyntaxException.class);
@ -1213,7 +1214,7 @@ public class LibvirtComputingResourceTest {
when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
when(nicTO.getType()).thenReturn(TrafficType.Guest);
when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenThrow(InternalErrorException.class);
when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenThrow(InternalErrorException.class);
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
try {
when(libvirtComputingResource.getVolumePath(conn, volume)).thenReturn("/path");
@ -2550,9 +2551,9 @@ public class LibvirtComputingResourceTest {
final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
when(libvirtComputingResource.checkNetwork(nic.getGuestNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(nic.getPrivateNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(nic.getPublicNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(TrafficType.Guest, nic.getGuestNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(TrafficType.Management, nic.getPrivateNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(TrafficType.Public, nic.getPublicNetworkName())).thenReturn(true);
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
assertNotNull(wrapper);
@ -2560,9 +2561,9 @@ public class LibvirtComputingResourceTest {
final Answer answer = wrapper.execute(command, libvirtComputingResource);
assertTrue(answer.getResult());
verify(libvirtComputingResource, times(3)).checkNetwork(nic.getGuestNetworkName());
verify(libvirtComputingResource, times(3)).checkNetwork(nic.getPrivateNetworkName());
verify(libvirtComputingResource, times(3)).checkNetwork(nic.getPublicNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, nic.getGuestNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, nic.getPrivateNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Public, nic.getPublicNetworkName());
}
@Test
@ -2574,7 +2575,7 @@ public class LibvirtComputingResourceTest {
final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
when(libvirtComputingResource.checkNetwork(networkSetupInfo.getGuestNetworkName())).thenReturn(false);
when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(false);
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
assertNotNull(wrapper);
@ -2582,7 +2583,7 @@ public class LibvirtComputingResourceTest {
final Answer answer = wrapper.execute(command, libvirtComputingResource);
assertFalse(answer.getResult());
verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getGuestNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
}
@Test
@ -2594,8 +2595,8 @@ public class LibvirtComputingResourceTest {
final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
when(libvirtComputingResource.checkNetwork(networkSetupInfo.getGuestNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(networkSetupInfo.getPrivateNetworkName())).thenReturn(false);
when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName())).thenReturn(false);
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
assertNotNull(wrapper);
@ -2603,8 +2604,8 @@ public class LibvirtComputingResourceTest {
final Answer answer = wrapper.execute(command, libvirtComputingResource);
assertFalse(answer.getResult());
verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getGuestNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getPrivateNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName());
}
@Test
@ -2616,9 +2617,9 @@ public class LibvirtComputingResourceTest {
final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
when(libvirtComputingResource.checkNetwork(networkSetupInfo.getGuestNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(networkSetupInfo.getPrivateNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(networkSetupInfo.getPublicNetworkName())).thenReturn(false);
when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName())).thenReturn(true);
when(libvirtComputingResource.checkNetwork(TrafficType.Public, networkSetupInfo.getPublicNetworkName())).thenReturn(false);
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
assertNotNull(wrapper);
@ -2626,8 +2627,8 @@ public class LibvirtComputingResourceTest {
final Answer answer = wrapper.execute(command, libvirtComputingResource);
assertFalse(answer.getResult());
verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getGuestNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getPrivateNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName());
}
@Test
@ -3151,12 +3152,13 @@ public class LibvirtComputingResourceTest {
when(intDef.getMacAddress()).thenReturn("00:00:00:00");
when(nic.getMac()).thenReturn("00:00:00:01");
when(nic.getName()).thenReturn("br0");
try {
when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
when(libvirtComputingResource.getVifDriver(nic.getType())).thenReturn(vifDriver);
when(libvirtComputingResource.getVifDriver(nic.getType(), nic.getName())).thenReturn(vifDriver);
when(vifDriver.plug(nic, "Other PV", "")).thenReturn(interfaceDef);
when(interfaceDef.toString()).thenReturn("Interface");
@ -3180,7 +3182,7 @@ public class LibvirtComputingResourceTest {
try {
verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType());
verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType(), nic.getName());
verify(vifDriver, times(1)).plug(nic, "Other PV", "");
} catch (final LibvirtException e) {
fail(e.getMessage());
@ -3253,7 +3255,7 @@ public class LibvirtComputingResourceTest {
when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
when(libvirtComputingResource.getVifDriver(nic.getType())).thenReturn(vifDriver);
when(libvirtComputingResource.getVifDriver(nic.getType(), nic.getName())).thenReturn(vifDriver);
when(vifDriver.plug(nic, "Other PV", "")).thenThrow(InternalErrorException.class);
@ -3273,7 +3275,7 @@ public class LibvirtComputingResourceTest {
try {
verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType());
verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType(), nic.getName());
verify(vifDriver, times(1)).plug(nic, "Other PV", "");
} catch (final LibvirtException e) {
fail(e.getMessage());

View File

@ -19,14 +19,15 @@
package com.cloud.hypervisor.kvm.resource;
import junit.framework.TestCase;
import java.io.File;
import java.util.List;
import junit.framework.TestCase;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
public class LibvirtDomainXMLParserTest extends TestCase {
@ -227,6 +228,8 @@ public class LibvirtDomainXMLParserTest extends TestCase {
for (int i = 0; i < ifs.size(); i++) {
assertEquals(ifModel, ifs.get(i).getModel());
assertEquals(ifType, ifs.get(i).getNetType());
assertEquals(Integer.valueOf(i + 3), ifs.get(i).getSlot());
assertEquals("vnet" + i, ifs.get(i).getDevName());
}
List<RngDef> rngs = parser.getRngs();

View File

@ -19,14 +19,15 @@
package com.cloud.hypervisor.kvm.resource;
import java.io.File;
import junit.framework.TestCase;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
import com.cloud.utils.Pair;
import java.io.File;
public class LibvirtVMDefTest extends TestCase {
public void testInterfaceEtehrnet() {
@ -34,8 +35,12 @@ public class LibvirtVMDefTest extends TestCase {
ifDef.defEthernet("targetDeviceName", "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO);
String expected =
"<interface type='ethernet'>\n" + "<target dev='targetDeviceName'/>\n" + "<mac address='00:11:22:aa:bb:dd'/>\n" + "<model type='virtio'/>\n"
+ "</interface>\n";
"<interface type='ethernet'>\n"
+ "<target dev='targetDeviceName'/>\n"
+ "<mac address='00:11:22:aa:bb:dd'/>\n"
+ "<model type='virtio'/>\n"
+ "<link state='up'/>\n"
+ "</interface>\n";
assertEquals(expected, ifDef.toString());
}
@ -45,8 +50,44 @@ public class LibvirtVMDefTest extends TestCase {
ifDef.defDirectNet("targetDeviceName", null, "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO, "private");
String expected =
"<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.DIRECT + "'>\n" + "<source dev='targetDeviceName' mode='private'/>\n" +
"<mac address='00:11:22:aa:bb:dd'/>\n" + "<model type='virtio'/>\n" + "</interface>\n";
"<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.DIRECT + "'>\n"
+ "<source dev='targetDeviceName' mode='private'/>\n"
+ "<mac address='00:11:22:aa:bb:dd'/>\n"
+ "<model type='virtio'/>\n"
+ "<link state='up'/>\n"
+ "</interface>\n";
assertEquals(expected, ifDef.toString());
}
public void testInterfaceBridgeSlot() {
LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
ifDef.defBridgeNet("targetDeviceName", null, "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO);
ifDef.setSlot(16);
String expected =
"<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.BRIDGE + "'>\n"
+ "<source bridge='targetDeviceName'/>\n"
+ "<mac address='00:11:22:aa:bb:dd'/>\n"
+ "<model type='virtio'/>\n"
+ "<link state='up'/>\n"
+ "<address type='pci' domain='0x0000' bus='0x00' slot='0x10' function='0x0'/>\n"
+ "</interface>\n";
assertEquals(expected, ifDef.toString());
ifDef.setLinkStateUp(false);
ifDef.setDevName("vnet11");
expected =
"<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.BRIDGE + "'>\n"
+ "<source bridge='targetDeviceName'/>\n"
+ "<target dev='vnet11'/>\n"
+ "<mac address='00:11:22:aa:bb:dd'/>\n"
+ "<model type='virtio'/>\n"
+ "<link state='down'/>\n"
+ "<address type='pci' domain='0x0000' bus='0x00' slot='0x10' function='0x0'/>\n"
+ "</interface>\n";
assertEquals(expected, ifDef.toString());
}

View File

@ -0,0 +1,274 @@
// 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.hypervisor.kvm.resource.wrapper;
import static org.mockito.AdditionalMatchers.not;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.naming.ConfigurationException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import org.mockito.BDDMockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ReplugNicCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.hypervisor.kvm.resource.BridgeVifDriver;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.resource.OvsVifDriver;
import com.cloud.network.Networks;
import com.cloud.utils.script.Script;
import com.cloud.vm.VirtualMachine;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Script.class)
public class LibvirtReplugNicCommandWrapperTest {
private static final String part_1 =
"<domain type='kvm' id='143'>\n"
+ " <name>i-85-285-VM</name>\n"
+ " <uuid>8825b180-468f-4227-beb7-6b06fd342116</uuid>\n"
+ " <description>CentOS 5.5 (64-bit)</description>\n"
+ " <memory unit='KiB'>262144</memory>\n"
+ " <currentMemory unit='KiB'>262144</currentMemory>\n"
+ " <vcpu placement='static'>1</vcpu>\n"
+ " <cputune>\n"
+ " <shares>256</shares>\n"
+ " </cputune>\n"
+ " <sysinfo type='smbios'>\n"
+ " <system>\n"
+ " <entry name='manufacturer'>Apache Software Foundation</entry>\n"
+ " <entry name='product'>CloudStack KVM Hypervisor</entry>\n"
+ " <entry name='uuid'>8825b180-468f-4227-beb7-6b06fd342116</entry>\n"
+ " </system>\n"
+ " </sysinfo>\n"
+ " <os>\n"
+ " <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>\n"
+ " <boot dev='cdrom'/>\n"
+ " <boot dev='hd'/>\n"
+ " <smbios mode='sysinfo'/>\n"
+ " </os>\n"
+ " <features>\n"
+ " <acpi/>\n"
+ " <apic/>\n"
+ " <pae/>\n"
+ " </features>\n"
+ " <clock offset='utc'>\n"
+ " <timer name='kvmclock'/>\n"
+ " </clock>\n"
+ " <on_poweroff>destroy</on_poweroff>\n"
+ " <on_reboot>restart</on_reboot>\n"
+ " <on_crash>destroy</on_crash>\n"
+ " <devices>\n"
+ " <emulator>/usr/libexec/qemu-kvm</emulator>\n"
+ " <disk type='file' device='disk'>\n"
+ " <driver name='qemu' type='qcow2' cache='none'/>\n"
+ " <source file='/mnt/4436eeec-abec-3ef8-b733-c9541df20361/0c4aae69-2652-4a04-b460-1abb5a1a695c'/>\n"
+ " <backingStore type='file' index='1'>\n"
+ " <format type='raw'/>\n"
+ " <source file='/mnt/4436eeec-abec-3ef8-b733-c9541df20361/d9ce07e5-9e13-11e7-816b-faac09070700'/>\n"
+ " <backingStore/>\n"
+ " </backingStore>\n"
+ " <target dev='vda' bus='virtio'/>\n"
+ " <serial>0c4aae6926524a04b460</serial>\n"
+ " <alias name='virtio-disk0'/>\n"
+ " <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>\n"
+ " </disk>\n"
+ " <disk type='file' device='cdrom'>\n"
+ " <driver name='qemu' type='raw' cache='none'/>\n"
+ " <backingStore/>\n"
+ " <target dev='hdc' bus='ide'/>\n"
+ " <readonly/>\n"
+ " <alias name='ide0-1-0'/>\n"
+ " <address type='drive' controller='0' bus='1' target='0' unit='0'/>\n"
+ " </disk>\n"
+ " <controller type='usb' index='0'>\n"
+ " <alias name='usb'/>\n"
+ " <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>\n"
+ " </controller>\n"
+ " <controller type='pci' index='0' model='pci-root'>\n"
+ " <alias name='pci.0'/>\n"
+ " </controller>\n"
+ " <controller type='ide' index='0'>\n"
+ " <alias name='ide'/>\n"
+ " <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>\n"
+ " </controller>\n"
+ " <controller type='virtio-serial' index='0'>\n"
+ " <alias name='virtio-serial0'/>\n"
+ " <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n"
+ " </controller>\n";
private static final String part_2 =
" <interface type='bridge'>\n"
+ " <mac address='02:00:7c:98:00:02'/>\n"
+ " <source bridge='breth2-234'/>\n"
+ " <bandwidth>\n"
+ " <inbound average='25600' peak='25600'/>\n"
+ " <outbound average='25600' peak='25600'/>\n"
+ " </bandwidth>\n"
+ " <target dev='vnet10'/>\n"
+ " <model type='virtio'/>\n"
+ " <link state='up'/>\n"
+ " <alias name='net0'/>\n"
+ " <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n"
+ " </interface>\n";
private static final String part_3 =
" <serial type='pty'>\n"
+ " <source path='/dev/pts/4'/>\n"
+ " <target port='0'/>\n"
+ " <alias name='serial0'/>\n"
+ " </serial>\n"
+ " <console type='pty' tty='/dev/pts/4'>\n"
+ " <source path='/dev/pts/4'/>\n"
+ " <target type='serial' port='0'/>\n"
+ " <alias name='serial0'/>\n"
+ " </console>\n"
+ " <channel type='unix'>\n"
+ " <source mode='bind' path='/var/lib/libvirt/qemu/i-85-285-VM.org.qemu.guest_agent.0'/>\n"
+ " <target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/>\n"
+ " <alias name='channel0'/>\n"
+ " <address type='virtio-serial' controller='0' bus='0' port='1'/>\n"
+ " </channel>\n"
+ " <input type='tablet' bus='usb'>\n"
+ " <alias name='input0'/>\n"
+ " </input>\n"
+ " <input type='mouse' bus='ps2'/>\n"
+ " <input type='keyboard' bus='ps2'/>\n"
+ " <graphics type='vnc' port='5903' autoport='yes' listen='10.100.100.11'>\n"
+ " <listen type='address' address='10.100.100.11'/>\n"
+ " </graphics>\n"
+ " <video>\n"
+ " <model type='cirrus' vram='16384' heads='1'/>\n"
+ " <alias name='video0'/>\n"
+ " <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n"
+ " </video>\n"
+ " <memballoon model='none'>\n"
+ " <alias name='balloon0'/>\n"
+ " </memballoon>\n"
+ " </devices>\n"
+ "</domain>\n";
private static final String fullfile = part_1 + part_2 + part_3;
private LibvirtComputingResource res;
private final Domain _domain = mock(Domain.class);
@Before
public void setUp() throws LibvirtException, ConfigurationException {
// Use a spy because we only want to override getVifDriverClass
LibvirtComputingResource resReal = new LibvirtComputingResource();
res = spy(resReal);
Connect conn = mock(Connect.class);
LibvirtUtilitiesHelper helper = mock(LibvirtUtilitiesHelper.class);
when(_domain.getXMLDesc(0))
.thenReturn(fullfile)
.thenReturn(part_1 + part_3);
when(conn.domainLookupByName(anyString())).thenReturn(_domain);
when(helper.getConnectionByVmName(anyString())).thenReturn(conn);
PowerMockito.mockStatic(Script.class);
BDDMockito.given(Script.findScript(anyString(), anyString())).willReturn("dummypath/tofile.sh");
Map<String, String> pifs = new HashMap<>();
pifs.put("alubr0", "alubr0");
Map<String, Object> params = new HashMap<>();
params.put("libvirt.computing.resource", res);
params.put("libvirt.host.pifs", pifs);
BridgeVifDriver bridgeVifDriver = spy(new BridgeVifDriver());
OvsVifDriver ovsVifDriver = spy(new OvsVifDriver());
doNothing().when(bridgeVifDriver).getPifs();
doNothing().when(ovsVifDriver).getPifs();
doReturn(helper).when(res).getLibvirtUtilitiesHelper();
doReturn(bridgeVifDriver).when(res).getVifDriver(eq(Networks.TrafficType.Guest), anyString());
doReturn(ovsVifDriver).when(res).getVifDriver(Networks.TrafficType.Guest, "alubr0");
doReturn(bridgeVifDriver).when(res).getVifDriver(not(eq(Networks.TrafficType.Guest)));
doReturn(Arrays.asList(bridgeVifDriver, ovsVifDriver)).when(res).getAllVifDrivers();
bridgeVifDriver.configure(params);
ovsVifDriver.configure(params);
}
@Test
public void testReplugNic() throws LibvirtException {
final String expectedDetachXml =
"<interface type='bridge'>\n"
+ "<source bridge='breth2-234'/>\n"
+ "<target dev='vnet10'/>\n"
+ "<mac address='02:00:7c:98:00:02'/>\n"
+ "<model type='virtio'/>\n"
+ "<link state='up'/>\n"
+ "</interface>\n";
final String expectedAttachXml =
"<interface type='bridge'>\n"
+ "<source bridge='alubr0'/>\n"
+ "<target dev='vnet10'/>\n"
+ "<mac address='02:00:7c:98:00:02'/>\n"
+ "<model type='virtio'/>\n"
+ "<virtualport type='openvswitch'>\n"
+ "</virtualport>\n"
+ "<link state='down'/>\n"
+ "<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n"
+ "</interface>\n";
final String expectedUpdateXml =
"<interface type='bridge'>\n"
+ "<source bridge='alubr0'/>\n"
+ "<target dev='vnet10'/>\n"
+ "<mac address='02:00:7c:98:00:02'/>\n"
+ "<model type='virtio'/>\n"
+ "<virtualport type='openvswitch'>\n"
+ "</virtualport>\n"
+ "<link state='up'/>\n"
+ "<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n"
+ "</interface>\n";
final LibvirtReplugNicCommandWrapper wrapper = new LibvirtReplugNicCommandWrapper();
final NicTO nic = new NicTO();
nic.setType(Networks.TrafficType.Guest);
nic.setName("alubr0");
nic.setBroadcastType(Networks.BroadcastDomainType.Vsp);
nic.setMac("02:00:7c:98:00:02");
final ReplugNicCommand command = new ReplugNicCommand(nic, "i-85-285-VM", VirtualMachine.Type.User);
final Answer result = wrapper.execute(command, res);
verify(_domain).detachDevice(expectedDetachXml);
verify(_domain).attachDevice(expectedAttachXml);
verify(_domain).updateDeviceFlags(expectedUpdateXml, LibvirtReplugNicCommandWrapper.DomainAffect.LIVE.getValue());
}
}

View File

@ -25,6 +25,8 @@ import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.agent.api.PlugNicAnswer;
import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.agent.api.ReplugNicAnswer;
import com.cloud.agent.api.ReplugNicCommand;
import com.cloud.agent.api.SetupGuestNetworkCommand;
import com.cloud.agent.api.UnPlugNicAnswer;
import com.cloud.agent.api.UnPlugNicCommand;
@ -70,6 +72,8 @@ public interface MockNetworkManager extends Manager {
UnPlugNicAnswer unplugNic(UnPlugNicCommand cmd);
ReplugNicAnswer replugNic(ReplugNicCommand cmd);
IpAssocAnswer ipAssoc(IpAssocVpcCommand cmd);
SetSourceNatAnswer setSourceNat(SetSourceNatCommand cmd);

View File

@ -30,6 +30,8 @@ import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.agent.api.PlugNicAnswer;
import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.agent.api.ReplugNicAnswer;
import com.cloud.agent.api.ReplugNicCommand;
import com.cloud.agent.api.SetupGuestNetworkCommand;
import com.cloud.agent.api.UnPlugNicAnswer;
import com.cloud.agent.api.UnPlugNicCommand;
@ -134,13 +136,24 @@ public class MockNetworkManagerImpl extends ManagerBase implements MockNetworkMa
public UnPlugNicAnswer unplugNic(UnPlugNicCommand cmd) {
String vmname = cmd.getVmName();
if (_mockVmDao.findByVmName(vmname) != null) {
s_logger.debug("Plugged NIC (dev=" + cmd.getNic().getDeviceId() + ", " + cmd.getNic().getIp() + ") into " + cmd.getVmName());
s_logger.debug("Unplugged NIC (dev=" + cmd.getNic().getDeviceId() + ", " + cmd.getNic().getIp() + ") into " + cmd.getVmName());
return new UnPlugNicAnswer(cmd, true, "success");
}
s_logger.error("Plug NIC failed for (dev=" + cmd.getNic().getDeviceId() + ", " + cmd.getNic().getIp() + ") into " + cmd.getVmName());
s_logger.error("Unplug NIC failed for (dev=" + cmd.getNic().getDeviceId() + ", " + cmd.getNic().getIp() + ") into " + cmd.getVmName());
return new UnPlugNicAnswer(cmd, false, "failure");
}
@Override
public ReplugNicAnswer replugNic(ReplugNicCommand cmd) {
String vmname = cmd.getVmName();
if (_mockVmDao.findByVmName(vmname) != null) {
s_logger.debug("Replugged NIC (dev=" + cmd.getNic().getDeviceId() + ", " + cmd.getNic().getIp() + ") into " + cmd.getVmName());
return new ReplugNicAnswer(cmd, true, "success");
}
s_logger.error("Replug NIC failed for (dev=" + cmd.getNic().getDeviceId() + ", " + cmd.getNic().getIp() + ") into " + cmd.getVmName());
return new ReplugNicAnswer(cmd, false, "failure");
}
@Override
public IpAssocAnswer ipAssoc(IpAssocVpcCommand cmd) {
String[] results = new String[cmd.getIpAddresses().length];

View File

@ -26,6 +26,12 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
import org.apache.cloudstack.ca.SetupCertificateCommand;
import org.apache.cloudstack.ca.SetupKeyStoreCommand;
import org.apache.cloudstack.storage.command.DeleteCommand;
@ -33,8 +39,6 @@ import org.apache.cloudstack.storage.command.DownloadCommand;
import org.apache.cloudstack.storage.command.DownloadProgressCommand;
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
import org.apache.cloudstack.storage.command.UploadStatusCommand;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
@ -71,6 +75,7 @@ import com.cloud.agent.api.PlugNicCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.ReplugNicCommand;
import com.cloud.agent.api.RevertToVMSnapshotCommand;
import com.cloud.agent.api.ScaleVmCommand;
import com.cloud.agent.api.SecStorageFirewallCfgCommand;
@ -131,8 +136,6 @@ import com.cloud.utils.db.DB;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine.PowerState;
import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
@Component
public class SimulatorManagerImpl extends ManagerBase implements SimulatorManager, PluggableService {
@ -392,6 +395,8 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage
answer = _mockNetworkMgr.plugNic((PlugNicCommand)cmd);
} else if (cmd instanceof UnPlugNicCommand) {
answer = _mockNetworkMgr.unplugNic((UnPlugNicCommand)cmd);
} else if (cmd instanceof ReplugNicCommand) {
answer = _mockNetworkMgr.replugNic((ReplugNicCommand)cmd);
} else if (cmd instanceof IpAssocVpcCommand) {
answer = _mockNetworkMgr.ipAssoc((IpAssocVpcCommand)cmd);
} else if (cmd instanceof SetSourceNatCommand) {

View File

@ -53,9 +53,9 @@ import com.vmware.vim25.AboutInfo;
import com.vmware.vim25.BoolPolicy;
import com.vmware.vim25.ComputeResourceSummary;
import com.vmware.vim25.CustomFieldStringValue;
import com.vmware.vim25.DasVmPriority;
import com.vmware.vim25.DVPortConfigInfo;
import com.vmware.vim25.DVPortConfigSpec;
import com.vmware.vim25.DasVmPriority;
import com.vmware.vim25.DatastoreSummary;
import com.vmware.vim25.DistributedVirtualPort;
import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
@ -178,6 +178,8 @@ import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.RebootRouterCommand;
import com.cloud.agent.api.ReplugNicAnswer;
import com.cloud.agent.api.ReplugNicCommand;
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
import com.cloud.agent.api.RevertToVMSnapshotCommand;
import com.cloud.agent.api.ScaleVmAnswer;
@ -491,6 +493,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
answer = execute((CheckNetworkCommand)cmd);
} else if (clz == PlugNicCommand.class) {
answer = execute((PlugNicCommand)cmd);
} else if (clz == ReplugNicCommand.class) {
answer = execute((ReplugNicCommand)cmd);
} else if (clz == UnPlugNicCommand.class) {
answer = execute((UnPlugNicCommand)cmd);
} else if (cmd instanceof CreateVMSnapshotCommand) {
@ -1116,6 +1120,87 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
}
private ReplugNicAnswer execute(ReplugNicCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource ReplugNicCommand " + _gson.toJson(cmd));
}
getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
VmwareContext context = getServiceContext();
try {
VmwareHypervisorHost hyperHost = getHyperHost(context);
String vmName = cmd.getVmName();
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
if (vmMo == null) {
if (hyperHost instanceof HostMO) {
ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
vmMo = clusterMo.findVmOnHyperHost(vmName);
}
}
if (vmMo == null) {
String msg = "Router " + vmName + " no longer exists to execute ReplugNic command";
s_logger.error(msg);
throw new Exception(msg);
}
/*
if(!isVMWareToolsInstalled(vmMo)){
String errMsg = "vmware tools is not installed or not running, cannot add nic to vm " + vmName;
s_logger.debug(errMsg);
return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + errMsg);
}
*/
// Fallback to E1000 if no specific nicAdapter is passed
VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000;
Map<String, String> details = cmd.getDetails();
if (details != null) {
nicDeviceType = VirtualEthernetCardType.valueOf((String) details.get("nicAdapter"));
}
NicTO nicTo = cmd.getNic();
VirtualDevice nic = findVirtualNicDevice(vmMo, nicTo.getMac());
if (nic == null) {
return new ReplugNicAnswer(cmd, false, "Nic to replug not found");
}
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, cmd.getVMType());
String dvSwitchUuid = null;
if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
VmwareHelper.updateDvNicDevice(nic, networkInfo.first(), dvSwitchUuid);
} else {
s_logger.info("Preparing NIC device on network " + networkInfo.second());
VmwareHelper.updateNicDevice(nic, networkInfo.first(), networkInfo.second());
}
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
//VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
deviceConfigSpec.setDevice(nic);
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo, dvSwitchUuid);
if (!vmMo.configureVm(vmConfigSpec)) {
throw new Exception("Failed to configure devices when running ReplugNicCommand");
}
return new ReplugNicAnswer(cmd, true, "success");
} catch (Exception e) {
s_logger.error("Unexpected exception: ", e);
return new ReplugNicAnswer(cmd, false, "Unable to execute ReplugNicCommand due to " + e.toString());
}
}
private UnPlugNicAnswer execute(UnPlugNicCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource UnPlugNicCommand " + _gson.toJson(cmd));

View File

@ -35,7 +35,7 @@
</repository>
</repositories>
<properties>
<nuage.vsp.client.version>1.0.5</nuage.vsp.client.version>
<nuage.vsp.client.version>1.0.6</nuage.vsp.client.version>
</properties>
<dependencies>
<dependency>

View File

@ -19,40 +19,7 @@
package com.cloud.network.element;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.commons.lang3.StringUtils;
import net.nuage.vsp.acs.client.api.model.VspAclRule;
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
import net.nuage.vsp.acs.client.api.model.VspNetwork;
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.network.ExternalNetworkDeviceManager;
import org.apache.cloudstack.network.topology.NetworkTopologyContext;
import org.apache.cloudstack.resourcedetail.VpcDetailVO;
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.StartupCommand;
@ -65,7 +32,6 @@ import com.cloud.agent.api.element.ShutDownVpcVspCommand;
import com.cloud.agent.api.element.ShutDownVspCommand;
import com.cloud.dc.Vlan;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.deploy.DeployDestination;
@ -77,11 +43,11 @@ import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.UnsupportedServiceException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkMigrationManager;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks;
import com.cloud.network.PhysicalNetworkServiceProvider;
@ -90,14 +56,11 @@ import com.cloud.network.dao.FirewallRulesCidrsDao;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.NuageVspDao;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.manager.NuageVspManager;
import com.cloud.network.manager.NuageVspManagerImpl;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.FirewallRuleType;
import com.cloud.network.rules.FirewallRuleVO;
@ -109,16 +72,16 @@ import com.cloud.network.vpc.PrivateGateway;
import com.cloud.network.vpc.StaticRouteProfile;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcOfferingServiceMapVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.resource.ResourceManager;
import com.cloud.resource.ResourceStateAdapter;
import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.server.ResourceTag;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.util.NuageVspEntityBuilder;
import com.cloud.util.NuageVspUtil;
import com.cloud.utils.Pair;
@ -132,6 +95,33 @@ import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import net.nuage.vsp.acs.client.api.model.VspAclRule;
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
import net.nuage.vsp.acs.client.api.model.VspNetwork;
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.network.ExternalNetworkDeviceManager;
import org.apache.cloudstack.resourcedetail.VpcDetailVO;
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class NuageVspElement extends AdapterBase implements ConnectivityProvider, IpDeployer, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider,
DhcpServiceProvider, ResourceStateAdapter, VpcProvider, NetworkACLServiceProvider {
@ -165,20 +155,12 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
@Inject
ResourceManager _resourceMgr;
@Inject
HostDao _hostDao;
@Inject
NetworkModel _networkModel;
@Inject
NetworkServiceMapDao _ntwkSrvcDao;
@Inject
NuageVspDao _nuageVspDao;
@Inject
NetworkDao _networkDao;
@Inject
DomainDao _domainDao;
@Inject
DataCenterDao _dcDao;
@Inject
IPAddressDao _ipAddressDao;
@Inject
VlanDao _vlanDao;
@ -187,12 +169,8 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
@Inject
NicDao _nicDao;
@Inject
VpcDao _vpcDao;
@Inject
VpcOfferingServiceMapDao _vpcOfferingSrvcDao;
@Inject
NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
@Inject
AgentManager _agentMgr;
@Inject
NetworkOfferingDao _ntwkOfferingDao;
@ -212,15 +190,10 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
NuageVspEntityBuilder _nuageVspEntityBuilder;
@Inject
VpcDetailsDao _vpcDetailsDao;
@Inject
NetworkModel _networkMgr;
@Inject
NetworkTopologyContext networkTopologyContext;
@Inject
DomainRouterDao _routerDao;
@Inject
VpcVirtualNetworkApplianceManager _routerMgr;
ResourceTagDao _resourceTagDao;
@Override
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> service) throws ResourceUnavailableException {
@ -714,6 +687,17 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
preConfiguredDomainTemplateName = _configDao.getValue(NuageVspManager.NuageVspVpcDomainTemplateName.key());
}
cleanUpVpcCaching(vpc.getId());
//related to migration caching
List<? extends ResourceTag> vpcResourceDetails = _resourceTagDao.listByResourceUuid(vpc.getUuid());
if (vpcResourceDetails != null) {
vpcResourceDetails.stream()
.filter(item -> item.getKey().equals(NetworkMigrationManager.MIGRATION))
.findFirst()
.map(ResourceTag::getResourceId)
.ifPresent(this::cleanUpVpcCaching);
}
ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand(vpcDomain.getUuid(), vpc.getUuid(), preConfiguredDomainTemplateName, domainRouterUuids);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
@ -721,11 +705,17 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
if ((null != answer) && (null != answer.getDetails())) {
throw new ResourceUnavailableException(answer.getDetails(), Vpc.class, vpc.getId());
}
return false;
}
}
return true;
}
private void cleanUpVpcCaching(long vpcId) {
_vpcDetailsDao.removeDetail(vpcId, NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
_vpcDetailsDao.removeDetail(vpcId, NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
}
private Long getPhysicalNetworkId(Long zoneId) {
Long guestPhysicalNetworkId = 0L;
List<PhysicalNetworkVO> physicalNetworkList = _physicalNetworkDao.listByZone(zoneId);

View File

@ -223,7 +223,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
implemented.setCidr(network.getCidr());
}
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(implemented);
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(implemented, true);
String tenantId = context.getDomain().getName() + "-" + context.getAccount().getAccountId();
String broadcastUriStr = implemented.getUuid() + "/" + vspNetwork.getVirtualRouterIp();
implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
@ -268,22 +268,20 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
}
private void saveNetworkAndVpcDetails(VspNetwork vspNetwork, NetworkRelatedVsdIds networkRelatedVsdIds, Long vpcId) {
if (!vspNetwork.isShared() && !vspNetwork.getNetworkRelatedVsdIds().equals(networkRelatedVsdIds)) {
Map<String, String> networkDetails = constructNetworkDetails(networkRelatedVsdIds, vspNetwork.isVpc());
long networkId = vspNetwork.getId();
for (Map.Entry<String, String> networkDetail : networkDetails.entrySet()) {
NetworkDetailVO networkDetailVO = new NetworkDetailVO(vspNetwork.getId(), networkDetail.getKey(), networkDetail.getValue(), false);
_networkDetailsDao.persist(networkDetailVO);
_networkDetailsDao.addDetail(networkId, networkDetail.getKey(), networkDetail.getValue(), false);
}
if(vspNetwork.isVpc()) {
Map<String, String> vpcDetails = constructVpcDetails(networkRelatedVsdIds);
for (Map.Entry<String, String> vpcDetail : vpcDetails.entrySet()) {
VpcDetailVO vpcDetailVO = new VpcDetailVO(vpcId, vpcDetail.getKey(), vpcDetail.getValue(), false);
_vpcDetailsDao.persist(vpcDetailVO);
_vpcDetailsDao.addDetail(vpcId, vpcDetail.getKey(), vpcDetail.getValue(), false);
}
}
}
@ -355,6 +353,16 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network);
if (vm.getType() == VirtualMachine.Type.DomainRouter && vspNetwork.getVirtualRouterIp().equals("null")) {
//In case of upgrade network offering
vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network, true);
String broadcastUriStr = network.getUuid() + "/" + vspNetwork.getVirtualRouterIp();
NetworkVO updatedNetwork = _networkDao.createForUpdate(network.getId());
updatedNetwork.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
_networkDao.update(updatedNetwork.getId(), updatedNetwork);
network = _networkDao.findById(network.getId());
}
if (vspNetwork.isShared()) {
vspNetwork = _nuageVspEntityBuilder.updateVspNetworkByPublicIp(vspNetwork, network, nic.getIPv4Address());
@ -623,6 +631,17 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Handling trash() call back to delete the network " + network.getName() + " with uuid " + network.getUuid() + " from VSP");
}
boolean networkMigrationCopy = network.getRelated() != network.getId();
cleanUpNetworkCaching(network.getId());
if (networkMigrationCopy) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Network " + network.getName() + " is a copy of a migrated network. Cleaning up network details of related network.");
}
cleanUpNetworkCaching(network.getRelated());
}
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(vspNetwork);
@ -640,6 +659,12 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
return super.trash(network, offering);
}
private void cleanUpNetworkCaching(long id) {
_networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
_networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
_networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID);
}
private boolean networkHasDns(Network network) {
if (network != null) {

View File

@ -19,6 +19,7 @@
package com.cloud.util;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@ -159,11 +160,18 @@ public class NuageVspEntityBuilder {
}
public VspNetwork buildVspNetwork(Network network) {
return buildVspNetwork(network.getDomainId(), network);
return buildVspNetwork(network.getDomainId(), network, false);
}
//TODO:Sigert implement caching in this function. retrieve data
public VspNetwork buildVspNetwork(long domainId, Network network) {
return buildVspNetwork(domainId, network, false);
}
public VspNetwork buildVspNetwork(Network network, boolean recalculateBroadcastUri) {
return buildVspNetwork(network.getDomainId(), network, recalculateBroadcastUri);
}
public VspNetwork buildVspNetwork(long domainId, Network network, boolean recalculateBroadcastUri) {
VspNetwork.Builder vspNetworkBuilder = new VspNetwork.Builder()
.id(network.getId())
.uuid(network.getUuid())
@ -247,7 +255,7 @@ public class NuageVspEntityBuilder {
try {
List<Pair<String, String>> ipAddressRanges =
networkOffering.getGuestType() == Network.GuestType.Shared ? getSharedIpAddressRanges(network.getId()) : getIpAddressRanges(network);
String virtualRouterIp = getVirtualRouterIP(network, ipAddressRanges);
String virtualRouterIp = getVirtualRouterIP(network, ipAddressRanges, recalculateBroadcastUri);
vspNetworkBuilder.virtualRouterIp(virtualRouterIp);
} catch (InsufficientVirtualNetworkCapacityException ex) {
s_logger.error("There is an insufficient network capacity in network " + network.getId(), ex);
@ -332,10 +340,20 @@ public class NuageVspEntityBuilder {
return null;
}
private String getVirtualRouterIP(Network network, List<Pair<String, String>> ipAddressRanges) throws InsufficientVirtualNetworkCapacityException {
if (network.getBroadcastUri() != null) {
private String getVirtualRouterIP(Network network, List<Pair<String, String>> ipAddressRanges, boolean recalculateBroadcastUri) throws InsufficientVirtualNetworkCapacityException {
//Add a check to see if a VR should be present in the offering or not?
if (!recalculateBroadcastUri && network.getBroadcastUri() != null) {
return network.getBroadcastUri().getPath().substring(1);
}
ensureIpCapacity(network, ipAddressRanges);
if(network.getGuestType() == Network.GuestType.Shared) {
return ipAddressRanges.stream()
.sorted(Comparator.comparingLong(p -> NetUtils.ip2Long(p.getLeft())))
.findFirst()
.map(Pair::getLeft)
.orElseThrow(() -> new IllegalArgumentException("Shared network without ip ranges? How can this happen?"));
}
Pair<String, String> lowestIpAddressRange = null;
long ipCount = 0;
@ -351,6 +369,33 @@ public class NuageVspEntityBuilder {
}
}
Network networkToCheck;
if (isMigratingNetwork(network)) {
networkToCheck = _networkDao.findById(network.getRelated());
} else {
networkToCheck = network;
}
Long freeIp = _networkModel.getAvailableIps(networkToCheck, null)
.stream()
.findFirst()
.orElseThrow(() -> new InsufficientVirtualNetworkCapacityException("There is no free ip available for the VirtualRouter.",
Network.class,
network.getId()));
return NetUtils.long2Ip(freeIp);
}
private boolean isMigratingNetwork(Network network) {
return network.getRelated() != network.getId();
}
private void ensureIpCapacity(Network network, List<Pair<String, String>> ipAddressRanges) throws InsufficientVirtualNetworkCapacityException {
long ipCount = ipAddressRanges.stream()
.mapToLong(this::getIpCount)
.sum();
if (ipCount == 0) {
throw new InsufficientVirtualNetworkCapacityException("VSP allocates an IP for VirtualRouter." + " But no ip address ranges are specified", Network.class,
network.getId());
@ -358,12 +403,10 @@ public class NuageVspEntityBuilder {
throw new InsufficientVirtualNetworkCapacityException("VSP allocates an IP for VirtualRouter." + " So, subnet should have atleast minimum 3 hosts", Network.class,
network.getId());
}
}
String virtualRouterIp = lowestIpAddressRange.getLeft();
long lowestIp = NetUtils.ip2Long(lowestIpAddressRange.getLeft());
lowestIp = lowestIp + 1;
lowestIpAddressRange.setLeft(NetUtils.long2Ip(lowestIp));
return virtualRouterIp;
private long getIpCount(Pair<String, String> ipAddressRange) {
return NetUtils.ip2Long(ipAddressRange.getRight()) - NetUtils.ip2Long(ipAddressRange.getLeft()) + 1;
}
public VspVm buildVspVm(VirtualMachine vm, Network network) {

View File

@ -89,11 +89,18 @@ public class NuageTest {
ConfigKey.init(configDepot);
when(_nuageVspEntityBuilder.buildVspDomain(any(Domain.class))).thenReturn(buildVspDomain());
when(_nuageVspEntityBuilder.buildVspNetwork(any(Network.class))).thenReturn(buildVspNetwork());
when(_nuageVspEntityBuilder.buildVspNetwork(anyLong(), any(Network.class))).thenReturn(buildVspNetwork());
VspNetwork vspNetwork = buildVspNetwork();
when(_nuageVspEntityBuilder.buildVspNetwork(any(Network.class))).thenReturn(vspNetwork);
when(_nuageVspEntityBuilder.buildVspNetwork(any(Network.class), anyBoolean())).thenReturn(vspNetwork);
when(_nuageVspEntityBuilder.buildVspNetwork(anyLong(), any(Network.class))).thenReturn(vspNetwork);
when(_nuageVspEntityBuilder.buildVspNetwork(anyLong(), any(Network.class), anyBoolean())).thenReturn(vspNetwork);
when(_nuageVspEntityBuilder.buildVspVm(any(VirtualMachine.class), any(Network.class))).thenReturn(buildVspVm());
when(_nuageVspEntityBuilder.buildVspNic(anyString(), any(NicProfile.class))).thenReturn(buildVspNic());
when(_nuageVspEntityBuilder.buildVspNic(any(NicVO.class))).thenReturn(buildVspNic());
when(_nuageVspEntityBuilder.buildVspStaticNat(anyBoolean(), any(IPAddressVO.class), any(VlanVO.class), any(NicVO.class))).thenReturn(buildVspStaticNat());
when(_nuageVspEntityBuilder.buildVspAclRule(any(FirewallRule.class), any(Network.class))).thenReturn(buildVspAclRule());
when(_nuageVspEntityBuilder.buildVspAclRule(any(NetworkACLItem.class))).thenReturn(buildVspAclRule());

View File

@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import com.cloud.tags.dao.ResourceTagDao;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
@ -107,6 +108,7 @@ public class NuageVspElementTest extends NuageTest {
@Mock private VpcDetailsDao _vpcDetailsDao;
@Mock private DomainRouterDao _domainRouterDao;
@Mock private ResourceManager _resourceManager;
@Mock private ResourceTagDao _resourceTagDao;
@Before
public void setUp() throws Exception {

View File

@ -107,6 +107,8 @@
<bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
<bean id="NetworkMigrationManagerImpl" class="com.cloud.network.NetworkMigrationManagerImpl" />
<bean id="alertManagerImpl" class="com.cloud.alert.AlertManagerImpl" />

View File

@ -5071,6 +5071,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
final Integer maxconn = cmd.getMaxconnections();
Availability availability = null;
final String state = cmd.getState();
final String tags = cmd.getTags();
CallContext.current().setEventDetails(" Id: " + id);
// Verify input parameters
@ -5111,6 +5112,25 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
}
if (tags != null) {
List<DataCenterVO> dataCenters = _zoneDao.listAll();
TrafficType trafficType = offeringToUpdate.getTrafficType();
String oldTags = offeringToUpdate.getTags();
for (DataCenterVO dataCenter : dataCenters) {
long zoneId = dataCenter.getId();
long newPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, tags, trafficType);
if (oldTags != null) {
long oldPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, oldTags, trafficType);
if (newPhysicalNetworkId != oldPhysicalNetworkId) {
throw new InvalidParameterValueException("New tags: selects different physical network for zone " + zoneId);
}
}
}
offering.setTags(tags);
}
// Verify availability
if (availabilityStr != null) {
for (final Availability avlb : Availability.values()) {

View File

@ -23,6 +23,7 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
import org.apache.cloudstack.api.ResourceDetail;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
import org.apache.cloudstack.resourcedetail.dao.AutoScaleVmGroupDetailsDao;
@ -124,6 +125,8 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource
SnapshotPolicyDetailsDao _snapshotPolicyDetailsDao;
@Inject
GuestOsDetailsDao _guestOsDetailsDao;
@Inject
NetworkOfferingDetailsDao _networkOfferingDetailsDao;
private static Map<ResourceObjectType, ResourceDetailsDao<? extends ResourceDetail>> s_daoMap = new HashMap<ResourceObjectType, ResourceDetailsDao<? extends ResourceDetail>>();
@ -157,6 +160,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource
s_daoMap.put(ResourceObjectType.LBHealthCheckPolicy, _healthcheckPolicyDetailsDao);
s_daoMap.put(ResourceObjectType.SnapshotPolicy, _snapshotPolicyDetailsDao);
s_daoMap.put(ResourceObjectType.GuestOs, _guestOsDetailsDao);
s_daoMap.put(ResourceObjectType.NetworkOffering, _networkOfferingDetailsDao);
return true;
}
@ -200,7 +204,11 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource
long id = _taggedResourceMgr.getResourceId(resourceId, resourceType);
DetailDaoHelper newDetailDaoHelper = new DetailDaoHelper(resourceType);
newDetailDaoHelper.removeDetail(id, key);
if (key != null) {
newDetailDaoHelper.removeDetail(id, key);
} else {
newDetailDaoHelper.removeDetails(id);
}
return true;
}
@ -225,6 +233,10 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource
dao.removeDetail(resourceId, key);
}
private void removeDetails(long resourceId) {
dao.removeDetails(resourceId);
}
private ResourceDetail getDetail(long resourceId, String key) {
return dao.findDetail(resourceId, key);
}

View File

@ -0,0 +1,85 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network;
import com.cloud.network.vpc.Vpc;
import com.cloud.offering.NetworkOffering;
/**
* The NetworkMigrationManager should be used for migration purpose ONLY.
*/
public interface NetworkMigrationManager {
String MIGRATION = "migration";
/**
* Returns a copy of the provided network.
* All nics in the orginal network will be re-assigned to the newly created network.
* All network details will be copied to the newly created network.
* @param network the network to be copied
* @param networkOffering the network offering of the network that is copied
* @return the networkid of the copy
*/
long makeCopyOfNetwork(Network network, NetworkOffering networkOffering, Long vpcId);
/**
* Returns a copy of the provided vpc
* All acls rules and public ips will be re-assigned to the newly created vpc.
* @param vpcId the vpc id of the vpc that needs to be copied
* @param vpcOfferingId the new vpc offering id
* @return the vpc id of the copy
*/
Long makeCopyOfVpc(long vpcId, long vpcOfferingId);
/**
* Starts the vpc if, the vpc is not already started
*/
void startVpc(Vpc vpc);
/**
* Upgrade the physical network and the offering of a network.
* @param networkId the networkid of the network that needs to be upgraded.
* @param newPhysicalNetworkId the id of the new physical network where the network should be moved to.
* @param networkOfferingId the new network offering.
* @return the networkid of the upgraded network
*/
Network upgradeNetworkToNewNetworkOffering (long networkId, long newPhysicalNetworkId, long networkOfferingId, Long vpcId);
/**
* Deletes the copy of a network which was previously created by the networkMigrationManager
* For deletion of the copy the old UUID of the original network is used to assure that plugins, using the UUID, clean up the network correctly.
* @param networkCopyId the networkId of the copied network
* @param originalNetworkId the networkId of the original network
*/
void deleteCopyOfNetwork(long networkCopyId, long originalNetworkId);
/**
* Deletes the copy of a vpc which was previously created by the networkMigrationManager
* For deletion the copy of the old UUID of the original vpc is used to assure that plugins, using the UUID, clean up the vpc correctly.
* @param vpcCopyId the vpc id of the copied vpc
* @param originalVpcId the vpc id of the original vpc
*/
void deleteCopyOfVpc(long vpcCopyId, long originalVpcId);
/**
* Moves all the nics from the srcNetwork to the network in the new physical network.
* The nics in the source network will be marked as removed afterwards.
* @param srcNetwork the source network containing the nics to be moved
* @param networkInNewPhysicalNet the destination network where the nics need to be recreated.
*/
void assignNicsToNewPhysicalNetwork(Network srcNetwork, Network networkInNewPhysicalNet);
}

View File

@ -0,0 +1,693 @@
// 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.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO;
import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.resourcedetail.FirewallRuleDetailVO;
import org.apache.cloudstack.resourcedetail.VpcDetailVO;
import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao;
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
import com.cloud.configuration.Resource;
import com.cloud.dc.DataCenter;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
import com.cloud.host.dao.HostDao;
import com.cloud.network.dao.FirewallRulesCidrsDao;
import com.cloud.network.dao.FirewallRulesCidrsVO;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkDetailVO;
import com.cloud.network.dao.NetworkDetailsDao;
import com.cloud.network.dao.NetworkDomainDao;
import com.cloud.network.dao.NetworkDomainVO;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.RouterNetworkDao;
import com.cloud.network.dao.RouterNetworkVO;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.rules.RulesManager;
import com.cloud.network.vpc.NetworkACLVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcGatewayVO;
import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpc.VpcService;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.NetworkACLDao;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcGatewayDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.server.ResourceTag;
import com.cloud.tags.ResourceTagVO;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.user.Account;
import com.cloud.user.AccountVO;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.Nic;
import com.cloud.vm.NicDetailVO;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.ReservationContextImpl;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachineProfileImpl;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicDetailsDao;
import com.cloud.vm.dao.NicIpAliasDao;
import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.UserVmDao;
public class NetworkMigrationManagerImpl implements NetworkMigrationManager {
public static final Logger s_logger = Logger.getLogger(NetworkMigrationManagerImpl.class.getName());
@Inject
private DataCenterDao _dcDao = null;
@Inject
private NetworkDetailsDao _networkDetailsDao = null;
@Inject
private AccountDao _accountDao = null;
@Inject
private NetworkDomainDao _networkDomainDao = null;
@Inject
private NetworkOrchestrationService _networkMgr = null;
@Inject
private ResourceLimitService _resourceLimitMgr = null;
@Inject
private NetworkDao _networksDao = null;
@Inject
private NetworkOfferingDao _networkOfferingDao = null;
@Inject
private NetworkOfferingServiceMapDao _networkOfferingServiceDao = null;
@Inject
private NicDao _nicDao = null;
@Inject
private NicSecondaryIpDao _nicSecondaryIpDao = null;
@Inject
private NicIpAliasDao _nicIpAliasDao = null;
@Inject
private NicDetailsDao _nicDetailsDao = null;
@Inject
private FirewallRulesDao _firewallDao = null;
@Inject
private FirewallRulesCidrsDao _firewallRulesCidrDao = null;
@Inject
private FirewallRuleDetailsDao _firewallRuleDetailsDao = null;
@Inject
private EntityManager _entityMgr = null;
@Inject
private RouterNetworkDao _routerNetworkDao = null;
@Inject
private DomainRouterDao _routerDao = null;
@Inject
private NetworkService _networkService = null;
@Inject
private UserVmDao _vmDao = null;
@Inject
private NetworkModel _networkModel= null;
@Inject
private VMNetworkMapDao _vmNetworkMapDao = null;
@Inject
private HostDao _hostDao = null;
@Inject
private VirtualMachineManager _itMgr = null;
@Inject
private IPAddressDao _ipAddressDao = null;
@Inject
private RulesManager _rulesMgr = null;
@Inject
private VpcDao _vpcDao = null;
@Inject
private VpcDetailsDao _vpcDetailsDao = null;
@Inject
private IpAddressManager _ipAddressManager = null;
@Inject
private VpcService _vpcService = null;
@Inject
private NetworkACLDao _networkACLDao = null;
@Inject
private VpcManager _vpcManager = null;
@Inject
private VpcGatewayDao _vpcGatewayDao = null;
@Inject
private ResourceTagDao _resourceTagDao = null;
@Override public long makeCopyOfNetwork(Network network, NetworkOffering networkOffering, Long vpcId) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Making a copy of network with uuid " + network.getUuid() + " and id " + network.getId() + " for migration.");
}
long originalNetworkId = network.getId();
NetworkDomainVO domainNetworkMapByNetworkId = _networkDomainDao.getDomainNetworkMapByNetworkId(originalNetworkId);
AccountVO networkAccount = _accountDao.findById(network.getAccountId());
boolean subdomainAccess = true;
if (domainNetworkMapByNetworkId != null) {
subdomainAccess = domainNetworkMapByNetworkId.isSubdomainAccess();
}
DataCenterDeployment plan = new DataCenterDeployment(network.getDataCenterId(), null, null, null, null, network.getPhysicalNetworkId());
List<? extends Network> networks = _networkMgr.setupNetwork(networkAccount, networkOffering, network, plan, network.getName(), network.getDisplayText(), true,
network.getDomainId(), network.getAclType(), subdomainAccess,
vpcId, true);
_resourceLimitMgr.incrementResourceCount(network.getAccountId(), Resource.ResourceType.network, network.isDisplay());
long networkCopyId;
if (networks == null || networks.isEmpty()) {
throw new CloudRuntimeException("Fail to create a network");
} else {
DataCenter zone = _dcDao.findById(network.getDataCenterId());
String guestNetworkCidr = zone.getGuestNetworkCidr();
if (networks.get(0).getGuestType() == Network.GuestType.Isolated
&& networks.get(0).getTrafficType() == Networks.TrafficType.Guest) {
Network networkCopy = networks.get(0);
for (final Network nw : networks) {
if (nw.getCidr() != null && nw.getCidr().equals(guestNetworkCidr)) {
networkCopy = nw;
}
}
networkCopyId = networkCopy.getId();
} else {
// For shared network
networkCopyId = networks.get(0).getId();
}
}
//Update the related network
NetworkVO originalNetwork = _networksDao.findById(originalNetworkId);
originalNetwork.setRelated(networkCopyId);
_networksDao.update(originalNetworkId, originalNetwork);
NetworkVO copiedNetwork = _networksDao.findById(networkCopyId);
copiedNetwork.setRelated(originalNetworkId);
copiedNetwork.setDisplayNetwork(false);
copiedNetwork.setBroadcastUri(network.getBroadcastUri());
copiedNetwork.setState(network.getState());
_networksDao.update(networkCopyId, copiedNetwork);
copyNetworkDetails(originalNetworkId, networkCopyId);
copyFirewallRulesToNewNetwork(network, networkCopyId);
assignUserNicsToNewNetwork(originalNetworkId, networkCopyId);
assignRouterNicsToNewNetwork(network.getId(), networkCopyId);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Succesfully created a copy of network " + originalNetwork.getName() + "(" + originalNetwork.getUuid() + ") id is " + originalNetwork.getId() + " for migration. The network copy has uuid " + network.getUuid() + " and id " + network.getId());
}
return networkCopyId;
}
@DB
private void copyNetworkDetails(long srcNetworkId, long dstNetworkId) {
List<NetworkDetailVO> networkDetails = _networkDetailsDao.listDetails(srcNetworkId);
for (NetworkDetailVO networkDetail : networkDetails) {
_networkDetailsDao.persist(new NetworkDetailVO(dstNetworkId, networkDetail.getName(), networkDetail.getValue(), networkDetail.isDisplay()));
}
}
/**
* reassigns the nics to the new network from the src network.
* @param srcNetworkId
* @param dstNetworkId
*/
private void assignUserNicsToNewNetwork(long srcNetworkId, long dstNetworkId) {
List<NicVO> nics = _nicDao.listByNetworkId(srcNetworkId);
for (NicVO nic : nics) {
if (nic.getVmType() == VirtualMachine.Type.User) {
nic.setNetworkId(dstNetworkId);
_nicDao.persist(nic);
//update the number of active nics in both networks after migration.
if (nic.getState() == Nic.State.Reserved) {
_networksDao.changeActiveNicsBy(srcNetworkId, -1);
_networksDao.changeActiveNicsBy(dstNetworkId, 1);
}
}
}
List<? extends IPAddressVO> publicIps = _ipAddressDao.listByAssociatedNetwork(srcNetworkId, null);
for (IPAddressVO ipAddress : publicIps) {
ipAddress.setAssociatedWithNetworkId(dstNetworkId);
_ipAddressDao.persist(ipAddress);
}
}
@Override
public Long makeCopyOfVpc(long vpcId, long vpcOfferingId) {
VpcVO vpc = _vpcDao.findById(vpcId);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Making a copy of vpc with uuid " + vpc.getUuid() + " and id " + vpc.getId() + " for migration.");
}
if (vpc == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Specified vpc id doesn't exist in the system");
ex.addProxyObject(String.valueOf(vpcId), "vpcId");
throw ex;
}
Vpc copyOfVpc;
long copyOfVpcId;
try {
copyOfVpc = _vpcService.createVpc(vpc.getZoneId(), vpcOfferingId, vpc.getAccountId(), vpc.getName(), vpc.getDisplayText(), vpc.getCidr(),
vpc.getNetworkDomain(), vpc.isDisplay());
copyOfVpcId = copyOfVpc.getId();
//on resume of migration the uuid will be swapped already. So the copy will have the value of the original vpcid.
_resourceTagDao.persist(new ResourceTagVO(MIGRATION, Long.toString(vpcId), vpc.getAccountId(), vpc.getDomainId(), copyOfVpcId, ResourceTag.ResourceObjectType.Vpc, null, vpc.getUuid()));
VpcVO copyVpcVO = _vpcDao.findById(copyOfVpcId);
vpc.setDisplay(false);
swapUuids(vpc, copyVpcVO);
reassignACLRulesToNewVpc(vpcId, copyOfVpcId);
reassignPublicIpsToNewVpc(vpcId, copyOfVpc);
copyVpcDetails(vpcId, copyOfVpcId);
reassignGatewayToNewVpc(vpcId, copyOfVpcId);
copyVpcResourceTagsToNewVpc(vpcId, copyOfVpcId);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Succesfully created a copy of network " + vpc.getName() + "(" + vpc.getUuid() + ") id is " + vpc.getId() + " for migration. The network copy has uuid " + copyVpcVO.getUuid() + " and id " + copyOfVpc.getId());
}
} catch (ResourceAllocationException e) {
throw new CloudRuntimeException(e.getMessage());
}
return copyOfVpcId;
}
@Override
public void startVpc(Vpc vpc) {
if (vpc.getState() != Vpc.State.Enabled) {
try {
_vpcService.startVpc(vpc.getId(), true);
} catch (ResourceUnavailableException | InsufficientCapacityException e) {
s_logger.error("Vpc can not be started. Aborting migration process");
throw new CloudRuntimeException("Vpc can not be started.", e);
}
}
}
private void copyVpcDetails(long srcVpcId, long dstVpcId) {
List<VpcDetailVO> vpcDetails = _vpcDetailsDao.listDetails(srcVpcId);
for (VpcDetailVO vpcDetail : vpcDetails) {
_vpcDetailsDao.persist(new VpcDetailVO(dstVpcId, vpcDetail.getName(), vpcDetail.getValue(), vpcDetail.isDisplay()));
}
}
/**
* Reassign the ACL rules from the original vpc to the new VPC
* @param srcVpcId
* @param dstVpcId
*/
private void reassignACLRulesToNewVpc(long srcVpcId, long dstVpcId){
List<NetworkACLVO> networkACL = _networkACLDao.listByVpcId(srcVpcId);
for (NetworkACLVO aclList : networkACL) {
aclList.setVpcId(dstVpcId);
_networkACLDao.persist(aclList);
}
}
private void reassignPublicIpsToNewVpc(long srcVpcId, Vpc dstVpc) {
List<? extends IPAddressVO> publicIps = _ipAddressDao.listByAssociatedVpc(srcVpcId, _vpcManager.isSrcNatIpRequired(dstVpc.getVpcOfferingId()) ? null : false);
for(IPAddressVO publicIp : publicIps) {
publicIp.setVpcId(dstVpc.getId());
_ipAddressDao.persist(publicIp);
}
}
private void reassignGatewayToNewVpc(long srcVpcId, long dstVpcId){
List<VpcGatewayVO> vpcGateways = _vpcGatewayDao.listByVpcId(srcVpcId);
for (VpcGatewayVO vpcGateway : vpcGateways) {
vpcGateway.setVpcId(dstVpcId);
_vpcGatewayDao.persist(vpcGateway);
}
}
private void copyVpcResourceTagsToNewVpc(long srcVpcId, long dstVpcId){
List<? extends ResourceTag> resourceTags = _resourceTagDao.listBy(srcVpcId, ResourceTag.ResourceObjectType.Vpc);
for (ResourceTag resourceTag : resourceTags) {
resourceTag.setResourceId(dstVpcId);
_resourceTagDao.persist(
new ResourceTagVO(
resourceTag.getKey(),
resourceTag.getValue(),
resourceTag.getAccountId(),
resourceTag.getDomainId(),
dstVpcId,
resourceTag.getResourceType(),
resourceTag.getCustomer(),
resourceTag.getResourceUuid()));
}
}
private void copyFirewallRulesToNewNetwork(Network srcNetwork, long dstNetworkId) {
List<FirewallRuleVO> firewallRules = _firewallDao.listByNetworkPurposeTrafficType(srcNetwork.getId(), FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress);
firewallRules.addAll(_firewallDao.listByNetworkPurposeTrafficType(srcNetwork.getId(), FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Ingress));
if (s_logger.isDebugEnabled()) {
s_logger.debug("Copying firewall rules from network with id " + srcNetwork.getId() + " to network with id " + dstNetworkId);
}
//Loop over all the firewall rules in the original network and copy all values to a new firewall rule
//Copy all objects that are dependant on the firewall rules
for (FirewallRuleVO originalFirewallRule : firewallRules) {
FirewallRuleVO ruleVO = new FirewallRuleVO(originalFirewallRule.getXid(),
originalFirewallRule.getSourceIpAddressId(),
originalFirewallRule.getSourcePortStart(),
originalFirewallRule.getSourcePortEnd(),
originalFirewallRule.getProtocol(),
dstNetworkId,
srcNetwork.getAccountId(),
srcNetwork.getDomainId(),
originalFirewallRule.getPurpose(),
originalFirewallRule.getSourceCidrList(),
originalFirewallRule.getDestinationCidrList(),
originalFirewallRule.getIcmpCode(),
originalFirewallRule.getIcmpType(),
originalFirewallRule.getRelated(),
originalFirewallRule.getTrafficType(),
originalFirewallRule.getType());
ruleVO = _firewallDao.persist(ruleVO);
//Firewall rule cidrs
List<FirewallRulesCidrsVO> firewallRulesCidrsVOS = _firewallRulesCidrDao.listByFirewallRuleId(originalFirewallRule.getId());
for (FirewallRulesCidrsVO firewallRulesCidrVO: firewallRulesCidrsVOS) {
_firewallRulesCidrDao.persist(new FirewallRulesCidrsVO(ruleVO.getId(), firewallRulesCidrVO.getSourceCidrList()));
}
//Firewall rules details
List<FirewallRuleDetailVO> originalFirewallRuleDetails = _firewallRuleDetailsDao.listDetails(originalFirewallRule.getId());
for (FirewallRuleDetailVO originalFirewallRuleDetail : originalFirewallRuleDetails) {
_firewallRuleDetailsDao.persist(new FirewallRuleDetailVO(ruleVO.getId(), originalFirewallRuleDetail.getName(), originalFirewallRuleDetail.getValue(), originalFirewallRuleDetail.isDisplay()));
}
}
}
private void assignRouterNicsToNewNetwork(long srcNetworkId, long dstNetworkId) {
final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(srcNetworkId, VirtualRouter.Role.VIRTUAL_ROUTER);
for (DomainRouterVO domainRouter : routers) {
NicVO vrNic = _nicDao.findByNetworkIdAndType(srcNetworkId, VirtualMachine.Type.DomainRouter);
vrNic.setNetworkId(dstNetworkId);
_nicDao.update(vrNic.getId(), vrNic);
RouterNetworkVO routerNetwork = _routerNetworkDao.findByRouterAndNetwork(domainRouter.getId(), srcNetworkId);
routerNetwork.setNetworkId(dstNetworkId);
_routerNetworkDao.persist(routerNetwork);
}
}
@Override
public Network upgradeNetworkToNewNetworkOffering(long networkId, long newPhysicalNetworkId, long networkOfferingId, Long vpcId) {
s_logger.debug("upgrading network to network with new offering.");
NetworkVO network = _networksDao.findById(networkId);
NetworkOffering newOffering = _networkOfferingDao.findByIdIncludingRemoved(networkOfferingId);
long gurusImplementing = 0;
network.setBroadcastUri(null);
AccountVO networkAccount = _accountDao.findById(network.getAccountId());
DataCenterDeployment plan = new DataCenterDeployment(network.getDataCenterId(), null, null, null, null, newPhysicalNetworkId);
for (final NetworkGuru guru : _networkMgr.getNetworkGurus()) {
final Network designedNetwork = guru.design(newOffering, plan, network, networkAccount);
if (designedNetwork == null) {
continue;
}
gurusImplementing++;
if (gurusImplementing > 1) {
throw new CloudRuntimeException("Failed to migrate network to new physical network. Multiple network guru's for the same network are currently not supported.");
}
network.setTrafficType(designedNetwork.getTrafficType());
network.setMode(designedNetwork.getMode());
network.setBroadcastDomainType(designedNetwork.getBroadcastDomainType());
network.setBroadcastUri(designedNetwork.getBroadcastUri());
network.setNetworkOfferingId(designedNetwork.getNetworkOfferingId());
network.setState(designedNetwork.getState());
network.setPhysicalNetworkId(designedNetwork.getPhysicalNetworkId());
network.setRedundant(designedNetwork.isRedundant());
network.setGateway(designedNetwork.getGateway());
network.setCidr(designedNetwork.getCidr());
network.setGuruName(guru.getName());
network.setVpcId(vpcId);
}
_networksDao.update(network.getId(), network, _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), newPhysicalNetworkId));
return network;
}
@Override
public void deleteCopyOfNetwork(long networkCopyId, long originalNetworkId) {
NetworkVO networkCopy = _networksDao.findById(networkCopyId);
NicVO userNic = _nicDao.findByNetworkIdAndType(networkCopyId, VirtualMachine.Type.User);
if (userNic != null) {
s_logger.error("Something went wrong while migrating nics from the old network to the new network. Failed to delete copy of network. There are still user nics present in the network.");
throw new CloudRuntimeException("Failed to delete copy of network. There are still user nics present in the network.");
}
NetworkVO originalNetwork = _networksDao.findById(originalNetworkId);
swapUuids(originalNetwork, networkCopy);
try {
if (!_networkService.deleteNetwork(networkCopy.getId(), true)) {
throw new CloudRuntimeException("Failed to delete network. Clean up not successful.");
}
} finally {
swapUuids(networkCopy, originalNetwork);
}
originalNetwork.setRelated(originalNetworkId);
_networksDao.persist(originalNetwork);
}
@Override
public void deleteCopyOfVpc(long vpcCopyId, long originalVpcId) {
VpcVO copyOfvpc = _vpcDao.findById(vpcCopyId);
VpcVO originalVpc = _vpcDao.findById(originalVpcId);
//Be sure that when we delete the vpc, it has the uuid with what it was created.
swapUuids(copyOfvpc, originalVpc);
try {
if(!_vpcService.deleteVpc(vpcCopyId)) {
throw new CloudRuntimeException("Deletion of VPC failed. Clean up was not successful.");
}
} catch (ResourceUnavailableException e) {
throw new CloudRuntimeException(e.getMessage());
} finally {
swapUuids(originalVpc, copyOfvpc);
}
_resourceTagDao.removeByResourceIdAndKey(originalVpcId, ResourceTag.ResourceObjectType.Vpc, MIGRATION);
}
private Boolean migrateNicsInDB(NicVO originalNic, Network networkInNewPhysicalNet, DataCenter dc, ReservationContext context) {
s_logger.debug("migrating nics in database.");
UserVmVO vmVO = _vmDao.findById(originalNic.getInstanceId());
VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmVO, null, null, null, null);
NicProfile nicProfile = new NicProfile(originalNic, networkInNewPhysicalNet, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(networkInNewPhysicalNet), null);
try {
nicProfile = _networkMgr.allocateNic(nicProfile, networkInNewPhysicalNet, originalNic.isDefaultNic(), nicProfile.getDeviceId(), vmProfile).first();
} catch (InsufficientVirtualNetworkCapacityException | InsufficientAddressCapacityException e) {
throw new CloudRuntimeException("Allocation of new nicProfile failed during migration", e);
}
//Update vm_network_map table
if (vmProfile.getType() == VirtualMachine.Type.User) {
final VMNetworkMapVO vno = new VMNetworkMapVO(vmVO.getId(), networkInNewPhysicalNet.getId());
_vmNetworkMapDao.persist(vno);
}
NicVO newNic = _nicDao.findById(nicProfile.getId());
copyNicDetails(originalNic.getId(), newNic.getId());
//Update nic uuid here
moveServices(originalNic, newNic);
if (originalNic.getState() == Nic.State.Reserved) {
final VirtualMachine vm = vmProfile.getVirtualMachine();
final Host host = _hostDao.findById(vm.getHostId());
final DeployDestination dest = new DeployDestination(dc, null, null, host);
try {
nicProfile = _networkMgr.prepareNic(vmProfile, dest, context, nicProfile.getId(), networkInNewPhysicalNet);
_itMgr.replugNic(networkInNewPhysicalNet, _itMgr.toNicTO(nicProfile, host.getHypervisorType()), _itMgr.toVmTO(vmProfile), context, dest);
} catch (ResourceUnavailableException | InsufficientCapacityException e) {
throw new CloudRuntimeException("Migration of Nic failed", e);
}
}
//Mark the old nic as removed
markAsNonDefault(originalNic);
_networkMgr.removeNic(vmProfile, originalNic);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Nic is migrated successfully for vm " + vmVO + " to " + networkInNewPhysicalNet);
}
return true;
}
@Override
public void assignNicsToNewPhysicalNetwork(Network srcNetwork, Network networkInNewPhysicalNet) {
List<NicVO> nics = _nicDao.listByNetworkId(srcNetwork.getId());
final CallContext cctx = CallContext.current();
final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
final DataCenter dc = _entityMgr.findById(DataCenter.class, networkInNewPhysicalNet.getDataCenterId());
//For each nic in the old network check if the nic belongs to a guest vm and migrate it to the new network.
for (NicVO originalNic : nics) {
if (originalNic.getVmType() != VirtualMachine.Type.User) {
continue;
}
Transaction.execute((TransactionCallback<Boolean>)
(status) -> migrateNicsInDB(originalNic, networkInNewPhysicalNet, dc, context));
}
//Now that nics are migrated we can migrate the static nats on those nics
reapplyPublicIps(srcNetwork, networkInNewPhysicalNet);
}
private void reapplyPublicIps(Network networkInOldPhysicalNetwork, Network networkInNewPhysicalNet) {
CallContext ctx = CallContext.current();
long callerUserId = ctx.getCallingUserId();
Account caller = ctx.getCallingAccount();
AccountVO networkAccount = _accountDao.findById(networkInNewPhysicalNet.getAccountId());
List<? extends IPAddressVO> staticNatIps = _ipAddressDao.listStaticNatPublicIps(networkInOldPhysicalNetwork.getId());
List<String> providers = _networkOfferingServiceDao.listProvidersForServiceForNetworkOffering(networkInNewPhysicalNet.getNetworkOfferingId(), Network.Service.SourceNat);
boolean isSrcNatIpNeeded = providers.stream().anyMatch(provider -> provider.contains(Network.Provider.VirtualRouter.getName()));
for (IPAddressVO ipAddress : staticNatIps) {
if (!ipAddress.isSourceNat() || isSrcNatIpNeeded) {
ipAddress.setAssociatedWithNetworkId(networkInNewPhysicalNet.getId());
_ipAddressDao.persist(ipAddress);
} else {
_ipAddressManager.disassociatePublicIpAddress(ipAddress.getId(), callerUserId, caller);
}
}
_rulesMgr.applyStaticNatsForNetwork(networkInNewPhysicalNet.getId(), false, networkAccount);
}
private void copyNicDetails(long originalNicId, long dstNicId) {
List<NicDetailVO> nicDetails = _nicDetailsDao.listDetails(originalNicId);
for (NicDetailVO nicDetail : nicDetails) {
_nicDetailsDao.persist(new NicDetailVO(dstNicId, nicDetail.getName(), nicDetail.getValue(), nicDetail.isDisplay()));
}
}
private void moveServices(NicVO originalNic, NicVO newNic) {
_nicIpAliasDao.moveIpAliases(originalNic.getId(), newNic.getId());
_nicSecondaryIpDao.moveSecondaryIps(originalNic.getId(), newNic.getId());
swapUuids(originalNic, newNic);
}
private void markAsNonDefault(NicVO nic) {
nic.setDefaultNic(false);
_nicDao.persist(nic);
}
/**
* Swaps the UUID's of the given nics's
* @param oldNic
* @param newNic
*/
private void swapUuids(NicVO oldNic, NicVO newNic) {
final String realUuid = oldNic.getUuid();
final String dummyUuid = newNic.getUuid();
oldNic.setUuid(dummyUuid.replace("-", "+"));
newNic.setUuid(realUuid);
_nicDao.persist(oldNic);
_nicDao.persist(newNic);
oldNic.setUuid(dummyUuid);
_nicDao.persist(oldNic);
}
/**
* Swaps the UUID's of the given networks
* @param oldNetwork
* @param newNetwork
*/
private void swapUuids(NetworkVO oldNetwork, NetworkVO newNetwork) {
String realUuid = oldNetwork.getUuid();
String dummyUuid = newNetwork.getUuid();
oldNetwork.setUuid(dummyUuid.replace("-","+"));
newNetwork.setUuid(realUuid);
_networksDao.update(oldNetwork.getId(), oldNetwork);
_networksDao.update(newNetwork.getId(), newNetwork);
oldNetwork.setUuid(dummyUuid);
_networksDao.update(oldNetwork.getId(), oldNetwork);
}
/**
* Swaps the UUID's of the given vpcs
* @param oldVpc
* @param newVpc
*/
private void swapUuids(VpcVO oldVpc, VpcVO newVpc) {
String realUuid = oldVpc.getUuid();
String dummyUuid = newVpc.getUuid();
oldVpc.setUuid(dummyUuid.replace("-","+"));
newVpc.setUuid(realUuid);
_vpcDao.update(oldVpc.getId(), oldVpc);
_vpcDao.update(newVpc.getId(), newVpc);
oldVpc.setUuid(dummyUuid);
_vpcDao.update(oldVpc.getId(), oldVpc);
}
}

View File

@ -34,13 +34,14 @@ import java.util.Collections;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
import com.cloud.configuration.Config;
@ -100,7 +101,6 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.projects.dao.ProjectAccountDao;
import com.cloud.server.ConfigurationServer;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
@ -146,23 +146,18 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
AccountManager _accountMgr;
@Inject
ConfigurationDao _configDao;
@Inject
ConfigurationManager _configMgr;
@Inject
NetworkOfferingDao _networkOfferingDao = null;
@Inject
NetworkDao _networksDao = null;
@Inject
NicDao _nicDao = null;
@Inject
PodVlanMapDao _podVlanMapDao;
@Inject
ConfigurationServer _configServer;
List<NetworkElement> networkElements;
private List<NetworkElement> networkElements;
public List<NetworkElement> getNetworkElements() {
return networkElements;

View File

@ -33,12 +33,12 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.ApiConstants;
@ -58,7 +58,6 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.PublishScope;
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
import com.cloud.configuration.Config;
@ -70,10 +69,8 @@ import com.cloud.dc.DataCenterVO;
import com.cloud.dc.DataCenterVnetVO;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterVnetDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.Domain;
@ -82,8 +79,6 @@ import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils;
import com.cloud.event.dao.EventDao;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
@ -108,7 +103,6 @@ import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkDetailVO;
import com.cloud.network.dao.NetworkDetailsDao;
@ -128,7 +122,6 @@ import com.cloud.network.element.OvsProviderVO;
import com.cloud.network.element.VirtualRouterElement;
import com.cloud.network.element.VpcVirtualRouterElement;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.lb.LoadBalancingRulesService;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.rules.RulesManager;
@ -141,6 +134,7 @@ import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpc.dao.NetworkACLDao;
import com.cloud.network.vpc.dao.PrivateIpDao;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
@ -148,11 +142,13 @@ import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.org.Grouping;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectManager;
import com.cloud.server.ResourceTag;
import com.cloud.server.ResourceTag.ResourceObjectType;
import com.cloud.tags.ResourceTagVO;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountService;
import com.cloud.user.AccountVO;
import com.cloud.user.DomainManager;
import com.cloud.user.ResourceLimitService;
@ -191,7 +187,6 @@ import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.NicSecondaryIpVO;
@ -227,19 +222,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
@Inject
UserDao _userDao = null;
@Inject
EventDao _eventDao = null;
@Inject
ConfigurationDao _configDao;
@Inject
UserVmDao _userVmDao = null;
@Inject
AccountManager _accountMgr;
@Inject
ConfigurationManager _configMgr;
@Inject
AccountVlanMapDao _accountVlanMapDao;
@Inject
NetworkOfferingDao _networkOfferingDao = null;
@Inject
NetworkDao _networksDao = null;
@ -247,23 +237,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
NicDao _nicDao = null;
@Inject
RulesManager _rulesMgr;
@Inject
UsageEventDao _usageEventDao;
List<NetworkGuru> _networkGurus;
@Inject
NetworkDomainDao _networkDomainDao;
@Inject
VMInstanceDao _vmDao;
@Inject
FirewallRulesDao _firewallDao;
@Inject
ResourceLimitService _resourceLimitMgr;
@Inject
DomainManager _domainMgr;
@Inject
@ -274,10 +256,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
PhysicalNetworkDao _physicalNetworkDao;
@Inject
PhysicalNetworkServiceProviderDao _pNSPDao;
@Inject
PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
@Inject
NetworkServiceMapDao _ntwkSrvcDao;
@Inject
@ -292,17 +272,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
NetworkOrchestrationService _networkMgr;
@Inject
NetworkModel _networkModel;
@Inject
NicSecondaryIpDao _nicSecondaryIpDao;
@Inject
PortForwardingRulesDao _portForwardingDao;
@Inject
HostDao _hostDao;
@Inject
HostPodDao _hostPodDao;
@Inject
InternalLoadBalancerElementService _internalLbElementSvc;
@Inject
DataCenterVnetDao _datacneterVnet;
@ -318,26 +294,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
IpAddressManager _ipAddrMgr;
@Inject
EntityManager _entityMgr;
@Inject
LoadBalancerVMMapDao _lbVmMapDao;
@Inject
LoadBalancingRulesService _lbService;
@Inject
public SecurityGroupService _securityGroupService;
@Inject
MessageBus _messageBus;
@Inject
DomainRouterDao _routerDao;
@Inject
NetworkDetailsDao _networkDetailsDao;
@Inject
LoadBalancerDao _loadBalancerDao;
@Inject
NetworkMigrationManager _networkMigrationManager;
@Inject
VpcOfferingDao _vpcOfferingDao;
@Inject
AccountService _accountService;
int _cidrLimit;
boolean _allowSubdomainNetworkAccess;
@ -947,9 +917,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// don't allow releasing system ip address
if (ipVO.getSystem()) {
InvalidParameterValueException ex = new InvalidParameterValueException("Can't release system IP address with specified id");
ex.addProxyObject(ipVO.getUuid(), "systemIpAddrId");
throw ex;
throwInvalidIdException("Can't release system IP address with specified id", ipVO.getUuid(), "systemIpAddrId");
}
boolean success = _ipAddrMgr.disassociatePublicIpAddress(ipAddressId, userId, caller);
@ -1319,9 +1287,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// Can add vlan range only to the network which allows it
if (createVlan && !ntwkOff.getSpecifyIpRanges()) {
InvalidParameterValueException ex = new InvalidParameterValueException("Network offering with specified id doesn't support adding multiple ip ranges");
ex.addProxyObject(ntwkOff.getUuid(), "networkOfferingId");
throw ex;
throwInvalidIdException("Network offering with specified id doesn't support adding multiple ip ranges", ntwkOff.getUuid(), "networkOfferingId");
}
Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId, domainId,
@ -1521,9 +1487,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
// getProject() returns type ProjectVO.
InvalidParameterValueException ex = new InvalidParameterValueException("Account " + caller + " cannot access specified project id");
ex.addProxyObject(project.getUuid(), "projectId");
throw ex;
throwInvalidIdException("Account " + caller + " cannot access specified project id", project.getUuid(), "projectId");
}
//add project account
@ -1847,16 +1811,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (network == null) {
// see NetworkVO.java
InvalidParameterValueException ex = new InvalidParameterValueException("unable to find network with specified id");
ex.addProxyObject(String.valueOf(networkId), "networkId");
throw ex;
throwInvalidIdException("unable to find network with specified id", String.valueOf(networkId), "networkId");
}
// don't allow to delete system network
if (isNetworkSystem(network)) {
InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id is system and can't be removed");
ex.addProxyObject(network.getUuid(), "networkId");
throw ex;
throwInvalidIdException("Network with specified id is system and can't be removed", network.getUuid(), "networkId");
}
Account owner = _accountMgr.getAccount(network.getAccountId());
@ -1891,9 +1851,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// Check if network exists
NetworkVO network = _networksDao.findById(networkId);
if (network == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id doesn't exist");
ex.addProxyObject(networkId.toString(), "networkId");
throw ex;
throwInvalidIdException("Network with specified id doesn't exist", networkId.toString(), "networkId");
}
// Don't allow to restart network if it's not in Implemented/Setup state
@ -2019,9 +1977,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
final NetworkVO network = _networksDao.findById(networkId);
if (network == null) {
// see NetworkVO.java
InvalidParameterValueException ex = new InvalidParameterValueException("Specified network id doesn't exist in the system");
ex.addProxyObject(String.valueOf(networkId), "networkId");
throw ex;
throwInvalidIdException("Specified network id doesn't exist in the system", String.valueOf(networkId), "networkId");
}
//perform below validation if the network is vpc network
@ -2083,17 +2039,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
if (networkOfferingId != null) {
if (networkOffering == null || networkOffering.isSystemOnly()) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering with specified id");
ex.addProxyObject(networkOfferingId.toString(), "networkOfferingId");
throw ex;
throwInvalidIdException("Unable to find network offering with specified id", networkOfferingId.toString(), "networkOfferingId");
}
// network offering should be in Enabled state
if (networkOffering.getState() != NetworkOffering.State.Enabled) {
InvalidParameterValueException ex = new InvalidParameterValueException("Network offering with specified id is not in " + NetworkOffering.State.Enabled
+ " state, can't upgrade to it");
ex.addProxyObject(networkOffering.getUuid(), "networkOfferingId");
throw ex;
throwInvalidIdException("Network offering with specified id is not in " + NetworkOffering.State.Enabled
+ " state, can't upgrade to it", networkOffering.getUuid(), "networkOfferingId");
}
//can't update from vpc to non-vpc network offering
boolean forVpcNew = _configMgr.isOfferingForVpc(networkOffering);
@ -2112,9 +2064,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
if (changeCidr) {
if (!checkForNonStoppedVmInNetwork(network.getId())) {
InvalidParameterValueException ex = new InvalidParameterValueException("All user vm of network of specified id should be stopped before changing CIDR!");
ex.addProxyObject(network.getUuid(), "networkId");
throw ex;
throwInvalidIdException("All user vm of network of specified id should be stopped before changing CIDR!", network.getUuid(), "networkId");
}
}
// check if the network is upgradable
@ -2171,7 +2121,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (network.getGuestType() != GuestType.Isolated) {
throw new InvalidParameterValueException("Can only allow IP Reservation in networks with guest type " + GuestType.Isolated);
}
if (networkOfferingChanged == true) {
if (networkOfferingChanged) {
throw new InvalidParameterValueException("Cannot specify this nework offering change and guestVmCidr at same time. Specify only one.");
}
if (!(network.getState() == Network.State.Implemented)) {
@ -2214,12 +2164,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
for (NicVO nic : nicsPresent) {
long nicIp = NetUtils.ip2Long(nic.getIPv4Address());
//check if nic IP is outside the guest vm cidr
if (nicIp < startIp || nicIp > endIp) {
if (!(nic.getState() == Nic.State.Deallocating)) {
if ((nicIp < startIp || nicIp > endIp) && nic.getState() != Nic.State.Deallocating) {
throw new InvalidParameterValueException("Active IPs like " + nic.getIPv4Address() + " exist outside the Guest VM CIDR. Cannot apply reservation ");
}
}
}
}
// In some scenarios even though guesVmCidr and network CIDR do not appear similar but
// the IP ranges exactly matches, in these special cases make sure no Reservation gets applied
@ -2259,7 +2207,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// 1) Shutdown all the elements and cleanup all the rules. Don't allow to shutdown network in intermediate
// states - Shutdown and Implementing
int resourceCount=1;
if(updateInSequence && restartNetwork && _networkOfferingDao.findById(network.getNetworkOfferingId()).getRedundantRouter()
if (updateInSequence && restartNetwork && _networkOfferingDao.findById(network.getNetworkOfferingId()).getRedundantRouter()
&& (networkOfferingId==null || _networkOfferingDao.findById(networkOfferingId).getRedundantRouter()) && network.getVpcId()==null) {
_networkMgr.canUpdateInSequence(network, forced);
NetworkDetailVO networkDetail =new NetworkDetailVO(network.getId(),Network.updatingInSequence,"true",true);
@ -2268,19 +2216,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
resourceCount=_networkMgr.getResourceCount(network);
}
List<String > servicesNotInNewOffering = null;
if(networkOfferingId != null)
servicesNotInNewOffering = _networkMgr.getServicesNotSupportedInNewOffering(network,networkOfferingId);
if(!forced && servicesNotInNewOffering != null && !servicesNotInNewOffering.isEmpty()){
if (networkOfferingId != null) {
servicesNotInNewOffering = _networkMgr.getServicesNotSupportedInNewOffering(network, networkOfferingId);
}
if (!forced && servicesNotInNewOffering != null && !servicesNotInNewOffering.isEmpty()) {
NetworkOfferingVO newOffering = _networkOfferingDao.findById(networkOfferingId);
throw new CloudRuntimeException("The new offering:"+newOffering.getUniqueName()
+" will remove the following services "+servicesNotInNewOffering +"along with all the related configuration currently in use. will not proceed with the network update." +
"set forced parameter to true for forcing an update.");
}
try{
if(servicesNotInNewOffering!=null && !servicesNotInNewOffering.isEmpty()){
try {
if (servicesNotInNewOffering!=null && !servicesNotInNewOffering.isEmpty()) {
_networkMgr.cleanupConfigForServicesInNetwork(servicesNotInNewOffering,network);
}
}catch (Throwable e){
} catch (Throwable e) {
s_logger.debug("failed to cleanup config related to unused services error:"+e.getMessage());
}
@ -2411,13 +2360,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
}
resourceCount--;
} while(updateInSequence && resourceCount>0);
}catch (Exception exception){
if(updateInSequence)
_networkMgr.finalizeUpdateInSequence(network,false);
} while (updateInSequence && resourceCount>0);
} catch (Exception exception) {
if (updateInSequence) {
_networkMgr.finalizeUpdateInSequence(network, false);
}
throw new CloudRuntimeException("failed to update network "+network.getUuid()+" due to "+exception.getMessage());
}finally {
if(updateInSequence){
} finally {
if (updateInSequence) {
if( _networkDetailsDao.findDetail(networkId,Network.updatingInSequence)!=null){
_networkDetailsDao.removeDetail(networkId,Network.updatingInSequence);
}
@ -2426,74 +2376,357 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
return getNetwork(network.getId());
}
protected Set<Long> getAvailableIps(Network network, String requestedIp) {
String[] cidr = network.getCidr().split("/");
List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
Set<Long> usedIps = new TreeSet<Long>();
@Override
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_MIGRATE, eventDescription = "migrating network", async = true)
public Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume) {
NetworkVO network = _networksDao.findById(networkId);
NetworkOffering newNtwkOff = _networkOfferingDao.findById(networkOfferingId);
for (String ip : ips) {
if (requestedIp != null && requestedIp.equals(ip)) {
s_logger.warn("Requested ip address " + requestedIp + " is already in use in network" + network);
return null;
}
usedIps.add(NetUtils.ip2Long(ip));
//perform below validation if the network is vpc network
if (network.getVpcId() != null) {
s_logger.warn("Failed to migrate network as the specified network is a vpc tier. Use migrateVpc.");
throw new InvalidParameterValueException("Failed to migrate network as the specified network is a vpc tier. Use migrateVpc.");
}
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps);
String gateway = network.getGateway();
if ((gateway != null) && (allPossibleIps.contains(NetUtils.ip2Long(gateway))))
allPossibleIps.remove(NetUtils.ip2Long(gateway));
if (_configMgr.isOfferingForVpc(newNtwkOff)) {
s_logger.warn("Failed to migrate network as the specified network offering is a VPC offering");
throw new InvalidParameterValueException("Failed to migrate network as the specified network offering is a VPC offering");
}
return allPossibleIps;
verifyNetworkCanBeMigrated(callerAccount, network);
//Retrieve new Physical NetworkId
long newPhysicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
final long oldNetworkOfferingId = network.getNetworkOfferingId();
NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
if (!resume && network.getRelated() != network.getId()) {
s_logger.warn("Related network is not equal to network id. You might want to re-run migration with resume = true command.");
throw new CloudRuntimeException("Failed to migrate network as previous migration left this network in transient condition. Specify resume as true.");
}
if (networkNeedsMigration(network, newPhysicalNetworkId, oldNtwkOff, newNtwkOff)) {
return migrateNetworkToPhysicalNetwork(network, oldNtwkOff, newNtwkOff, null, null, newPhysicalNetworkId, callerAccount, callerUser);
} else {
s_logger.info("Network does not need migration.");
return network;
}
}
protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
private class NetworkCopy {
private Long networkIdInOldPhysicalNet;
private Network networkInNewPhysicalNet;
public NetworkCopy(Long networkIdInOldPhysicalNet, Network networkInNewPhysicalNet) {
this.networkIdInOldPhysicalNet = networkIdInOldPhysicalNet;
this.networkInNewPhysicalNet = networkInNewPhysicalNet;
}
public Long getNetworkIdInOldPhysicalNet() {
return networkIdInOldPhysicalNet;
}
public Network getNetworkInNewPhysicalNet() {
return networkInNewPhysicalNet;
}
}
private Network migrateNetworkToPhysicalNetwork(Network network, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff, Long oldVpcId, Long newVpcId, long newPhysicalNetworkId, Account callerAccount, User callerUser) {
boolean resume = network.getRelated() != network.getId();
NetworkCopy networkCopy;
// Resume is only true when there is already a copy of the network created
if (resume) {
Network networkInNewPhysicalNet = network;
networkCopy = new NetworkCopy(network.getRelated(), networkInNewPhysicalNet);
//the new network could already be implemented, check if the already partially upgrade networks has the same network offering as before or check if it still has the original network offering
//the old network offering uuid should be the one of the already created copy
if (networkInNewPhysicalNet.getNetworkOfferingId() != newNtwkOff.getId()) {
throw new InvalidParameterValueException("Failed to resume migrating network as network offering does not match previously specified network offering (" + newNtwkOff.getUuid() + ")");
}
} else {
networkCopy = Transaction.execute(
(TransactionCallback<NetworkCopy>)
(status) -> migrateNetworkInDb(network, oldNtwkOff, newNtwkOff, oldVpcId, newVpcId, newPhysicalNetworkId));
}
Long networkIdInOldPhysicalNet = networkCopy.getNetworkIdInOldPhysicalNet();
Network networkInNewPhysicalNet = networkCopy.getNetworkInNewPhysicalNet();
ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
DataCenter zone = _dcDao.findById(network.getDataCenterId());
NetworkVO networkInOldPhysNet = _networksDao.findById(networkIdInOldPhysicalNet);
boolean shouldImplement = (newNtwkOff.getIsPersistent()
|| networkInOldPhysNet.getState() == Network.State.Implemented)
&& networkInNewPhysicalNet.getState() != Network.State.Implemented;
if (shouldImplement) {
DeployDestination dest = new DeployDestination(zone, null, null, null);
s_logger.debug("Implementing the network " + network + " elements and resources as a part of network update");
try {
networkInNewPhysicalNet = _networkMgr.implementNetwork(networkInNewPhysicalNet.getId(), dest, context)
.second();
} catch (Exception ex) {
s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex);
CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update");
e.addProxyObject(network.getUuid(), "networkId");
throw e;
}
}
_networkMigrationManager.assignNicsToNewPhysicalNetwork(networkInOldPhysNet, networkInNewPhysicalNet);
//clean up the old copy of the network
_networkMigrationManager.deleteCopyOfNetwork(networkIdInOldPhysicalNet, networkInNewPhysicalNet.getId());
return getNetwork(network.getId());
}
private NetworkCopy migrateNetworkInDb(Network network, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff, Long oldVpcId, Long newVpcId, long newPhysicalNetworkId) {
//The copy will be the network in the old physical network
//And we will use it to store tmp data while we upgrade or original network to the new physical network
Long networkIdInOldPhysicalNet = _networkMigrationManager.makeCopyOfNetwork(network, oldNtwkOff, oldVpcId);
Network networkInNewPhysicalNet = _networkMigrationManager.upgradeNetworkToNewNetworkOffering(network.getId(), newPhysicalNetworkId,newNtwkOff.getId(), newVpcId);
return new NetworkCopy(networkIdInOldPhysicalNet, networkInNewPhysicalNet);
}
@Override
public Vpc migrateVpcNetwork(long vpcId, long vpcOfferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume) {
//Check if a previous migration run failed and try to resume if resume = true
ResourceTag relatedVpc = _resourceTagDao.findByKey(vpcId, ResourceObjectType.Vpc, NetworkMigrationManager.MIGRATION);
long vpcCopyId = 0;
/*
* In the vpc migration process the newly created Vpc will be used as the new VPC (opposed to network tier migration).
* In case the copy of the vpc was already created. The uuid where already swapped and the id we receive here is the id of the Copy!
* The id stored in the resource tag table under the key "migration" is the id of the ORIGINAL vpc!
*/
if (relatedVpc != null) {
if (resume) {
vpcCopyId = vpcId;
vpcId = Long.parseLong(relatedVpc.getValue());
//let's check if the user did not change the vpcoffering opposed to the last failed run.
verifyAlreadyMigratedTiers(vpcCopyId, vpcOfferingId, networkToOffering);
} else {
s_logger.warn("This vpc has a migration row in the resource details table. You might want to re-run migration with resume = true command.");
throw new CloudRuntimeException("Failed to migrate VPC as previous migration left this VPC in transient condition. Specify resume as true.");
}
}
Vpc vpc = _vpcDao.findById(vpcId);
_accountMgr.checkAccess(account, null, true, vpc);
if (vpc.getVpcOfferingId() == vpcOfferingId) {
return vpc;
}
//Try to fail fast, check networks in the VPC and if we can migrate them before proceeding.
List<NetworkVO> tiersInVpc = _networksDao.listByVpc(vpcId);
vpcTiersCanBeMigrated(tiersInVpc, account, networkToOffering, resume);
//In case this is the first time we try to migrate this vpc
if (relatedVpc == null) {
final long vpcIdFinal = vpcId;
vpcCopyId = Transaction.execute((TransactionCallback<Long>)(status) -> _networkMigrationManager.makeCopyOfVpc(vpcIdFinal, vpcOfferingId));
}
Vpc copyOfVpc = _vpcDao.findById(vpcCopyId);
_networkMigrationManager.startVpc(copyOfVpc);
for (Network tier : tiersInVpc) {
String networkOfferingUuid = networkToOffering.get(tier.getUuid());
//UUID may be swapped already with a new uuid due to previous migration failure.
//So we check the related network also in case we don't find the network offering
Long networkId = null;
if (resume && networkOfferingUuid == null) {
tier = _networksDao.findById(tier.getRelated());
networkOfferingUuid = networkToOffering.get(tier.getUuid());
//In this case the tier already exists so we need to get the id of the tier so we can validate correctly
networkId = tier.getId();
}
NetworkOfferingVO newNtwkOff = _networkOfferingDao.findByUuid(networkOfferingUuid);
Account networkAccount = _accountService.getActiveAccountById(tier.getAccountId());
try {
_vpcMgr.validateNtwkOffForNtwkInVpc(networkId, newNtwkOff.getId(), tier.getCidr(), tier.getNetworkDomain(), copyOfVpc, tier.getGateway(), networkAccount, tier.getNetworkACLId());
} catch (InvalidParameterValueException e) {
s_logger.error("Specified network offering can not be used in combination with specified vpc offering. Aborting migration. You can re-run with resume = true and the correct uuid.");
throw e;
}
long newPhysicalNetworkId = findPhysicalNetworkId(tier.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
final long oldNetworkOfferingId = tier.getNetworkOfferingId();
NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
if (networkNeedsMigration(tier, newPhysicalNetworkId, oldNtwkOff, newNtwkOff) || (resume && tier.getRelated() != tier.getId())) {
migrateNetworkToPhysicalNetwork(tier, oldNtwkOff, newNtwkOff, vpcId, vpcCopyId, newPhysicalNetworkId, account, callerUser);
}
}
_networkMigrationManager.deleteCopyOfVpc(vpcId, vpcCopyId);
return _vpcDao.findById(vpcCopyId);
}
private void vpcTiersCanBeMigrated(List<? extends Network> tiersInVpc, Account account, Map<String, String> networkToOffering, boolean resume) {
for (Network network : tiersInVpc) {
String networkOfferingUuid = networkToOffering.get(network.getUuid());
//offering uuid can be a tier where the uuid is previously already swapped in a previous migration
if (resume && networkOfferingUuid == null) {
NetworkVO oldVPCtier = _networksDao.findById(network.getRelated());
networkOfferingUuid = networkToOffering.get(oldVPCtier.getUuid());
}
if (networkOfferingUuid == null) {
throwInvalidIdException("Failed to migrate VPC as the specified tierNetworkOfferings is not complete",
String.valueOf(network.getUuid()), "networkUuid");
}
NetworkOfferingVO newNtwkOff = _networkOfferingDao.findByUuid(networkOfferingUuid);
if (newNtwkOff == null) {
throwInvalidIdException("Failed to migrate VPC as at least one network offering in tierNetworkOfferings does not exist", networkOfferingUuid, "networkOfferingUuid");
}
if (!_configMgr.isOfferingForVpc(newNtwkOff)) {
throw new InvalidParameterValueException("Network offering " + newNtwkOff.getName() + " ("+ newNtwkOff.getUuid() +") can't be used for VPC networks for network " + network.getName() + "(" + network.getUuid() + ")");
}
verifyNetworkCanBeMigrated(account, network);
long newPhysicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
final long oldNetworkOfferingId = network.getNetworkOfferingId();
NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
networkNeedsMigration(network, newPhysicalNetworkId, oldNtwkOff, newNtwkOff);
}
}
private void verifyAlreadyMigratedTiers(long migratedVpcId, long vpcOfferingId, Map<String, String> networkToOffering) {
Vpc migratedVpc = _vpcDao.findById(migratedVpcId);
if (migratedVpc.getVpcOfferingId() != vpcOfferingId) {
s_logger.error("The vpc is already partially migrated in a previous run. The provided vpc offering is not the same as the one used during the first migration process.");
throw new InvalidParameterValueException("Failed to resume migrating VPC as VPC offering does not match previously specified VPC offering (" + migratedVpc.getVpcOfferingId() + ")");
}
List<NetworkVO> migratedTiers = _networksDao.listByVpc(migratedVpcId);
for (Network tier : migratedTiers) {
String tierNetworkOfferingUuid = networkToOffering.get(tier.getUuid());
if (!StringUtils.isNotBlank(tierNetworkOfferingUuid)) {
throwInvalidIdException("Failed to resume migrating VPC as the specified tierNetworkOfferings is not complete",
String.valueOf(tier.getUuid()), "networkUuid");
}
NetworkOfferingVO newNetworkOffering = _networkOfferingDao.findByUuid(tierNetworkOfferingUuid);
if (newNetworkOffering == null) {
throw new InvalidParameterValueException("Failed to migrate VPC as at least one tier offering in tierNetworkOfferings does not exist.");
}
if (newNetworkOffering.getId() != tier.getNetworkOfferingId()) {
NetworkOfferingVO tierNetworkOffering = _networkOfferingDao.findById(tier.getNetworkOfferingId());
throw new InvalidParameterValueException("Failed to resume migrating VPC as at least one network offering in tierNetworkOfferings does not match previously specified network offering (network uuid=" + tier.getUuid() + " was previously specified with offering uuid=" + tierNetworkOffering.getUuid() + ")");
}
}
}
private void throwInvalidIdException(String message, String uuid, String description) {
InvalidParameterValueException ex = new InvalidParameterValueException(message);
ex.addProxyObject(uuid, description);
throw ex;
}
private boolean networkNeedsMigration(Network network, long newPhysicalNetworkId, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff) {
if (newNtwkOff == null || newNtwkOff.isSystemOnly()) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering.");
if (newNtwkOff != null) {
ex.addProxyObject(String.valueOf(newNtwkOff.getId()), "networkOfferingId");
}
throw ex;
}
if (newNtwkOff.getId() != oldNtwkOff.getId() || network.getId() != network.getRelated()) {
Collection<String> newProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(newNtwkOff, newPhysicalNetworkId)
.values();
Collection<String> oldProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(oldNtwkOff, network.getPhysicalNetworkId())
.values();
if (providersConfiguredForExternalNetworking(newProviders) != providersConfiguredForExternalNetworking(oldProviders)) {
throw new InvalidParameterValueException("Updating network failed since guest CIDR needs to be changed!");
}
// check if the network is moveable
if (!canMoveToPhysicalNetwork(network, oldNtwkOff.getId(), newNtwkOff.getId())) {
throw new InvalidParameterValueException(
"Can't upgrade from network offering " + oldNtwkOff.getUuid() + " to " + newNtwkOff.getUuid() + "; check logs for more information");
}
List<VMInstanceVO> vmInstances = _vmDao.listNonRemovedVmsByTypeAndNetwork(network.getId(), null);
boolean vmStateIsNotTransitioning = vmInstances.stream()
.anyMatch(vm -> vm.getState() != VirtualMachine.State.Stopped && vm.getState() != VirtualMachine.State.Running);
if (vmStateIsNotTransitioning) {
throw new CloudRuntimeException("Failed to migrate network as at least one VM is not in running or stopped state.");
}
} else {
return false;
}
// network offering should be in Enabled state
if (newNtwkOff.getState() != NetworkOffering.State.Enabled) {
throw new InvalidParameterValueException("Failed to migrate network as the specified network offering is not enabled.");
}
return true;
}
private void verifyNetworkCanBeMigrated(Account callerAccount, Network network) {
// Don't allow to update system network
NetworkOffering oldOffering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
if (oldOffering.isSystemOnly()) {
throw new InvalidParameterValueException("Failed to migrate network as the specified network is a system network.");
}
// allow to upgrade only Guest networks
if (network.getTrafficType() != TrafficType.Guest) {
throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest);
}
_accountMgr.checkAccess(callerAccount, null, true, network);
boolean validateNetworkReadyToMigrate = (network.getState() == Network.State.Implemented
|| network.getState() == Network.State.Setup
|| network.getState() == Network.State.Allocated);
if (!validateNetworkReadyToMigrate) {
s_logger.error("Failed to migrate network as it is in invalid state.");
CloudRuntimeException ex = new CloudRuntimeException("Failed to migrate network as it is in invalid state.");
ex.addProxyObject(network.getUuid(), "networkId");
throw ex;
}
}
private boolean canMoveToPhysicalNetwork(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId);
// can upgrade only Isolated networks
// can move only Isolated networks for now
if (oldNetworkOffering.getGuestType() != GuestType.Isolated) {
throw new InvalidParameterValueException("NetworkOfferingId can be upgraded only for the network of type " + GuestType.Isolated);
}
// security group service should be the same
if (areServicesSupportedByNetworkOffering(oldNetworkOfferingId, Service.SecurityGroup) != areServicesSupportedByNetworkOffering(newNetworkOfferingId, Service.SecurityGroup)) {
s_logger.debug("Offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different securityGroupProperty, can't upgrade");
return false;
}
// Type of the network should be the same
if (oldNetworkOffering.getGuestType() != newNetworkOffering.getGuestType()) {
s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " are of different types, can't upgrade");
return false;
}
// tags should be the same
if (newNetworkOffering.getTags() != null) {
if (oldNetworkOffering.getTags() == null) {
s_logger.debug("New network offering id=" + newNetworkOfferingId + " has tags and old network offering id=" + oldNetworkOfferingId + " doesn't, can't upgrade");
return false;
}
if (!StringUtils.areTagsEqual(oldNetworkOffering.getTags(), newNetworkOffering.getTags())) {
s_logger.debug("Network offerings " + newNetworkOffering.getUuid() + " and " + oldNetworkOffering.getUuid() + " have different tags, can't upgrade");
return false;
}
}
// Traffic types should be the same
if (oldNetworkOffering.getTrafficType() != newNetworkOffering.getTrafficType()) {
s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different traffic types, can't upgrade");
return false;
}
// specify vlan should be the same
if (oldNetworkOffering.getSpecifyVlan() != newNetworkOffering.getSpecifyVlan()) {
s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyVlan, can't upgrade");
return false;
}
// specify ipRanges should be the same
if (oldNetworkOffering.getSpecifyIpRanges() != newNetworkOffering.getSpecifyIpRanges()) {
s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyIpRangess, can't upgrade");
@ -2525,6 +2758,38 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
return canIpsUseOffering(publicIps, newNetworkOfferingId);
}
protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId);
// security group service should be the same
if (areServicesSupportedByNetworkOffering(oldNetworkOfferingId, Service.SecurityGroup) != areServicesSupportedByNetworkOffering(newNetworkOfferingId, Service.SecurityGroup)) {
s_logger.debug("Offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different securityGroupProperty, can't upgrade");
return false;
}
// tags should be the same
if (newNetworkOffering.getTags() != null) {
if (oldNetworkOffering.getTags() == null) {
s_logger.debug("New network offering id=" + newNetworkOfferingId + " has tags and old network offering id=" + oldNetworkOfferingId + " doesn't, can't upgrade");
return false;
}
if (!StringUtils.areTagsEqual(oldNetworkOffering.getTags(), newNetworkOffering.getTags())) {
s_logger.debug("Network offerings " + newNetworkOffering.getUuid() + " and " + oldNetworkOffering.getUuid() + " have different tags, can't upgrade");
return false;
}
}
// specify vlan should be the same
if (oldNetworkOffering.getSpecifyVlan() != newNetworkOffering.getSpecifyVlan()) {
s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyVlan, can't upgrade");
return false;
}
return canMoveToPhysicalNetwork(network, oldNetworkOfferingId, newNetworkOfferingId);
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", create = true)
@ -2668,17 +2933,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// verify input parameters
PhysicalNetworkVO network = _physicalNetworkDao.findById(id);
if (network == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system");
ex.addProxyObject(id.toString(), "physicalNetworkId");
throw ex;
throwInvalidIdException("Physical Network with specified id doesn't exist in the system", id.toString(), "physicalNetworkId");
}
// if zone is of Basic type, don't allow to add vnet range
DataCenter zone = _dcDao.findById(network.getDataCenterId());
if (zone == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Zone with id=" + network.getDataCenterId() + " doesn't exist in the system");
ex.addProxyObject(String.valueOf(network.getDataCenterId()), "dataCenterId");
throw ex;
throwInvalidIdException("Zone with id=" + network.getDataCenterId() + " doesn't exist in the system", String.valueOf(network.getDataCenterId()), "dataCenterId");
}
if (newVnetRange != null) {
if (zone.getNetworkType() == NetworkType.Basic || (zone.getNetworkType() == NetworkType.Advanced && zone.isSecurityGroupEnabled())) {
@ -2948,9 +3209,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// verify input parameters
PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
if (pNetwork == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system");
ex.addProxyObject(physicalNetworkId.toString(), "physicalNetworkId");
throw ex;
throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
}
checkIfPhysicalNetworkIsDeletable(physicalNetworkId);
@ -3277,9 +3536,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (projectId != null) {
Project project = _projectMgr.getProject(projectId);
if (project == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project by id " + projectId);
ex.addProxyObject(projectId.toString(), "projectId");
throw ex;
throwInvalidIdException("Unable to find project by id " + projectId, projectId.toString(), "projectId");
}
accountId = project.getProjectAccountId();
}
@ -3371,18 +3628,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// verify input parameters
PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
if (network == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system");
ex.addProxyObject(physicalNetworkId.toString(), "physicalNetworkId");
throw ex;
throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
}
// verify input parameters
if (destinationPhysicalNetworkId != null) {
PhysicalNetworkVO destNetwork = _physicalNetworkDao.findById(destinationPhysicalNetworkId);
if (destNetwork == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Destination Physical Network with specified id doesn't exist in the system");
ex.addProxyObject(destinationPhysicalNetworkId.toString(), "destinationPhysicalNetworkId");
throw ex;
throwInvalidIdException("Destination Physical Network with specified id doesn't exist in the system", destinationPhysicalNetworkId.toString(),
"destinationPhysicalNetworkId");
}
}
@ -3836,9 +4090,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
public Pair<List<? extends PhysicalNetworkTrafficType>, Integer> listTrafficTypes(Long physicalNetworkId) {
PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
if (network == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system");
ex.addProxyObject(physicalNetworkId.toString(), "physicalNetworkId");
throw ex;
throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
}
Pair<List<PhysicalNetworkTrafficTypeVO>, Integer> result = _pNTrafficTypeDao.listAndCountBy(physicalNetworkId);
@ -4038,9 +4290,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
// Validate physical network
final PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
if (pNtwk == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a physical network" + " having the given id");
ex.addProxyObject(String.valueOf(physicalNetworkId), "physicalNetworkId");
throw ex;
throwInvalidIdException("Unable to find a physical network" + " having the given id", String.valueOf(physicalNetworkId), "physicalNetworkId");
}
// VALIDATE IP INFO
@ -4152,9 +4402,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
UserVmVO userVm = _userVmDao.findById(vmId);
if (userVm == null || (!userVm.isDisplayVm() && caller.getType() == Account.ACCOUNT_TYPE_NORMAL)) {
InvalidParameterValueException ex = new InvalidParameterValueException("Virtual mahine id does not exist");
ex.addProxyObject(Long.valueOf(vmId).toString(), "vmId");
throw ex;
throwInvalidIdException("Virtual machine id does not exist", Long.valueOf(vmId).toString(), "vmId");
}
_accountMgr.checkAccess(caller, null, true, userVm);
@ -4171,9 +4419,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
UserVmVO userVm = _userVmDao.findById(vmId);
if (userVm == null || (!userVm.isDisplayVm() && caller.getType() == Account.ACCOUNT_TYPE_NORMAL)) {
InvalidParameterValueException ex = new InvalidParameterValueException("Virtual mahine id does not exist");
ex.addProxyObject(Long.valueOf(vmId).toString(), "vmId");
throw ex;
throwInvalidIdException("Virtual machine id does not exist", Long.valueOf(vmId).toString(), "vmId");
}
_accountMgr.checkAccess(caller, null, true, userVm);

View File

@ -867,6 +867,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
// verify permissions
_accountMgr.checkAccess(ctx.getCallingAccount(), null, false, vpc);
_resourceTagDao.removeByIdAndType(vpcId, ResourceObjectType.Vpc);
return destroyVpc(vpc, ctx.getCallingAccount(), ctx.getCallingUserId());
}

View File

@ -125,6 +125,8 @@ import org.apache.cloudstack.api.command.admin.network.ListNetworksCmdByAdmin;
import org.apache.cloudstack.api.command.admin.network.ListPhysicalNetworksCmd;
import org.apache.cloudstack.api.command.admin.network.ListStorageNetworkIpRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListSupportedNetworkServicesCmd;
import org.apache.cloudstack.api.command.admin.network.MigrateNetworkCmd;
import org.apache.cloudstack.api.command.admin.network.MigrateVPCCmd;
import org.apache.cloudstack.api.command.admin.network.ReleaseDedicatedGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.UpdateNetworkCmdByAdmin;
import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
@ -3012,6 +3014,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(UpdateLBHealthCheckPolicyCmd.class);
cmdList.add(GetUploadParamsForTemplateCmd.class);
cmdList.add(GetUploadParamsForVolumeCmd.class);
cmdList.add(MigrateNetworkCmd.class);
cmdList.add(MigrateVPCCmd.class);
cmdList.add(AcquirePodIpCmdByAdmin.class);
cmdList.add(ReleasePodIpCmdByAdmin.class);
cmdList.add(CreateManagementNetworkIpRangeCmd.class);

View File

@ -24,6 +24,8 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.network.vpc.VpcOfferingVO;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.storage.SnapshotPolicyVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.exception.CloudRuntimeException;
@ -127,7 +129,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
s_typeMap.put(ResourceObjectType.LBStickinessPolicy, LBStickinessPolicyVO.class);
s_typeMap.put(ResourceObjectType.LBHealthCheckPolicy, LBHealthCheckPolicyVO.class);
s_typeMap.put(ResourceObjectType.SnapshotPolicy, SnapshotPolicyVO.class);
s_typeMap.put(ResourceObjectType.NetworkOffering, NetworkOfferingVO.class);
s_typeMap.put(ResourceObjectType.VpcOffering, VpcOfferingVO.class);
}
@Inject

View File

@ -24,6 +24,9 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
@ -35,8 +38,6 @@ import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
@ -68,6 +69,7 @@ import com.cloud.network.element.StaticNatServiceProvider;
import com.cloud.network.element.UserDataServiceProvider;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.rules.LoadBalancerContainer.Scheme;
import com.cloud.network.vpc.Vpc;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account;
@ -256,9 +258,18 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
return null;
}
@Override
public Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume) {
return null;
}
@Override public Vpc migrateVpcNetwork(long vpcId, long vpcNetworkofferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume) {
return null;
}
/* (non-Javadoc)
* @see com.cloud.network.NetworkService#createPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.util.List, java.lang.String, java.lang.Long, java.util.List, java.lang.String)
*/
* @see com.cloud.network.NetworkService#createPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.util.List, java.lang.String, java.lang.Long, java.util.List, java.lang.String)
*/
@Override
public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List<String> isolationMethods, String broadcastDomainRange,
Long domainId, List<String> tags, String name) {
@ -899,6 +910,10 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
return 0;
}
@Override public List<NetworkGuru> getNetworkGurus() {
return null;
}
@Override
public void finalizeUpdateInSequence(Network network, boolean success) {
return;

View File

@ -35,6 +35,7 @@ from marvin.lib.base import (Domain,
Router,
ServiceOffering,
StaticNATRule,
ResourceDetails,
VirtualMachine,
VPC,
VpcOffering,
@ -42,15 +43,16 @@ from marvin.lib.base import (Domain,
from marvin.lib.common import (get_domain,
get_template,
get_zone)
from marvin.cloudstackAPI import restartVPC, listNuageUnderlayVlanIpRanges
from marvin.cloudstackAPI import (restartVPC,
listNuageUnderlayVlanIpRanges)
# Import System Modules
from retry import retry
import importlib
import functools
import logging
import socket
import sys
import time
from retry import retry
import sys
from nuage_vsp_statistics import VsdDataCollector
@ -112,6 +114,7 @@ class nuageTestCase(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.debug("setUpClass nuageTestCase")
cls._cleanup = []
# We want to fail quicker, if it's a failure
socket.setdefaulttimeout(60)
@ -139,8 +142,7 @@ class nuageTestCase(cloudstackTestCase):
cls.api_client,
cls.test_data["service_offering"]
)
cls._cleanup = [cls.service_offering]
cls._cleanup.append(cls.service_offering)
cls.debug("setUpClass nuageTestCase [DONE]")
@classmethod
@ -385,7 +387,7 @@ class nuageTestCase(cloudstackTestCase):
@needscleanup
def create_Network(cls, nw_off, gateway="10.1.1.1",
netmask="255.255.255.0", vpc=None, acl_list=None,
testdata=None, account=None):
testdata=None, account=None, vlan=None):
if not account:
account = cls.account
cls.debug("Creating a network in the account - %s" % account.name)
@ -401,6 +403,7 @@ class nuageTestCase(cloudstackTestCase):
networkofferingid=nw_off.id,
zoneid=cls.zone.id,
gateway=gateway,
vlan=vlan,
vpcid=vpc.id if vpc else cls.vpc.id
if hasattr(cls, "vpc") else None,
aclid=acl_list.id if acl_list else None
@ -987,6 +990,23 @@ class nuageTestCase(cloudstackTestCase):
self.debug("Successfully verified the creation and state of Network "
"- %s in VSD" % network.name)
def verify_vsd_network_not_present(self, network, vpc=None):
self.debug("Verifying the creation and state of Network - %s in VSD" %
network.name)
ext_network_filter = self.get_externalID_filter(vpc.id) if vpc \
else self.get_externalID_filter(network.id)
vsd_domain = self.vsd.get_domain(filter=ext_network_filter)
if vsd_domain is None:
return
vsd_zone = self.vsd.get_zone(filter=ext_network_filter)
if vsd_zone is None:
return
vsd_subnet = self.vsd.get_subnet(
filter=self.get_externalID_filter(network.id))
self.assertEqual(vsd_subnet, None, "Network is present on the vsd.")
# get_subnet_id - Calculates and returns the subnet ID in VSD with the
# given CloudStack network ID and subnet gateway
def get_subnet_id(self, network_id, gateway):
@ -1300,3 +1320,21 @@ class nuageTestCase(cloudstackTestCase):
self.debug("Successfully verified the creation and state of Network "
"Firewall (Ingress/Egress ACL) rule with ID - %s in VSD" %
firewall_rule.id)
def add_resource_tag(self, resource_id, resource_type, key, value,
fordisplay=False):
details = {key: value}
return ResourceDetails.create(self.api_client, resourceid=resource_id,
resourcetype=resource_type,
details=details, fordisplay=fordisplay)
def list_resource_tag(self, resource_id, resource_type, key,
fordisplay=False):
return ResourceDetails.list(self.api_client, resourceid=resource_id,
resourcetype=resource_type, key=key,
fordisplay=fordisplay)
def delete_resource_tag(self, resource_id, resource_type):
return ResourceDetails.delete(self.api_client,
resourceid=resource_id,
resourcetype=resource_type)

View File

@ -1,4 +1,4 @@
#t Licensed to the Apache Software Foundation (ASF) under one
# 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

View File

@ -1241,7 +1241,8 @@ class TestNuageExtraDhcp(nuageTestCase):
for number in options_to_verify:
vm1 = self.when_i_create_a_vm(
isolated_network2, None, "vm1", dhcp_options=None, is_shared_network=False)
isolated_network2, None, "vm1", dhcp_options=None,
is_shared_network=False)
result = self.when_i_add_an_extra_nic_to_a_vm(vm1, network, None)
dhcp_options_network = self.get_extra_dhcp_options_starting_with(
number, network)

View File

@ -23,6 +23,7 @@ from marvin.cloudstackAPI import updateZone
from marvin.lib.base import Account, Network
# Import System Modules
from nose.plugins.attrib import attr
import time
class TestNuageInternalDns(nuageTestCase):
@ -293,6 +294,7 @@ class TestNuageInternalDns(nuageTestCase):
except Exception as e:
self.fail("SSH into VM failed with exception %s" % e)
time.sleep(30)
cmd = 'ping -c 2 vm2'
self.debug("ping vm2 by hostname with command: " + cmd)
outputlist = ssh.execute(cmd)

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@ from marvin.cloudstackAPI import (listInternalLoadBalancerVMs,
startInternalLoadBalancerVM)
# Import System Modules
from nose.plugins.attrib import attr
from unittest import skip
import copy
import time
@ -2268,6 +2269,8 @@ class TestNuageInternalLb(nuageTestCase):
self.verify_lb_wget_file(
wget_file, [internal_vm, internal_vm_1, internal_vm_2])
@skip
# Skip until CLOUDSTACK-9837 is fixed
@attr(tags=["advanced", "nuagevsp"], required_hardware="true")
def test_08_nuage_internallb_appliance_operations_traffic(self):
"""Test Nuage VSP VPC Internal LB functionality with InternalLbVm

View File

@ -133,6 +133,7 @@ known_categories = {
'Pool': 'Pool',
'VPC': 'VPC',
'PrivateGateway': 'VPC',
'migrateVpc': 'VPC',
'Simulator': 'simulator',
'StaticRoute': 'VPC',
'Tags': 'Resource tags',

View File

@ -1,4 +1,4 @@
#t Licensed to the Apache Software Foundation (ASF) under one
# 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
@ -253,6 +253,7 @@ test_data = {
"traffictype": 'GUEST',
"ispersistent": 'True',
"availability": 'Optional',
"tags": 'native',
"serviceProviderList": {
"Dhcp": 'VirtualRouter',
"Dns": 'VirtualRouter',
@ -284,6 +285,7 @@ test_data = {
"Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat",
"traffictype": "GUEST",
"availability": "Optional'",
"tags": "native",
"serviceProviderList": {
"Dhcp": "VirtualRouter",
"Dns": "VirtualRouter",
@ -324,6 +326,24 @@ test_data = {
"UserData": 'VirtualRouter',
},
},
"isolated_staticnat_network_offering": {
"name": 'isolated_staticnat_net_off_marvin',
"displaytext": 'isolated_staticnat_net_off_marvin',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,StaticNat,UserData,Firewall,Dns',
"traffictype": 'GUEST',
"ispersistent": 'True',
"availability": 'Optional',
"tags": 'native',
"serviceProviderList": {
"Dhcp": 'VirtualRouter',
"StaticNat": 'VirtualRouter',
"SourceNat": 'VirtualRouter',
"Firewall": 'VirtualRouter',
"UserData": 'VirtualRouter',
"Dns": 'VirtualRouter'
}
},
"isolated_network": {
"name": "Isolated Network",
"displaytext": "Isolated Network"
@ -399,9 +419,10 @@ test_data = {
"displaytext": "MySharedOffering",
"guestiptype": "Shared",
"supportedservices": "Dhcp,Dns,UserData",
"specifyVlan": "False",
"specifyIpRanges": "False",
"specifyVlan": "True",
"specifyIpRanges": "True",
"traffictype": "GUEST",
"tags": "native",
"serviceProviderList": {
"Dhcp": "VirtualRouter",
"Dns": "VirtualRouter",
@ -478,6 +499,12 @@ test_data = {
"NetworkACL": 'VpcVirtualRouter'
}
},
"vpc_offering_native": {
"name": "VPC native off",
"displaytext": "VPC native off",
"supportedservices":
"Dhcp,Dns,SourceNat,UserData,StaticNat,NetworkACL"
},
"vpc": {
"name": "TestVPC",
"displaytext": "TestVPC",
@ -614,6 +641,7 @@ test_data = {
"availability": "Optional",
"ispersistent": "False",
"useVpc": "on",
"tags": 'native',
"serviceProviderList": {
"Dhcp": "VpcVirtualRouter",
"Dns": "VpcVirtualRouter",
@ -687,6 +715,25 @@ test_data = {
"StaticNat": "VirtualRouter"
}
},
"vpc_network_offering_native": {
"name": 'vpc_net_off_marvin_native',
"displaytext": 'vpc_net_off_marvin_native',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,StaticNat,SourceNat,NetworkACL,UserData,Dns',
"traffictype": 'GUEST',
"availability": 'Optional',
"tags": "native",
"useVpc": 'on',
"ispersistent": 'True',
"serviceProviderList": {
"Dhcp": "VpcVirtualRouter",
"StaticNat": "VpcVirtualRouter",
"SourceNat": "VpcVirtualRouter",
"NetworkACL": "VpcVirtualRouter",
"UserData": "VpcVirtualRouter",
"Dns": "VpcVirtualRouter"
}
},
"fwrule": {
"startport": 22,
"endport": 22,
@ -1881,6 +1928,7 @@ test_data = {
"supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall,Dns',
"traffictype": 'GUEST',
"availability": 'Optional',
"tags": "nuage",
"serviceProviderList": {
"Dhcp": 'NuageVsp',
"StaticNat": 'NuageVsp',
@ -1894,6 +1942,70 @@ test_data = {
"SourceNat": {"SupportedSourceNatTypes": "perzone"}
}
},
# Persistent services supported by the Nuage VSP plugin for Isolated networks
"isolated_network_offering_persistent": {
"name": 'nuage_marvin',
"displaytext": 'nuage_marvin',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall,Dns',
"traffictype": 'GUEST',
"availability": 'Optional',
"ispersistent": 'True',
"tags": "nuage",
"serviceProviderList": {
"Dhcp": 'NuageVsp',
"StaticNat": 'NuageVsp',
"SourceNat": 'NuageVsp',
"Firewall": 'NuageVsp',
"Connectivity": 'NuageVsp',
"UserData": 'VirtualRouter',
"Dns": 'VirtualRouter'
},
"serviceCapabilityList": {
"SourceNat": {"SupportedSourceNatTypes": "perzone"}
}
},
# Purely nuage network offering
"isolated_network_offering_without_vr": {
"name": 'nuage_marvin',
"displaytext": 'nuage_marvin',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,Firewall',
"traffictype": 'GUEST',
"availabiliy": 'Optional',
"tags": "nuage",
"serviceProviderList": {
"Dhcp": 'NuageVsp',
"StaticNat": 'NuageVsp',
"SourceNat": 'NuageVsp',
"Firewall": 'NuageVsp',
"Connectivity": 'NuageVsp'
},
"serviceCapabilityList": {
"SourceNat": {"SupportedSourceNatTypes": "perzone"}
}
},
# Purely persistent nuage network offering
"isolated_network_offering_without_vr_persistent": {
"name": 'nuage_marvin',
"displaytext": 'nuage_marvin',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,Firewall',
"traffictype": 'GUEST',
"availability": 'Optional',
"tags": "nuage",
"ispersistent": 'True',
"serviceProviderList": {
"Dhcp": 'NuageVsp',
"StaticNat": 'NuageVsp',
"SourceNat": 'NuageVsp',
"Firewall": 'NuageVsp',
"Connectivity": 'NuageVsp'
},
"serviceCapabilityList": {
"SourceNat": {"SupportedSourceNatTypes": "perzone"}
}
},
# Services supported by the Nuage VSP plugin for VPC networks
"vpc_network_offering": {
"name": 'nuage_vpc_marvin',
@ -1904,6 +2016,7 @@ test_data = {
"availability": 'Optional',
"useVpc": 'on',
"ispersistent": 'True',
"tags": "nuage",
"serviceProviderList": {
"Dhcp": "NuageVsp",
"StaticNat": "NuageVsp",
@ -1924,6 +2037,7 @@ test_data = {
"supportedservices": 'Dhcp,Lb,StaticNat,SourceNat,NetworkACL,Connectivity,UserData,Dns',
"traffictype": 'GUEST',
"availability": 'Optional',
"tags": "nuage",
"useVpc": 'on',
"ispersistent": 'True',
"serviceProviderList": {
@ -2016,6 +2130,7 @@ test_data = {
"specifyVlan": "False",
"specifyIpRanges": "True",
"availability": 'Optional',
"tags": "nuage",
"serviceProviderList": {
"Dhcp": "NuageVsp",
"Connectivity": "NuageVsp"
@ -2030,6 +2145,7 @@ test_data = {
"specifyVlan": "False",
"specifyIpRanges": "True",
"availability": 'Optional',
"tags": "nuage",
"serviceProviderList": {
"Dhcp": "NuageVsp",
"Connectivity": "NuageVsp"

View File

@ -456,6 +456,9 @@ class DeployDataCenters(object):
phynet.zoneid = zoneid
phynet.name = net.name
phynet.isolationmethods = net.isolationmethods
if net.tags:
phynet.tags = net.tags
phynetwrk = self.__apiClient.createPhysicalNetwork(phynet)
if phynetwrk.id:
self.__tcRunLogger.\

View File

@ -2240,6 +2240,8 @@ class NetworkOffering:
cmd.ispersistent = services["ispersistent"]
if "egress_policy" in services:
cmd.egressdefaultpolicy = services["egress_policy"]
if "tags" in services:
cmd.tags = services["tags"]
cmd.details = [{}]
if "servicepackageuuid" in services:
cmd.details[0]["servicepackageuuid"] = services["servicepackageuuid"]
@ -2979,6 +2981,13 @@ class Network:
cmd.cleanup = cleanup
return(apiclient.restartNetwork(cmd))
def migrate(self, apiclient, network_offering_id, resume=False):
cmd = migrateNetwork.migrateNetworkCmd()
cmd.networkid = self.id
cmd.networkofferingid = network_offering_id
cmd.resume = resume
return(apiclient.migrateNetwork(cmd))
@classmethod
def list(cls, apiclient, **kwargs):
"""List all Networks matching criteria"""
@ -4405,6 +4414,15 @@ class VPC:
cmd.displaytext = displaytext
return (apiclient.updateVPC(cmd))
def migrate(self, apiclient, vpc_offering_id, vpc_network_offering_ids, resume=False):
cmd = migrateVPC.migrateVPCCmd()
cmd.vpcid = self.id
cmd.vpcofferingid = vpc_offering_id
cmd.tiernetworkofferings = vpc_network_offering_ids
cmd.resume = resume
return(apiclient.migrateVPC(cmd))
def delete(self, apiclient):
"""Delete VPC network"""
@ -5250,3 +5268,34 @@ class RegisteredServicePackage:
[setattr(cmd, k, v) for k, v in kwargs.items()]
return(apiclient.listRegisteredServicePackages(cmd))
class ResourceDetails:
@classmethod
def create(cls, apiclient, resourceid, resourcetype, details, fordisplay):
"""Create resource detail"""
cmd = addResourceDetail.addResourceDetailCmd()
cmd.resourceid = resourceid
cmd.resourcetype = resourcetype
cmd.fordisplay = fordisplay
cmd.details = []
for key, value in details.items():
cmd.details.append({
'key': key,
'value': value
})
return Tag(apiclient.createTags(cmd).__dict__)
@classmethod
def list(self, apiclient, **kwargs):
cmd = listResourceDetails.listResourceDetailsCmd()
[setattr(cmd, k, v) for k, v in kwargs.items()]
return (apiclient.listResourceDetails(cmd))
@classmethod
def delete(self, apiclient, resourceid, resourcetype):
cmd = removeResourceDetail.removeResourceDetailCmd()
cmd.resourceid = resourceid
cmd.resourcetype = resourcetype
return (apiclient.removeResourceDetail(cmd))

View File

@ -29,6 +29,8 @@ import java.util.List;
import java.util.Random;
import java.util.UUID;
import javax.annotation.Nonnull;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
@ -88,32 +90,48 @@ public class VmwareHelper {
return deviceNumber == 7;
}
@Nonnull
private static VirtualDeviceConnectInfo getVirtualDeviceConnectInfo(boolean connected, boolean connectOnStart) {
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
connectInfo.setAllowGuestControl(true);
connectInfo.setConnected(connected);
connectInfo.setStartConnected(connectOnStart);
return connectInfo;
}
@Nonnull
private static VirtualEthernetCard createVirtualEthernetCard(VirtualEthernetCardType deviceType) {
VirtualEthernetCard nic;
switch (deviceType) {
case E1000:
nic = new VirtualE1000();
break;
case PCNet32:
nic = new VirtualPCNet32();
break;
case Vmxnet2:
nic = new VirtualVmxnet2();
break;
case Vmxnet3:
nic = new VirtualVmxnet3();
break;
default:
assert (false);
nic = new VirtualE1000();
}
return nic;
}
public static VirtualDevice prepareNicOpaque(VirtualMachineMO vmMo, VirtualEthernetCardType deviceType, String portGroupName,
String macAddress, int contextNumber, boolean connected, boolean connectOnStart) throws Exception {
assert(vmMo.getRunningHost().hasOpaqueNSXNetwork());
VirtualEthernetCard nic;
switch (deviceType) {
case E1000:
nic = new VirtualE1000();
break;
case PCNet32:
nic = new VirtualPCNet32();
break;
case Vmxnet2:
nic = new VirtualVmxnet2();
break;
case Vmxnet3:
nic = new VirtualVmxnet3();
break;
default:
nic = new VirtualE1000();
}
VirtualEthernetCard nic = createVirtualEthernetCard(deviceType);
VirtualEthernetCardOpaqueNetworkBackingInfo nicBacking = new VirtualEthernetCardOpaqueNetworkBackingInfo();
nicBacking.setOpaqueNetworkId("br-int");
@ -121,54 +139,42 @@ public class VmwareHelper {
nic.setBacking(nicBacking);
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
connectInfo.setAllowGuestControl(true);
connectInfo.setConnected(connected);
connectInfo.setStartConnected(connectOnStart);
nic.setAddressType("Manual");
nic.setConnectable(connectInfo);
nic.setConnectable(getVirtualDeviceConnectInfo(connected, connectOnStart));
nic.setMacAddress(macAddress);
nic.setKey(-contextNumber);
return nic;
}
public static void updateNicDevice(VirtualDevice nic, ManagedObjectReference morNetwork, String portGroupName) throws Exception {
VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo();
nicBacking.setDeviceName(portGroupName);
nicBacking.setNetwork(morNetwork);
nic.setBacking(nicBacking);
}
public static void updateDvNicDevice(VirtualDevice nic, ManagedObjectReference morNetwork, String dvSwitchUuid) throws Exception {
final VirtualEthernetCardDistributedVirtualPortBackingInfo dvPortBacking = new VirtualEthernetCardDistributedVirtualPortBackingInfo();
final DistributedVirtualSwitchPortConnection dvPortConnection = new DistributedVirtualSwitchPortConnection();
dvPortConnection.setSwitchUuid(dvSwitchUuid);
dvPortConnection.setPortgroupKey(morNetwork.getValue());
dvPortBacking.setPort(dvPortConnection);
nic.setBacking(dvPortBacking);
}
public static VirtualDevice prepareNicDevice(VirtualMachineMO vmMo, ManagedObjectReference morNetwork, VirtualEthernetCardType deviceType, String portGroupName,
String macAddress, int contextNumber, boolean connected, boolean connectOnStart) throws Exception {
VirtualEthernetCard nic;
switch (deviceType) {
case E1000:
nic = new VirtualE1000();
break;
case PCNet32:
nic = new VirtualPCNet32();
break;
case Vmxnet2:
nic = new VirtualVmxnet2();
break;
case Vmxnet3:
nic = new VirtualVmxnet3();
break;
default:
assert (false);
nic = new VirtualE1000();
}
VirtualEthernetCard nic = createVirtualEthernetCard(deviceType);
VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo();
nicBacking.setDeviceName(portGroupName);
nicBacking.setNetwork(morNetwork);
nic.setBacking(nicBacking);
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
connectInfo.setAllowGuestControl(true);
connectInfo.setConnected(connected);
connectInfo.setStartConnected(connectOnStart);
nic.setAddressType("Manual");
nic.setConnectable(connectInfo);
nic.setConnectable(getVirtualDeviceConnectInfo(connected, connectOnStart));
nic.setMacAddress(macAddress);
nic.setKey(-contextNumber);
return nic;
@ -177,43 +183,18 @@ public class VmwareHelper {
public static VirtualDevice prepareDvNicDevice(VirtualMachineMO vmMo, ManagedObjectReference morNetwork, VirtualEthernetCardType deviceType, String dvPortGroupName,
String dvSwitchUuid, String macAddress, int contextNumber, boolean connected, boolean connectOnStart) throws Exception {
VirtualEthernetCard nic;
switch (deviceType) {
case E1000:
nic = new VirtualE1000();
break;
case PCNet32:
nic = new VirtualPCNet32();
break;
case Vmxnet2:
nic = new VirtualVmxnet2();
break;
case Vmxnet3:
nic = new VirtualVmxnet3();
break;
default:
assert (false);
nic = new VirtualE1000();
}
VirtualEthernetCard nic = createVirtualEthernetCard(deviceType);
final VirtualEthernetCardDistributedVirtualPortBackingInfo dvPortBacking = new VirtualEthernetCardDistributedVirtualPortBackingInfo();
final DistributedVirtualSwitchPortConnection dvPortConnection = new DistributedVirtualSwitchPortConnection();
final VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
dvPortConnection.setSwitchUuid(dvSwitchUuid);
dvPortConnection.setPortgroupKey(morNetwork.getValue());
dvPortBacking.setPort(dvPortConnection);
nic.setBacking(dvPortBacking);
connectInfo.setAllowGuestControl(true);
connectInfo.setConnected(connected);
connectInfo.setStartConnected(connectOnStart);
nic.setAddressType("Manual");
nic.setConnectable(connectInfo);
nic.setConnectable(getVirtualDeviceConnectInfo(connected, connectOnStart));
nic.setMacAddress(macAddress);
nic.setKey(-contextNumber);
return nic;