Merge branch '3.0.x' of ssh://git.cloud.com/var/lib/git/cloudstack-oss into 3.0.x

This commit is contained in:
Pranav Saxena 2012-08-06 16:00:12 +05:30
commit edf747495b
58 changed files with 5716 additions and 4392 deletions

View File

@ -46,11 +46,11 @@ public interface MockAgentManager extends Manager {
Answer checkHealth(CheckHealthCommand cmd);
Answer pingTest(PingTestCommand cmd);
Answer PrepareForMigration(PrepareForMigrationCommand cmd);
Answer prepareForMigrate(PrepareForMigrationCommand cmd);
MockHost getHost(String guid);
Answer MaintainCommand(MaintainCommand cmd);
Answer maintain(MaintainCommand cmd);
Answer checkNetworkCommand(CheckNetworkCommand cmd);
}

View File

@ -41,10 +41,9 @@ import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.PingTestCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.resource.AgentResourceBase;
import com.cloud.resource.AgentRoutingResource;
import com.cloud.resource.AgentStorageResource;
@ -336,7 +335,11 @@ public class MockAgentManagerImpl implements MockAgentManager {
@Override
public PrepareForMigrationAnswer PrepareForMigration(PrepareForMigrationCommand cmd) {
public PrepareForMigrationAnswer prepareForMigrate(PrepareForMigrationCommand cmd) {
VirtualMachineTO vm = cmd.getVirtualMachine();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Preparing host for migrating " + vm);
}
return new PrepareForMigrationAnswer(cmd);
}
@ -360,7 +363,7 @@ public class MockAgentManagerImpl implements MockAgentManager {
@Override
public MaintainAnswer MaintainCommand(com.cloud.agent.api.MaintainCommand cmd) {
public MaintainAnswer maintain(com.cloud.agent.api.MaintainCommand cmd) {
return new MaintainAnswer(cmd);
}

View File

@ -51,7 +51,7 @@ public interface MockVmManager extends Manager {
public Answer stopVM(StopCommand cmd);
public Answer rebootVM(RebootCommand cmd);
public Answer checkVmState(CheckVirtualMachineCommand cmd, String hostGuid);
public Answer checkVmState(CheckVirtualMachineCommand cmd);
public Map<String, State> getVmStates(String hostGuid);
public Answer getVncPort(GetVncPortCommand cmd);

View File

@ -239,8 +239,8 @@ public class MockVmManagerImpl implements MockVmManager {
}
@Override
public CheckVirtualMachineAnswer checkVmState(CheckVirtualMachineCommand cmd, String hostGuid) {
MockVMVO vm = _mockVmDao.findByVmNameAndHost(cmd.getVmName(), hostGuid);
public CheckVirtualMachineAnswer checkVmState(CheckVirtualMachineCommand cmd) {
MockVMVO vm = _mockVmDao.findByVmName(cmd.getVmName());
if (vm == null) {
return new CheckVirtualMachineAnswer(cmd, "can't find vm:" + cmd.getVmName());
}

View File

@ -15,7 +15,6 @@ package com.cloud.agent.manager;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
@ -29,6 +28,7 @@ import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.agent.api.BackupSnapshotCommand;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.agent.api.CheckNetworkCommand;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.Command;
@ -50,6 +50,7 @@ import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.ModifyStoragePoolCommand;
import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.agent.api.PingTestCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.SecStorageSetupCommand;
import com.cloud.agent.api.SecStorageVMSetupCommand;
@ -76,7 +77,6 @@ import com.cloud.agent.api.storage.DownloadCommand;
import com.cloud.agent.api.storage.DownloadProgressCommand;
import com.cloud.agent.api.storage.ListTemplateCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.mockvm.MockVm;
import com.cloud.simulator.MockConfigurationVO;
import com.cloud.simulator.MockHost;
import com.cloud.simulator.MockVMVO;
@ -193,12 +193,16 @@ public class SimulatorManagerImpl implements SimulatorManager {
return _mockAgentMgr.checkHealth((CheckHealthCommand)cmd);
} else if (cmd instanceof PingTestCommand) {
return _mockAgentMgr.pingTest((PingTestCommand)cmd);
} else if (cmd instanceof PrepareForMigrationCommand) {
return _mockAgentMgr.prepareForMigrate((PrepareForMigrationCommand)cmd);
} else if (cmd instanceof MigrateCommand) {
return _mockVmMgr.Migrate((MigrateCommand)cmd, info);
} else if (cmd instanceof StartCommand) {
return _mockVmMgr.startVM((StartCommand)cmd, info);
} else if (cmd instanceof CheckSshCommand) {
return _mockVmMgr.checkSshCommand((CheckSshCommand)cmd);
} else if (cmd instanceof CheckVirtualMachineCommand) {
return _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd);
} else if (cmd instanceof SetStaticNatRulesCommand) {
return _mockVmMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd);
} else if (cmd instanceof SetFirewallRulesCommand) {
@ -278,7 +282,7 @@ public class SimulatorManagerImpl implements SimulatorManager {
} else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
return _mockStorageMgr.CreatePrivateTemplateFromVolume((CreatePrivateTemplateFromVolumeCommand)cmd);
} else if (cmd instanceof MaintainCommand) {
return _mockAgentMgr.MaintainCommand((MaintainCommand)cmd);
return _mockAgentMgr.maintain((MaintainCommand)cmd);
} else if (cmd instanceof GetVmStatsCommand) {
return _mockVmMgr.getVmStats((GetVmStatsCommand)cmd);
} else if (cmd instanceof GetDomRVersionCmd) {

View File

@ -29,6 +29,7 @@ import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
@ -81,8 +82,6 @@ public class AgentRoutingResource extends AgentStorageResource {
return execute((StartCommand) cmd);
} else if (cmd instanceof StopCommand) {
return execute((StopCommand) cmd);
} else if (cmd instanceof PrepareForMigrationCommand) {
return execute((PrepareForMigrationCommand) cmd);
} else if (cmd instanceof CheckVirtualMachineCommand) {
return execute((CheckVirtualMachineCommand) cmd);
} else if (cmd instanceof ReadyCommand) {
@ -187,7 +186,7 @@ public class AgentRoutingResource extends AgentStorageResource {
String vmName = vmSpec.getName();
if (this.totalCpu < (vmSpec.getCpus() * vmSpec.getSpeed() + this.usedCpu) ||
this.totalMem < (vmSpec.getMaxRam() + this.usedMem)) {
return new StartAnswer(cmd, "No enough resource to start the vm");
return new StartAnswer(cmd, "Not enough resource to start the vm");
}
State state = State.Stopped;
synchronized (_vms) {

View File

@ -54,6 +54,15 @@ public class NetworkUsageCommand extends Command {
this.vpcCIDR = vpcCIDR;
}
public NetworkUsageCommand(String privateIP, String domRName, String option, boolean forVpc, String gatewayIP)
{
this.privateIP = privateIP;
this.domRName = domRName;
this.forVpc = forVpc;
this.gatewayIP = gatewayIP;
this.option = option;
}
public String getPrivateIP() {
return privateIP;
}

View File

@ -36,7 +36,7 @@ import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.NetworkService;
import com.cloud.network.StorageNetworkService;
import com.cloud.network.VirtualNetworkApplianceService;
import com.cloud.network.VpcVirtualNetworkApplianceService;
import com.cloud.network.as.AutoScaleService;
import com.cloud.network.firewall.FirewallService;
import com.cloud.network.firewall.NetworkACLService;
@ -117,7 +117,7 @@ public abstract class BaseCmd {
public static SecurityGroupService _securityGroupService;
public static SnapshotService _snapshotService;
public static ConsoleProxyService _consoleProxyService;
public static VirtualNetworkApplianceService _routerService;
public static VpcVirtualNetworkApplianceService _routerService;
public static ResponseGenerator _responseGenerator;
public static EntityManager _entityMgr;
public static RulesService _rulesService;
@ -149,7 +149,7 @@ public abstract class BaseCmd {
_securityGroupService = locator.getManager(SecurityGroupService.class);
_snapshotService = locator.getManager(SnapshotService.class);
_consoleProxyService = locator.getManager(ConsoleProxyService.class);
_routerService = locator.getManager(VirtualNetworkApplianceService.class);
_routerService = locator.getManager(VpcVirtualNetworkApplianceService.class);
_entityMgr = locator.getManager(EntityManager.class);
_rulesService = locator.getManager(RulesService.class);
_lbService = locator.getManager(LoadBalancingRulesService.class);

View File

@ -52,6 +52,10 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd{
"If used with the account parameter returns the VPC associated with the account for the specified domain.")
private Long domainId;
@IdentityMapper(entityTableName="projects")
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="create VPC for the project")
private Long projectId;
@IdentityMapper(entityTableName="data_center")
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the ID of the availability zone")
private Long zoneId;
@ -72,7 +76,8 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd{
@Parameter(name=ApiConstants.VPC_OFF_ID, type=CommandType.LONG, required=true, description="the ID of the VPC offering")
private Long vpcOffering;
@Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain")
@Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING,
description="VPC network domain. All networks inside the VPC will belong to this domain")
private String networkDomain;
/////////////////////////////////////////////////////
@ -174,7 +179,7 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd{
@Override
public long getEntityOwnerId() {
Long accountId = finalyzeAccountId(accountName, domainId, null, true);
Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
if (accountId == null) {
return UserContext.current().getCaller().getId();
}

View File

@ -137,7 +137,7 @@ public class ListVPCsCmd extends BaseListTaggedResourcesCmd{
List<? extends Vpc> vpcs = _vpcService.listVpcs(getId(), getVpcName(), getDisplayText(),
getSupportedServices(), getCidr(), getVpcOffId(), getState(), getAccountName(), getDomainId(),
this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), getZoneId(), this.isRecursive(),
this.listAll(), getRestartRequired(), getTags());
this.listAll(), getRestartRequired(), getTags(), getProjectId());
ListResponse<VpcResponse> response = new ListResponse<VpcResponse>();
List<VpcResponse> offeringResponses = new ArrayList<VpcResponse>();
for (Vpc vpc : vpcs) {

View File

@ -47,6 +47,9 @@ public class DiskOfferingResponse extends BaseResponse {
@SerializedName(ApiConstants.TAGS) @Param(description="the tags for the disk offering")
private String tags;
@SerializedName("storagetype") @Param(description="the storage type for this disk offering")
private String storageType;
public Long getId() {
return id.getValue();
}
@ -119,4 +122,11 @@ public class DiskOfferingResponse extends BaseResponse {
this.customized = customized;
}
public String getStorageType() {
return storageType;
}
public void setStorageType(String storageType) {
this.storageType = storageType;
}
}

View File

@ -74,10 +74,10 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons
@SerializedName(ApiConstants.NETWORK) @Param(description="the list of networks belongign to the VPC", responseObject = NetworkResponse.class)
private List<NetworkResponse> networks;
@SerializedName(ApiConstants.RESTART_REQUIRED) @Param(description="true network requires restart")
@SerializedName(ApiConstants.RESTART_REQUIRED) @Param(description="true VPC requires restart")
private Boolean restartRequired;
@SerializedName(ApiConstants.NETWORK_DOMAIN) @Param(description="the network domain")
@SerializedName(ApiConstants.NETWORK_DOMAIN) @Param(description="the network domain of the VPC")
private String networkDomain;
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the project", responseObject = ResourceTagResponse.class)

View File

@ -20,7 +20,7 @@ import com.cloud.network.router.VirtualRouter;
/**
* @author Alena Prokharchyk
*/
public interface VpcVirtualNetworkApplianceService {
public interface VpcVirtualNetworkApplianceService extends VirtualNetworkApplianceService{
/**
* @param router

View File

@ -113,13 +113,14 @@ public interface VpcService {
* @param listAll TODO
* @param restartRequired TODO
* @param tags TODO
* @param projectId TODO
* @param vpc
* @return
*/
public List<? extends Vpc> listVpcs(Long id, String vpcName, String displayText,
List<String> supportedServicesStr, String cidr, Long vpcOffId, String state, String accountName, Long domainId,
String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll,
Boolean restartRequired, Map<String, String> tags);
Boolean restartRequired, Map<String, String> tags, Long projectId);
/**
* @param vpcId

View File

@ -32,7 +32,7 @@ public interface Volume extends ControlledEntity, BasedOn, StateObject<Volume.St
Snapshotting("There is a snapshot created on this volume, not backed up to secondary storage yet"),
Expunging("The volume is being expunging"),
Destroy("The volume is destroyed, and can't be recovered."),
UploadOp ("The volume upload operation is in progress");
UploadOp ("The volume upload operation is in progress or in short the volume is on secondary storage");
String _description;
@ -57,9 +57,10 @@ public interface Volume extends ControlledEntity, BasedOn, StateObject<Volume.St
s_fsm.addTransition(Creating, Event.OperationSucceeded, Ready);
s_fsm.addTransition(Creating, Event.DestroyRequested, Destroy);
s_fsm.addTransition(Creating, Event.CreateRequested, Creating);
s_fsm.addTransition(Allocated, Event.UploadRequested, UploadOp);
s_fsm.addTransition(Allocated, Event.UploadRequested, UploadOp);
s_fsm.addTransition(UploadOp, Event.CopyRequested, Creating);// CopyRequested for volume from sec to primary storage
s_fsm.addTransition(Creating, Event.CopySucceeded, Ready);
s_fsm.addTransition(UploadOp, Event.CopySucceeded, Ready);
s_fsm.addTransition(Creating, Event.CopyFailed, UploadOp);// Copying volume from sec to primary failed.
s_fsm.addTransition(UploadOp, Event.DestroyRequested, Destroy);
s_fsm.addTransition(Ready, Event.DestroyRequested, Destroy);
s_fsm.addTransition(Destroy, Event.ExpungingRequested, Expunging);

View File

@ -15,10 +15,10 @@
*/
package com.cloud.bridge.persist.dao;
import java.util.List;
import org.apache.log4j.Logger;
import com.cloud.bridge.persist.EntityDao;
import com.cloud.stack.models.CloudStackConfiguration;
import com.cloud.stack.models.CloudStackServiceOffering;
@ -29,10 +29,9 @@ public class CloudStackSvcOfferingDao extends EntityDao<CloudStackServiceOfferin
super(CloudStackServiceOffering.class, true);
}
public CloudStackServiceOffering getSvcOfferingByName( String name ){
return queryEntity("from CloudStackServiceOffering where name=?", new Object[] {name});
}
public List<CloudStackServiceOffering> getSvcOfferingByName( String name ){
return queryEntities("from CloudStackServiceOffering where name=?", new Object[] {name});
}
public CloudStackServiceOffering getSvcOfferingById( String id ){
return queryEntity("from CloudStackServiceOffering where id=?", new Object[] {id});

View File

@ -258,6 +258,10 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
List<String> resourceTypeList = new ArrayList<String>();
if (items != null) {
for( int i=0; i < items.length; i++ ) {
if (!items[i].getResourceId().contains(":") || items[i].getResourceId().split(":").length != 2) {
throw new EC2ServiceException( ClientError.InvalidResourceId_Format,
"Invalid Format. ResourceId format is resource-type:resource-uuid");
}
String resourceType = items[i].getResourceId().split(":")[0];
if (resourceTypeList.isEmpty())
resourceTypeList.add(resourceType);

View File

@ -1775,8 +1775,12 @@ public class EC2Engine {
if (null == instanceType) instanceType = "m1.small";
CloudStackSvcOfferingDao dao = new CloudStackSvcOfferingDao();
return dao.getSvcOfferingByName(instanceType);
List<CloudStackServiceOffering> svcOfferingList = dao.getSvcOfferingByName(instanceType);
for (CloudStackServiceOffering svcOffering : svcOfferingList) {
if (svcOffering.getRemoved() == null)
return svcOffering;
}
return null;
} catch(Exception e) {
logger.error( "Error while retrieving ServiceOffering information by name - ", e);
throw new EC2ServiceException(ServerError.InternalError, e.getMessage());

View File

@ -77,6 +77,7 @@ public class EC2ServiceException extends RuntimeException {
InvalidPermission_Malformed("Client.InvalidPermission.Malformed", 400),
InvalidReservationID_Malformed("Client.InvalidReservationID.Malformed", 400),
InvalidReservationID_NotFound("Client.InvalidReservationID.NotFound", 400),
InvalidResourceId_Format("Client.InvalidResourceId.Format", 400),
InvalidSnapshotID_Malformed("Client.InvalidSnapshotID.Malformed", 400),
InvalidSnapshot_NotFound("Client.InvalidSnapshot.NotFound", 400),
InvalidUserID_Malformed("Client.InvalidUserID.Malformed", 400),

View File

@ -11,6 +11,9 @@
<property name="domainId">
<column name="domain_id" />
</property>
<property name="removed">
<column name="removed" />
</property>
</class>
</hibernate-mapping>

View File

@ -57,6 +57,8 @@ public class CloudStackServiceOffering {
private String systemVmType;
@SerializedName(ApiConstants.TAGS)
private String tags;
@SerializedName(ApiConstants.REMOVED)
private String removed;
/**
*
@ -196,4 +198,14 @@ public class CloudStackServiceOffering {
return tags;
}
/**
* @return the removed
*/
public String getRemoved() {
return removed;
}
public void setRemoved(String removed) {
this.removed = removed;
}
}

View File

@ -741,7 +741,95 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return new SetStaticNatRulesAnswer(cmd, results, endResult);
}
protected Answer VPCLoadBalancerConfig(final LoadBalancerConfigCommand cmd) {
VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
File keyFile = mgr.getSystemVMKeyFile();
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String controlIp = getRouterSshControlIp(cmd);
assert(controlIp != null);
LoadBalancerConfigurator cfgtr = new HAProxyConfigurator();
String[] config = cfgtr.generateConfiguration(cmd);
String tmpCfgFilePath = "/etc/haproxy/haproxy.cfg.new";
String tmpCfgFileContents = "";
for (int i = 0; i < config.length; i++) {
tmpCfgFileContents += config[i];
tmpCfgFileContents += "\n";
}
try {
SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", keyFile, null, "/etc/haproxy/", tmpCfgFileContents.getBytes(), "haproxy.cfg.new", null);
try {
String[][] rules = cfgtr.generateFwRules(cmd);
String[] addRules = rules[LoadBalancerConfigurator.ADD];
String[] removeRules = rules[LoadBalancerConfigurator.REMOVE];
String[] statRules = rules[LoadBalancerConfigurator.STATS];
String args = "";
String ip = cmd.getNic().getIp();
args += " -i " + ip;
StringBuilder sb = new StringBuilder();
if (addRules.length > 0) {
for (int i = 0; i < addRules.length; i++) {
sb.append(addRules[i]).append(',');
}
args += " -a " + sb.toString();
}
sb = new StringBuilder();
if (removeRules.length > 0) {
for (int i = 0; i < removeRules.length; i++) {
sb.append(removeRules[i]).append(',');
}
args += " -d " + sb.toString();
}
sb = new StringBuilder();
if (statRules.length > 0) {
for (int i = 0; i < statRules.length; i++) {
sb.append(statRules[i]).append(',');
}
args += " -s " + sb.toString();
}
// Invoke the command
Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_loadbalancer.sh " + args);
if (!result.first()) {
String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.second();
s_logger.error(msg);
return new Answer(cmd, false, msg);
}
if (s_logger.isInfoEnabled()) {
s_logger.info("VPCLoadBalancerConfigCommand on domain router " + routerIp + " completed");
}
} finally {
SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "rm " + tmpCfgFilePath);
}
return new Answer(cmd);
} catch (Throwable e) {
s_logger.error("Unexpected exception: " + e.toString(), e);
return new Answer(cmd, false, "VPCLoadBalancerConfigCommand failed due to " + VmwareHelper.getExceptionMessage(e));
}
}
protected Answer execute(final LoadBalancerConfigCommand cmd) {
if ( cmd.getVpcId() != null ) {
return VPCLoadBalancerConfig(cmd);
}
VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
File keyFile = mgr.getSystemVMKeyFile();
@ -869,7 +957,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
// eth0:xx.xx.xx.xx
//
// list IP with eth devices
// ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
// ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
// | awk -F: '{ print $1 ": " $3 }'
//
//

View File

@ -180,6 +180,8 @@ public class XenServer56Resource extends CitrixResourceBase {
args += " -v " + vpcCIDR;
} else if (option.equals("reset")) {
args += "-r";
} else if (option.equals("vpn")) {
args += "-n";
} else {
return new NetworkUsageAnswer(cmd, "success", 0L, 0L);
}

View File

@ -142,7 +142,7 @@ ipsec_tunnel_add() {
sudo echo " esp=$esppolicy" >> $vpnconffile &&
sudo echo " salifetime=${esplifetime}s" >> $vpnconffile &&
sudo echo " pfs=$pfs" >> $vpnconffile &&
sudo echo " keyingtries=3" >> $vpnconffile &&
sudo echo " keyingtries=2" >> $vpnconffile &&
sudo echo " auto=add" >> $vpnconffile &&
sudo echo "$leftpeer $rightpeer: PSK \"$secret\"" > $vpnsecretsfile &&
sudo chmod 0400 $vpnsecretsfile
@ -162,8 +162,8 @@ ipsec_tunnel_add() {
logger -t cloud "$(basename $0): done ipsec tunnel entry for right peer=$rightpeer right networks=$rightnets"
#20 seconds for checking if it's ready
for i in {1..4}
#5 seconds for checking if it's ready
for i in {1..5}
do
logger -t cloud "$(basename $0): checking connection status..."
/opt/cloud/bin/checks2svpn.sh $rightpeer
@ -172,7 +172,7 @@ ipsec_tunnel_add() {
then
break
fi
sleep 5
sleep 1
done
if [ $result -eq 0 ]
then

View File

@ -15,6 +15,7 @@
source /root/func.sh
source /opt/cloud/bin/vpc_func.sh
vpnoutmark="0x525"
lock="biglock"
locked=$(getLockFile $lock)
if [ "$locked" != "1" ]
@ -42,6 +43,22 @@ create_usage_rules () {
return $?
}
create_vpn_usage_rules () {
iptables -N VPN_STATS_$ethDev > /dev/null
iptables -I FORWARD -j VPN_STATS_$ethDev > /dev/null
iptables-save|grep "VPN_STATS_$ethDev -i $ethDev" > /dev/null
if [ $? -gt 0 ]
then
iptables -A VPN_STATS_$ethDev -i $ethDev -m mark --mark $vpnoutmark > /dev/null
fi
iptables-save|grep "VPN_STATS_$ethDev -o $ethDev" > /dev/null
if [ $? -gt 0 ]
then
iptables -A VPN_STATS_$ethDev -o $ethDev -m mark --mark $vpnoutmark > /dev/null
fi
return $?
}
get_usage () {
iptables -L NETWORK_STATS_$ethDev -n -v -x | awk '$1 ~ /^[0-9]+$/ { printf "%s:", $2}'; > /dev/null
if [ $? -gt 0 ]
@ -51,6 +68,16 @@ get_usage () {
fi
}
get_vpn_usage () {
iptables -L VPN_STATS_$ethDev -n -v -x | awk '$1 ~ /^[0-9]+$/ { printf "%s:", $2}'; > /dev/null
if [ $? -gt 0 ]
then
printf $?
return 1
fi
}
reset_usage () {
iptables -Z NETWORK_STATS_$ethDev > /dev/null
if [ $? -gt 0 -a $? -ne 2 ]
@ -65,9 +92,10 @@ cflag=
gflag=
rflag=
lflag=
vflag=
nflag=
while getopts 'cgrl:v:' OPTION
while getopts 'cgnrl:v:' OPTION
do
case $OPTION in
c) cflag=1
@ -82,6 +110,8 @@ do
v) vflag=1
vcidr="$OPTARG"
;;
n) nflag=1
;;
i) #Do nothing, since it's parameter for host script
;;
?) usage
@ -94,6 +124,7 @@ ethDev=$(getEthByIp $publicIp)
if [ "$cflag" == "1" ]
then
create_usage_rules
create_vpn_usage_rules
unlock_exit 0 $lock $locked
fi
@ -103,6 +134,12 @@ then
unlock_exit $? $lock $locked
fi
if [ "$nflag" == "1" ]
then
get_vpn_usage
unlock_exit $? $lock $locked
fi
if [ "$rflag" == "1" ]
then
reset_usage

View File

@ -469,6 +469,7 @@ public class ApiResponseHelper implements ResponseGenerator {
}
diskOfferingResponse.setTags(offering.getTags());
diskOfferingResponse.setCustomized(offering.isCustomized());
diskOfferingResponse.setStorageType(offering.getUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString());
diskOfferingResponse.setObjectName("diskoffering");
return diskOfferingResponse;
}

View File

@ -63,7 +63,7 @@ public class BareMetalPingServiceImpl extends BareMetalPxeServiceBase implements
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
idList.add(new IdentityProxy("pod", podId, "podId"));
idList.add(new IdentityProxy(zone, zoneId, "zoneId"));
InvalidParameterValueException ex = new InvalidParameterValueException("Already had a PXE server in Pod with specified podId and zone with specified zoneId", idList);
throw new InvalidParameterValueException("Already had a PXE server in Pod with specified podId and zone with specified zoneId", idList);
}

View File

@ -21,7 +21,7 @@ import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.NetworkManager;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.server.ManagementServer;
import com.cloud.storage.StorageManager;
import com.cloud.storage.allocator.StoragePoolAllocator;
@ -154,7 +154,7 @@ public enum Config {
PingTimeout("Advanced", AgentManager.class, Float.class, "ping.timeout", "2.5", "Multiplier to ping.interval before announcing an agent has timed out", null),
ClusterDeltaSyncInterval("Advanced", AgentManager.class, Integer.class, "sync.interval", "60", "Cluster Delta sync interval in seconds", null),
Port("Advanced", AgentManager.class, Integer.class, "port", "8250", "Port to listen on for agent connection.", null),
RouterCpuMHz("Advanced", NetworkManager.class, Integer.class, "router.cpu.mhz", String.valueOf(VirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ), "Default CPU speed (MHz) for router VM.", null),
RouterCpuMHz("Advanced", NetworkManager.class, Integer.class, "router.cpu.mhz", String.valueOf(VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ), "Default CPU speed (MHz) for router VM.", null),
RestartRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "restart.retry.interval", "600", "Time (in seconds) between retries to restart a vm", null),
RouterStatsInterval("Advanced", NetworkManager.class, Integer.class, "router.stats.interval", "300", "Interval (in seconds) to report router statistics.", null),
ExternalNetworkStatsInterval("Advanced", NetworkManager.class, Integer.class, "external.network.stats.interval", "300", "Interval (in seconds) to report external network statistics.", null),

View File

@ -122,7 +122,6 @@ import com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl;
import com.cloud.network.ovs.OvsTunnelManagerImpl;
import com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl;
import com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl;
import com.cloud.network.router.VirtualNetworkApplianceManagerImpl;
import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl;
import com.cloud.network.rules.RulesManagerImpl;
import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl;
@ -401,7 +400,6 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addManager("Snapshot Manager", SnapshotManagerImpl.class);
addManager("SnapshotScheduler", SnapshotSchedulerImpl.class);
addManager("SecurityGroupManager", SecurityGroupManagerImpl2.class);
addManager("DomainRouterManager", VirtualNetworkApplianceManagerImpl.class);
addManager("EntityManager", EntityManagerImpl.class);
addManager("LoadBalancingRulesManager", LoadBalancingRulesManagerImpl.class);
addManager("AutoScaleManager", AutoScaleManagerImpl.class);

View File

@ -29,8 +29,8 @@ import com.cloud.host.Status;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.NetworkManager;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.utils.component.Inject;
import com.cloud.vm.Nic;
import com.cloud.vm.UserVmVO;
@ -46,7 +46,7 @@ public class UserVmDomRInvestigator extends AbstractInvestigatorImpl {
@Inject private final UserVmDao _userVmDao = null;
@Inject private final AgentManager _agentMgr = null;
@Inject private final NetworkManager _networkMgr = null;
@Inject private final VirtualNetworkApplianceManager _vnaMgr = null;
@Inject private final VpcVirtualNetworkApplianceManager _vnaMgr = null;
@Override
public Boolean isVmAlive(VMInstanceVO vm, HostVO host) {

View File

@ -70,7 +70,6 @@ import com.cloud.hypervisor.vmware.util.VmwareContext;
import com.cloud.network.CiscoNexusVSMDeviceVO;
import com.cloud.network.NetworkManager;
import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.org.Cluster.ClusterType;
import com.cloud.secstorage.CommandExecLogDao;
import com.cloud.serializer.GsonHelper;
@ -92,7 +91,6 @@ import com.cloud.vm.DomainRouterVO;
import com.google.gson.Gson;
import com.vmware.apputils.vim25.ServiceUtil;
import com.vmware.vim25.HostConnectSpec;
import com.vmware.vim25.HostPortGroupSpec;
import com.vmware.vim25.ManagedObjectReference;
@Local(value = {VmwareManager.class})
@ -117,7 +115,6 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis
@Inject CommandExecLogDao _cmdExecLogDao;
@Inject ClusterManager _clusterMgr;
@Inject CheckPointManager _checkPointMgr;
@Inject VirtualNetworkApplianceManager _routerMgr;
@Inject SecondaryStorageVmManager _ssvmMgr;
@Inject CiscoNexusVSMDeviceDao _nexusDao;
@Inject ClusterVSMMapDao _vsmMapDao;

View File

@ -12,9 +12,6 @@
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@ -34,8 +31,6 @@ import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.router.VirtualNetworkApplianceManager;
public class SshKeysDistriMonitor implements Listener {

View File

@ -43,7 +43,6 @@ import com.cloud.network.NetworkManager;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.offering.NetworkOffering;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.uservm.UserVm;
@ -70,8 +69,6 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem
@Inject
NetworkManager _networkMgr;
@Inject
VirtualNetworkApplianceManager _routerMgr;
@Inject
UserVmManager _userVmMgr;
@Inject
UserVmDao _userVmDao;

View File

@ -53,8 +53,8 @@ import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.LbStickinessMethod;
import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
@ -102,7 +102,7 @@ LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServ
@Inject
NetworkOfferingDao _networkOfferingDao;
@Inject
VirtualNetworkApplianceManager _routerMgr;
VpcVirtualNetworkApplianceManager _routerMgr;
@Inject
ConfigurationManager _configMgr;
@Inject

View File

@ -89,7 +89,6 @@ import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
import com.cloud.network.lb.dao.ElasticLbVmMapDao;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.router.VirtualRouter.RedundantState;
import com.cloud.network.router.VirtualRouter.Role;
@ -149,8 +148,6 @@ ElasticLoadBalancerManager, Manager, VirtualMachineGuru<DomainRouterVO> {
@Inject
LoadBalancingRulesManager _lbMgr;
@Inject
VirtualNetworkApplianceManager _routerMgr;
@Inject
DomainRouterDao _routerDao = null;
@Inject
protected HostPodDao _podDao = null;

View File

@ -132,6 +132,7 @@ import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.Site2SiteCustomerGateway;
import com.cloud.network.Site2SiteVpnConnection;
import com.cloud.network.Site2SiteVpnConnectionVO;
import com.cloud.network.Site2SiteVpnGatewayVO;
import com.cloud.network.SshKeysDistriMonitor;
import com.cloud.network.VirtualNetworkApplianceService;
import com.cloud.network.VirtualRouterProvider;
@ -763,15 +764,15 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
String privateIP = router.getPrivateIpAddress();
if (privateIP != null) {
boolean forVpc = router.getVpcId() != null;
List<? extends Nic> routerNics = _nicDao.listByVmId(router.getId());
for (Nic routerNic : routerNics) {
Network network = _networkMgr.getNetwork(routerNic.getNetworkId());
if (network.getTrafficType() == TrafficType.Public) {
boolean forVpc = router.getVpcId() != null;
if ((forVpc && network.getTrafficType() == TrafficType.Public) || (!forVpc && network.getTrafficType() == TrafficType.Guest)) {
final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(),
forVpc, routerNic.getIp4Address());
UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(),
router.getDataCenterIdToDeployIn(), network.getId(), null, router.getId(), router.getType().toString());
router.getDataCenterIdToDeployIn(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), router.getType().toString());
NetworkUsageAnswer answer = null;
try {
answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
@ -793,7 +794,7 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
}
txn.start();
UserStatisticsVO stats = _statsDao.lock(router.getAccountId(),
router.getDataCenterIdToDeployIn(), network.getId(), routerNic.getIp4Address(), router.getId(), router.getType().toString());
router.getDataCenterIdToDeployIn(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), router.getType().toString());
if (stats == null) {
s_logger.warn("unable to find stats for account: " + router.getAccountId());
continue;
@ -838,6 +839,81 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
txn.close();
}
}
if(forVpc){
//Get VPN gateway
Site2SiteVpnGatewayVO s2sVpn = _s2sVpnGatewayDao.findByVpcId(router.getVpcId());
if(s2sVpn != null){
final NetworkUsageCommand vpnUsageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), "vpn", forVpc, routerNic.getIp4Address());
previousStats = _statsDao.findBy(s2sVpn.getAccountId(), router.getDataCenterIdToDeployIn(), network.getId(),
routerNic.getIp4Address(), s2sVpn.getId(), "VPNGateway");
answer = null;
try {
answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), vpnUsageCmd);
} catch (Exception e) {
s_logger.warn("Error while collecting vpn network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e);
continue;
}
if (answer != null) {
if (!answer.getResult()) {
s_logger.warn("Error while collecting vpn network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails());
continue;
}
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) {
s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics");
continue;
}
txn.start();
UserStatisticsVO stats = _statsDao.lock(s2sVpn.getAccountId(), router.getDataCenterIdToDeployIn(), network.getId(),
routerNic.getIp4Address(), s2sVpn.getId(), "VPNGateway");
if (stats == null) {
s_logger.warn("unable to find vpn stats for account: " + router.getAccountId()+" vpc Id: "+router.getVpcId());
continue;
}
if(previousStats != null
&& ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived())
|| (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){
s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " +
"Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " +
answer.getBytesReceived()+ "Sent: " +answer.getBytesSent());
continue;
}
if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Received # of bytes that's less than the last one. " +
"Assuming something went wrong and persisting it. Router: " +
answer.getRouterName()+" Reported: " + answer.getBytesReceived()
+ " Stored: " + stats.getCurrentBytesReceived());
}
stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
}
stats.setCurrentBytesReceived(answer.getBytesReceived());
if (stats.getCurrentBytesSent() > answer.getBytesSent()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Received # of bytes that's less than the last one. " +
"Assuming something went wrong and persisting it. Router: " +
answer.getRouterName()+" Reported: " + answer.getBytesSent()
+ " Stored: " + stats.getCurrentBytesSent());
}
stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
}
stats.setCurrentBytesSent(answer.getBytesSent());
_statsDao.update(stats.getId(), stats);
txn.commit();
} catch (Exception e) {
txn.rollback();
s_logger.warn("Unable to update user statistics for account: " + router.getAccountId()
+ " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent());
} finally {
txn.close();
}
}
}
}
}
}
}
@ -900,6 +976,7 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
}
}
@DB
protected void updateSite2SiteVpnConnectionState(List<DomainRouterVO> routers) {
for (DomainRouterVO router : routers) {
List<Site2SiteVpnConnectionVO> conns = _s2sVpnMgr.getConnectionsForRouter(router);
@ -949,26 +1026,34 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
continue;
}
for (Site2SiteVpnConnectionVO conn : conns) {
if (conn.getState() != Site2SiteVpnConnection.State.Connected &&
conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
continue;
Site2SiteVpnConnectionVO lock = _s2sVpnConnectionDao.acquireInLockTable(conn.getId());
if (lock == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + lock);
}
Site2SiteVpnConnection.State oldState = conn.getState();
Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
if (answer.isConnected(gw.getGatewayIp())) {
conn.setState(Site2SiteVpnConnection.State.Connected);
} else {
conn.setState(Site2SiteVpnConnection.State.Disconnected);
}
_s2sVpnConnectionDao.persist(conn);
if (oldState != conn.getState()) {
String title = "Site-to-site Vpn Connection to " + gw.getName() +
" just switch from " + oldState + " to " + conn.getState();
String context = "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() +
"(id: " + router.getId() + ") " + " just switch from " + oldState + " to " + conn.getState();
s_logger.info(context);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER,
router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context);
try {
if (conn.getState() != Site2SiteVpnConnection.State.Connected &&
conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
continue;
}
Site2SiteVpnConnection.State oldState = conn.getState();
Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
if (answer.isConnected(gw.getGatewayIp())) {
conn.setState(Site2SiteVpnConnection.State.Connected);
} else {
conn.setState(Site2SiteVpnConnection.State.Disconnected);
}
_s2sVpnConnectionDao.persist(conn);
if (oldState != conn.getState()) {
String title = "Site-to-site Vpn Connection to " + gw.getName() +
" just switch from " + oldState + " to " + conn.getState();
String context = "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() +
"(id: " + router.getId() + ") " + " just switch from " + oldState + " to " + conn.getState();
s_logger.info(context);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER,
router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context);
}
} finally {
_s2sVpnConnectionDao.releaseFromLockTable(lock.getId());
}
}
}
@ -2311,6 +2396,11 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
ConcurrentOperationException, ResourceUnavailableException {
s_logger.debug("Starting router " + router);
if (_itMgr.start(router, params, user, caller, planToDeploy) != null) {
// We don't want the failure of VPN Connection affect the status of router, so we try to make connection only after router start successfully
Long vpcId = router.getVpcId();
if (vpcId != null) {
_s2sVpnMgr.reconnectDisconnectedVpnByVpc(vpcId);
}
return _routerDao.findById(router.getId());
} else {
return null;
@ -3282,12 +3372,12 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
List<? extends Nic> routerNics = _nicDao.listByVmId(router.getId());
for (Nic routerNic : routerNics) {
Network network = _networkMgr.getNetwork(routerNic.getNetworkId());
if (network.getTrafficType() == TrafficType.Public) {
boolean forVpc = router.getVpcId() != null;
boolean forVpc = router.getVpcId() != null;
if ((forVpc && network.getTrafficType() == TrafficType.Public) || (!forVpc && network.getTrafficType() == TrafficType.Guest)) {
final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(),
forVpc, routerNic.getIp4Address());
UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(),
router.getDataCenterIdToDeployIn(), network.getId(), null, router.getId(), router.getType().toString());
router.getDataCenterIdToDeployIn(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), router.getType().toString());
NetworkUsageAnswer answer = null;
try {
answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
@ -3309,7 +3399,7 @@ VirtualMachineGuru<DomainRouterVO>, Listener {
}
txn.start();
UserStatisticsVO stats = _statsDao.lock(router.getAccountId(),
router.getDataCenterIdToDeployIn(), network.getId(), null, router.getId(), router.getType().toString());
router.getDataCenterIdToDeployIn(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), router.getType().toString());
if (stats == null) {
s_logger.warn("unable to find stats for account: " + router.getAccountId());
continue;

View File

@ -128,6 +128,7 @@ import com.cloud.vm.dao.VMInstanceDao;
public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager{
private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class);
String _name;
@Inject
VpcDao _vpcDao;
@Inject
@ -1348,4 +1349,5 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
_s2sVpnMgr.markDisconnectVpnConnByVpc(vpcId);
}
}
}

View File

@ -207,8 +207,8 @@ public class VpcManagerImpl implements VpcManager, Manager{
String maxNtwks = configs.get(Config.VpcMaxNetworks.key());
_maxNetworks = NumbersUtil.parseInt(maxNtwks, 3); // max=3 is default
IpAddressSearch = _ipAddressDao.createSearchBuilder();
IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ);
IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ);
@ -218,7 +218,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ);
IpAddressSearch.join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(), JoinBuilder.JoinType.INNER);
IpAddressSearch.done();
return true;
}
@ -517,7 +517,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
//Verify that caller can perform actions in behalf of vpc owner
_accountMgr.checkAccess(caller, null, false, owner);
//check resource limit
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.vpc);
@ -647,16 +647,16 @@ public class VpcManagerImpl implements VpcManager, Manager{
s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
VpcVO vpcVO = _vpcDao.findById(vpc.getId());
vpcVO.setState(Vpc.State.Inactive);
Transaction txn = Transaction.currentTxn();
txn.start();
_vpcDao.update(vpc.getId(), vpcVO);
//decrement resource count
_resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
txn.commit();
}
//shutdown VPC
if (!shutdownVpc(vpc.getId())) {
s_logger.warn("Failed to shutdown vpc " + vpc + " as a part of vpc destroy process");
@ -714,13 +714,13 @@ public class VpcManagerImpl implements VpcManager, Manager{
@Override
public List<? extends Vpc> listVpcs(Long id, String vpcName, String displayText, List<String> supportedServicesStr,
String cidr, Long vpcOffId, String state, String accountName, Long domainId, String keyword,
Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired, Map<String, String> tags) {
Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired, Map<String, String> tags, Long projectId) {
Account caller = UserContext.current().getCaller();
List<Long> permittedAccounts = new ArrayList<Long>();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
ListProjectResourcesCriteria>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject,
_accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject,
listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@ -839,7 +839,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
}
}
protected List<Service> getSupportedServices() {
List<Service> services = new ArrayList<Service>();
services.add(Network.Service.Dhcp);
@ -865,9 +865,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
//check if vpc exists
Vpc vpc = getActiveVpc(vpcId);
if (vpc == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified", null);
ex.addProxyObject("vpc", vpcId, "VPC");
throw ex;
throw new InvalidParameterValueException("Unable to find Enabled VPC", null);
}
//permission check
@ -944,7 +942,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
@DB
public void validateNtkwOffForVpc(long ntwkOffId, String cidr, String networkDomain,
Account networkOwner, Vpc vpc, Long networkId, String gateway) {
NetworkOffering guestNtwkOff = _configMgr.getNetworkOffering(ntwkOffId);
if (networkId == null) {
@ -1007,7 +1005,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
@DB
protected void validateNewVpcGuestNetwork(String cidr, String gateway, Account networkOwner, Vpc vpc, String networkDomain) {
Transaction txn = Transaction.currentTxn();
txn.start();
Vpc locked = _vpcDao.acquireInLockTable(vpc.getId());
@ -1154,7 +1152,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
// Verify input parameters
Vpc vpc = getActiveVpc(vpcId);
if (vpc == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id", null);
throw new InvalidParameterValueException("Unable to find Enabled VPC", null);
}
_accountMgr.checkAccess(caller, null, false, vpc);
@ -1220,7 +1218,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
//Validate parameters
Vpc vpc = getActiveVpc(vpcId);
if (vpc == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id", null);
throw new InvalidParameterValueException("Unable to find Enabled VPC", null);
}
//allow only one private gateway per vpc
@ -1300,7 +1298,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
@ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_DELETE, eventDescription = "deleting private gateway")
@DB
public boolean deleteVpcPrivateGateway(long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException {
Transaction txn = Transaction.currentTxn();
txn.start();
VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId);
@ -1315,11 +1313,11 @@ public class VpcManagerImpl implements VpcManager, Manager{
throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount +
" static routes applied. Remove the routes first");
}
gatewayVO.setState(VpcGateway.State.Deleting);
_vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting);
txn.commit();
//1) delete the gateway on the backend
@ -1390,11 +1388,12 @@ public class VpcManagerImpl implements VpcManager, Manager{
Account caller = UserContext.current().getCaller();
List<Long> permittedAccounts = new ArrayList<Long>();
String state = cmd.getState();
Long projectId = cmd.getProjectId();
Filter searchFilter = new Filter(VpcGatewayVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
ListProjectResourcesCriteria>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, null, accountName, null, permittedAccounts, domainIdRecursiveListProject,
_accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject,
listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@ -1566,8 +1565,18 @@ public class VpcManagerImpl implements VpcManager, Manager{
if (!NetUtils.isValidCIDR(cidr)){
throw new InvalidParameterValueException("Invalid format for cidr " + cidr, null);
}
//validate the cidr
//1) CIDR should be outside of VPC cidr for guest networks
if (NetUtils.isNetworksOverlap(vpc.getCidr(), cidr)) {
throw new InvalidParameterValueException("CIDR should be outside of VPC cidr " + vpc.getCidr(), null);
}
//2) CIDR should be outside of link-local cidr
if (NetUtils.isNetworksOverlap(vpc.getCidr(), NetUtils.getLinkLocalCIDR())) {
throw new InvalidParameterValueException("CIDR should be outside of link local cidr " + NetUtils.getLinkLocalCIDR(), null);
}
//TODO - check cidr for the conflicts
Transaction txn = Transaction.currentTxn();
txn.start();
@ -1599,10 +1608,11 @@ public class VpcManagerImpl implements VpcManager, Manager{
Account caller = UserContext.current().getCaller();
List<Long> permittedAccounts = new ArrayList<Long>();
Map<String, String> tags = cmd.getTags();
Long projectId = cmd.getProjectId();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
ListProjectResourcesCriteria>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject,
_accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject,
listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
@ -1734,7 +1744,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
public VpcGateway getPrivateGatewayForVpc(long vpcId) {
return _vpcGatewayDao.getPrivateGatewayForVpc(vpcId);
}
@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true)
@ -1783,8 +1793,8 @@ public class VpcManagerImpl implements VpcManager, Manager{
return _ipAddressDao.findById(ipId);
}
@Override
public void unassignIPFromVpcNetwork(long ipId, long networkId) {
IPAddressVO ip = _ipAddressDao.findById(ipId);
@ -1818,13 +1828,13 @@ public class VpcManagerImpl implements VpcManager, Manager{
}
s_logger.debug("Successfully released VPC ip address " + ip + " back to VPC pool ");
}
@Override
public boolean ipUsedInVpc(IpAddress ip) {
return (ip != null && ip.getVpcId() != null &&
(ip.isOneToOneNat() || !_firewallDao.listByIp(ip.getId()).isEmpty()));
}
@DB
@Override
public Network createVpcGuestNetwork(long ntwkOffId, String name, String displayText, String gateway,
@ -1835,20 +1845,18 @@ public class VpcManagerImpl implements VpcManager, Manager{
Vpc vpc = getActiveVpc(vpcId);
if (vpc == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC ", null);
ex.addProxyObject("vpc", vpcId, "VPC");
throw ex;
throw new InvalidParameterValueException("Unable to find Enabled VPC ", null);
}
_accountMgr.checkAccess(caller, null, false, vpc);
if (networkDomain == null) {
networkDomain = vpc.getNetworkDomain();
}
if (vpc.getZoneId() != zoneId) {
throw new InvalidParameterValueException("New network doesn't belong to vpc zone", null);
}
//1) Validate if network can be created for VPC
validateNtkwOffForVpc(ntwkOffId, cidr, networkDomain, owner, vpc, null, gateway);
@ -1858,12 +1866,12 @@ public class VpcManagerImpl implements VpcManager, Manager{
return guestNetwork;
}
protected IPAddressVO getExistingSourceNatInVpc(long ownerId, long vpcId) {
List<IPAddressVO> addrs = listPublicIpsAssignedToVpc(ownerId, true, vpcId);
IPAddressVO sourceNatIp = null;
if (addrs.isEmpty()) {
return null;
@ -1882,7 +1890,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
return sourceNatIp;
}
protected List<IPAddressVO> listPublicIpsAssignedToVpc(long accountId, Boolean sourceNat, long vpcId) {
SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
sc.setParameters("accountId", accountId);
@ -1895,8 +1903,8 @@ public class VpcManagerImpl implements VpcManager, Manager{
return _ipAddressDao.search(sc, null);
}
@Override
public PublicIp assignSourceNatIpAddressToVpc(Account owner, Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException {
long dcId = vpc.getZoneId();
@ -1928,7 +1936,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
Vpc vpc = getVpc(network.getVpcId());
validateNtkwOffForVpc(ntwkOffId, null, null, null, vpc, networkId, null);
}
return _ntwkMgr.updateGuestNetwork(networkId, name, displayText, callerAccount, callerUser, domainSuffix,
ntwkOffId, changeCidr);
}

View File

@ -49,7 +49,6 @@ import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.RemoteAccessVpnDao;
import com.cloud.network.dao.VpnUserDao;
import com.cloud.network.element.RemoteAccessVPNServiceProvider;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.rules.FirewallManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.Purpose;
@ -87,7 +86,6 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
@Inject VpnUserDao _vpnUsersDao;
@Inject RemoteAccessVpnDao _remoteAccessVpnDao;
@Inject IPAddressDao _ipAddressDao;
@Inject VirtualNetworkApplianceManager _routerMgr;
@Inject AccountManager _accountMgr;
@Inject DomainManager _domainMgr;
@Inject NetworkManager _networkMgr;

View File

@ -11,4 +11,5 @@ public interface Site2SiteVpnManager extends Site2SiteVpnService {
void markDisconnectVpnConnByVpc(long vpcId);
List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router);
boolean deleteCustomerGatewayByAccount(long accountId);
void reconnectDisconnectedVpnByVpc(Long vpcId);
}

View File

@ -49,11 +49,14 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.UserContext;
import com.cloud.user.UserStatisticsVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserStatisticsDao;
import com.cloud.utils.IdentityProxy;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.JoinBuilder;
@ -76,7 +79,7 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
@Inject AccountDao _accountDao;
@Inject VpcManager _vpcMgr;
@Inject AccountManager _accountMgr;
@Inject UserStatisticsDao _statsDao = null;
String _name;
@Override
@ -128,6 +131,13 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
Site2SiteVpnGatewayVO gw = new Site2SiteVpnGatewayVO(owner.getAccountId(), owner.getDomainId(), ips.get(0).getId(), vpcId);
_vpnGatewayDao.persist(gw);
UserStatisticsVO stats = _statsDao.findBy(owner.getAccountId(), vpc.getZoneId(), ips.get(0).getSourceNetworkId(),
ips.get(0).getAddress().toString(), gw.getId(), "VPNGateway");
if (stats == null) {
stats = new UserStatisticsVO(owner.getAccountId(), vpc.getZoneId(), ips.get(0).getAddress().toString(), gw.getId(),
"VPNGateway", ips.get(0).getSourceNetworkId());
_statsDao.persist(stats);
}
return gw;
}
@ -251,30 +261,39 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
}
@Override
@DB
public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException {
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) {
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
idList.add(new IdentityProxy(conn, id, "connectionId"));
throw new InvalidParameterValueException("Site to site VPN connection with specified connectionId not in correct state(pending or disconnected) to process!", idList);
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
if (conn == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + conn);
}
try {
if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) {
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
idList.add(new IdentityProxy(conn, id, "connectionId"));
throw new InvalidParameterValueException("Site to site VPN connection with specified connectionId not in correct state(pending or disconnected) to process!", idList);
}
conn.setState(State.Pending);
_vpnConnectionDao.persist(conn);
List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
boolean result = true;
for (Site2SiteVpnServiceProvider element : elements) {
result = result & element.startSite2SiteVpn(conn);
}
if (result) {
conn.setState(State.Connected);
conn.setState(State.Pending);
_vpnConnectionDao.persist(conn);
return conn;
List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
boolean result = true;
for (Site2SiteVpnServiceProvider element : elements) {
result = result & element.startSite2SiteVpn(conn);
}
if (result) {
conn.setState(State.Connected);
_vpnConnectionDao.persist(conn);
return conn;
}
conn.setState(State.Error);
_vpnConnectionDao.persist(conn);
throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id);
} finally {
_vpnConnectionDao.releaseFromLockTable(conn.getId());
}
conn.setState(State.Error);
_vpnConnectionDao.persist(conn);
throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id);
}
@Override
@ -439,26 +458,35 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
return true;
}
@DB
private void stopVpnConnection(Long id) throws ResourceUnavailableException {
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
if (conn.getState() != State.Connected && conn.getState() != State.Error) {
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
idList.add(new IdentityProxy(conn, id, "vpnConnectionId"));
throw new InvalidParameterValueException("Site to site VPN connection with specified id is not in correct state(connected) to process disconnect!", idList);
Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id);
if (conn == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + conn);
}
try {
if (conn.getState() != State.Connected && conn.getState() != State.Error) {
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
idList.add(new IdentityProxy(conn, id, "vpnConnectionId"));
throw new InvalidParameterValueException("Site to site VPN connection with specified id is not in correct state(connected) to process disconnect!", idList);
}
List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
boolean result = true;
conn.setState(State.Disconnected);
_vpnConnectionDao.persist(conn);
for (Site2SiteVpnServiceProvider element : elements) {
result = result & element.stopSite2SiteVpn(conn);
}
if (!result) {
conn.setState(State.Error);
conn.setState(State.Disconnected);
_vpnConnectionDao.persist(conn);
throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id);
List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
boolean result = true;
for (Site2SiteVpnServiceProvider element : elements) {
result = result & element.stopSite2SiteVpn(conn);
}
if (!result) {
conn.setState(State.Error);
_vpnConnectionDao.persist(conn);
throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id);
}
} finally {
_vpnConnectionDao.releaseFromLockTable(conn.getId());
}
}
@ -641,15 +669,24 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
}
@Override
@DB
public void markDisconnectVpnConnByVpc(long vpcId) {
List<Site2SiteVpnConnectionVO> conns = _vpnConnectionDao.listByVpcId(vpcId);
for (Site2SiteVpnConnectionVO conn : conns) {
if (conn == null) {
continue;
}
if (conn.getState() == Site2SiteVpnConnection.State.Connected) {
conn.setState(Site2SiteVpnConnection.State.Disconnected);
_vpnConnectionDao.persist(conn);
Site2SiteVpnConnectionVO lock = _vpnConnectionDao.acquireInLockTable(conn.getId());
if (lock == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + conn);
}
try {
if (conn.getState() == Site2SiteVpnConnection.State.Connected) {
conn.setState(Site2SiteVpnConnection.State.Disconnected);
_vpnConnectionDao.persist(conn);
}
} finally {
_vpnConnectionDao.releaseFromLockTable(lock.getId());
}
}
}
@ -675,4 +712,22 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
}
return result;
}
@Override
public void reconnectDisconnectedVpnByVpc(Long vpcId) {
List<Site2SiteVpnConnectionVO> conns = _vpnConnectionDao.listByVpcId(vpcId);
for (Site2SiteVpnConnectionVO conn : conns) {
if (conn == null) {
continue;
}
if (conn.getState() == Site2SiteVpnConnection.State.Disconnected) {
try {
startVpnConnection(conn.getId());
} catch (ResourceUnavailableException e) {
Site2SiteCustomerGatewayVO gw = _customerGatewayDao.findById(conn.getCustomerGatewayId());
s_logger.warn("Site2SiteVpnManager: Fail to re-initiate VPN connection " + conn.getId() + " which connect to " + gw.getName());
}
}
}
}
}

View File

@ -611,7 +611,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
if (clusterId != null) {
ClusterVO cluster = _clusterDao.findById(clusterId);
if (cluster == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("can not find cluster by Id", null);
throw new InvalidParameterValueException("can not find cluster", null);
} else {
if (cluster.getGuid() == null) {
List<HostVO> hosts = listAllHostsInCluster(clusterId);

View File

@ -1303,9 +1303,9 @@ public class ManagementServerImpl implements ManagementServer {
}// If ISO requested then it should be ISO.
if (isIso && template.getFormat() != ImageFormat.ISO) {
s_logger.error("Template Id " + templateId + " is not an ISO");
InvalidParameterValueException ex = new InvalidParameterValueException("Specified Template Id is not an ISO", null);
ex.addProxyObject(template, templateId, "templateId");
throw ex;
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
idList.add(new IdentityProxy(template, templateId, "templateId"));
throw new InvalidParameterValueException("Specified Template Id is not an ISO", idList);
}// If ISO not requested then it shouldn't be an ISO.
if (!isIso && template.getFormat() == ImageFormat.ISO) {
s_logger.error("Incorrect format of the template id " + templateId);

View File

@ -332,7 +332,7 @@ public class ConsoleProxyServlet extends HttpServlet {
param.setClientTunnelSession(parsedHostInfo.third());
}
sb.append("/ajax?token=" + encryptor.encryptObject(ConsoleProxyClientParam.class, param));
sb.append("/ajaximg?token=" + encryptor.encryptObject(ConsoleProxyClientParam.class, param));
sb.append("&w=").append(w).append("&h=").append(h);
if(s_logger.isDebugEnabled()) {

View File

@ -121,7 +121,6 @@ import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.network.NetworkManager;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.org.Grouping;
import com.cloud.org.Grouping.AllocationState;
import com.cloud.projects.Project.ListProjectResourcesCriteria;
@ -293,8 +292,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
@Inject
protected ClusterDao _clusterDao;
@Inject
protected VirtualNetworkApplianceManager _routerMgr;
@Inject
protected UsageEventDao _usageEventDao;
@Inject
protected VirtualMachineManager _vmMgr;
@ -732,6 +729,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
StoragePoolVO destPool = findStoragePool(dskCh, dc, pod, clusterId, vm, avoidPools);
// Copy the volume from secondary storage to the destination storage pool
stateTransitTo(volume, Event.CopyRequested);
VolumeHostVO volumeHostVO = _volumeHostDao.findByVolumeId(volume.getId());
HostVO secStorage = _hostDao.findById(volumeHostVO.getHostId());
String secondaryStorageURL = secStorage.getStorageUrl();

View File

@ -37,7 +37,7 @@ import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
import com.cloud.event.UsageEventVO;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
@ -1404,7 +1404,7 @@ public class Upgrade218to22 implements DbUpgrade {
pstmt.close();
int proxyRamSize = NumbersUtil.parseInt(getConfigValue(conn, "consoleproxy.ram.size"), ConsoleProxyManager.DEFAULT_PROXY_VM_RAMSIZE);
int domrRamSize = NumbersUtil.parseInt(getConfigValue(conn, "router.ram.size"), VirtualNetworkApplianceManager.DEFAULT_ROUTER_VM_RAMSIZE);
int domrRamSize = NumbersUtil.parseInt(getConfigValue(conn, "router.ram.size"), VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_VM_RAMSIZE);
int ssvmRamSize = NumbersUtil.parseInt(getConfigValue(conn, "secstorage.vm.ram.size"), SecondaryStorageVmManager.DEFAULT_SS_VM_RAMSIZE);
pstmt = conn
@ -1563,7 +1563,7 @@ public class Upgrade218to22 implements DbUpgrade {
pstmt.close();
int proxyCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "consoleproxy.cpu.mhz"), ConsoleProxyManager.DEFAULT_PROXY_VM_CPUMHZ);
int domrCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "router.cpu.mhz"), VirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ);
int domrCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "router.cpu.mhz"), VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ);
int ssvmCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "secstorage.vm.cpu.mhz"), SecondaryStorageVmManager.DEFAULT_SS_VM_CPUMHZ);
pstmt = conn

View File

@ -525,7 +525,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
return maxDataVolumesSupported.intValue();
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true)
public Volume attachVolumeToVM(AttachVolumeCmd command) {
@ -2928,9 +2928,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
// Verify input parameters
UserVmVO vm = _vmDao.findById(vmId);
if (vm == null || vm.getRemoved() != null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId", null);
ex.addProxyObject(vm, vmId, "vmId");
throw ex;
throw new InvalidParameterValueException("Unable to find a virtual machine with specified vmId", null);
}
if (vm.getState() == State.Destroyed || vm.getState() == State.Expunging) {
@ -3138,11 +3136,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
if (id != null) {
sc.setParameters("id", id);
}
if (templateId != null) {
sc.setParameters("templateId", templateId);
}
if (isoId != null) {
sc.setParameters("isoId", isoId);
}
@ -3314,9 +3312,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
if (s_logger.isDebugEnabled()) {
s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
}
InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Running, unable to migrate the vm with specified id", null);
ex.addProxyObject(vm, vmId, "vmId");
throw ex;
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
idList.add(new IdentityProxy(vm, vmId, "vmId"));
throw new InvalidParameterValueException("VM is not Running, unable to migrate the vm with specified id", idList);
}
if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM) && !vm.getHypervisorType().equals(HypervisorType.Ovm)) {
if (s_logger.isDebugEnabled()) {
@ -3396,9 +3394,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
//don't allow to move the vm from the project
if (oldAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) {
InvalidParameterValueException ex = new InvalidParameterValueException("Specified Vm id belongs to the project and can't be moved", null);
ex.addProxyObject(vm, cmd.getVmId(), "vmId");
throw ex;
List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
idList.add(new IdentityProxy(vm, cmd.getVmId(), "vmId"));
throw new InvalidParameterValueException("Specified Vm id belongs to the project and can't be moved", idList);
}
Account newAccount = _accountService.getActiveAccountByName(cmd.getAccountName(), cmd.getDomainId());
if (newAccount == null || newAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) {
@ -3680,9 +3678,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
long vmId = cmd.getVmId();
UserVmVO vm = _vmDao.findById(vmId);
if (vm == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Cann not find VM by ID ", null);
ex.addProxyObject(vm, vmId, "vmId");
throw ex;
throw new InvalidParameterValueException("Cann not find VM", null);
}
Account owner = _accountDao.findById(vm.getAccountId());

File diff suppressed because it is too large Load Diff

View File

@ -288,12 +288,14 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
RouterNetworkVO routerNtwkMap = new RouterNetworkVO(router.getId(), guestNetwork.getId(), guestNetwork.getGuestType());
_routerNetworkDao.persist(routerNtwkMap);
//2) create user stats entry for the network
UserStatisticsVO stats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn(),
guestNetwork.getId(), null, router.getId(), router.getType().toString());
if (stats == null) {
stats = new UserStatisticsVO(router.getAccountId(), router.getDataCenterIdToDeployIn(), null, router.getId(),
router.getType().toString(), guestNetwork.getId());
_userStatsDao.persist(stats);
if(router.getVpcId() == null){
UserStatisticsVO stats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn(),
guestNetwork.getId(), null, router.getId(), router.getType().toString());
if (stats == null) {
stats = new UserStatisticsVO(router.getAccountId(), router.getDataCenterIdToDeployIn(), null, router.getId(),
router.getType().toString(), guestNetwork.getId());
_userStatsDao.persist(stats);
}
}
txn.commit();
}

View File

@ -0,0 +1,796 @@
# -*- encoding: utf-8 -*-
# Copyright 2012 Citrix Systems, Inc. Licensed under the
# Apache License, Version 2.0 (the "License"); you may not use this
# file except in compliance with the License. Citrix Systems, Inc.
# reserves all rights not expressly granted by 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.
#
# Automatically generated by addcopyright.py at 04/03/2012
""" P1 tests for dedicated Host high availability
"""
#Import Local Modules
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from integration.lib.utils import *
from integration.lib.base import *
from integration.lib.common import *
from marvin import remoteSSHClient
import datetime
class Services:
""" Dedicated host HA test cases """
def __init__(self):
self.services = {
"account": {
"email": "test@test.com",
"firstname": "HA",
"lastname": "HA",
"username": "HA",
# Random characters are appended for unique
# username
"password": "password",
},
"service_offering_with_ha": {
"name": "Tiny Instance With HA Enabled",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 100, # in MHz
"memory": 64, # In MBs
},
"service_offering_without_ha": {
"name": "Tiny Instance Without HA",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 100, # in MHz
"memory": 64, # In MBs
},
"virtual_machine": {
"displayname": "VM",
"username": "root",
"password": "password",
"ssh_port": 22,
"hypervisor": 'XenServer',
# Hypervisor type should be same as
# hypervisor type of cluster
"privateport": 22,
"publicport": 22,
"protocol": 'TCP',
},
"ostypeid": '6a6b23aa-5e59-4b53-8161-0ad1aa5990f1',
"timeout": 100,
}
class TestHostHighAvailability(cloudstackTestCase):
""" Dedicated host HA test cases """
@classmethod
def setUpClass(cls):
cls.api_client = super(
TestHostHighAvailability,
cls
).getClsTestClient().getApiClient()
cls.services = Services().services
# Get Zone, Domain and templates
cls.domain = get_domain(
cls.api_client,
cls.services
)
cls.zone = get_zone(
cls.api_client,
cls.services
)
cls.template = get_template(
cls.api_client,
cls.zone.id,
cls.services["ostypeid"]
)
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["virtual_machine"]["template"] = cls.template.id
cls.service_offering_with_ha = ServiceOffering.create(
cls.api_client,
cls.services["service_offering_with_ha"],
offerha=True
)
cls.service_offering_without_ha = ServiceOffering.create(
cls.api_client,
cls.services["service_offering_without_ha"],
offerha=False
)
cls._cleanup = [
cls.service_offering_with_ha,
cls.service_offering_without_ha,
]
return
@classmethod
def tearDownClass(cls):
try:
#Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.account = Account.create(
self.apiclient,
self.services["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup = [self.account]
return
def tearDown(self):
try:
#Clean up, terminate the created accounts, domains etc
cleanup_resources(self.apiclient, self.cleanup)
self.testClient.close()
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def test_01_vm_deployment_with_compute_offering_with_ha_enabled(self):
""" Test VM deployments (Create HA enabled Compute Service Offering and VM) """
# Steps,
#1. Create a Compute service offering with the “Offer HA” option selected.
#2. Create a Guest VM with the compute service offering created above.
# Validations,
#1. Ensure that the offering is created and that in the UI the “Offer HA” field is enabled (Yes)
#The listServiceOffering API should list “offerha” as true.
#2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected.
# Also, check that the HA Enabled field is enabled “Yes”.
#list and validate above created service offering with Ha enabled
list_service_response = list_service_offering(
self.apiclient,
id=self.service_offering_with_ha.id
)
self.assertEqual(
isinstance(list_service_response, list),
True,
"listServiceOfferings returned invalid object in response."
)
self.assertNotEqual(
len(list_service_response),
0,
"listServiceOfferings returned empty list."
)
self.assertEqual(
list_service_response[0].offerha,
True,
"The service offering is not HA enabled"
)
#create virtual machine with the service offering with Ha enabled
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.account.name,
domainid=self.account.account.domainid,
serviceofferingid=self.service_offering_with_ha.id
)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"listVirtualMachines returned invalid object in response."
)
self.assertNotEqual(
len(vms),
0,
"listVirtualMachines returned empty list."
)
self.debug("Deployed VM on host: %s" % vms[0].hostid)
self.assertEqual(
vms[0].haenable,
True,
"VM not created with HA enable tag"
)
def test_02_no_vm_creation_on_host_with_haenabled(self):
""" Verify you can not create new VMs on hosts with an ha.tag """
# Steps,
#1. Fresh install CS (Bonita) that supports this feature
#2. Create Basic zone, pod, cluster, add 3 hosts to cluster (host1, host2, host3), secondary & primary Storage
#3. When adding host3, assign the HA host tag.
#4. You should already have a compute service offering with HA already create from above. If not, create one for HA.
#5. Create VMs with the service offering with and without the HA tag
# Validations,
#Check to make sure the newly created VM is not on any HA enabled hosts
#The VM should be created only on host1 or host2 and never host3 (HA enabled)
#create and verify virtual machine with HA enabled service offering
virtual_machine_with_ha = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.account.name,
domainid=self.account.account.domainid,
serviceofferingid=self.service_offering_with_ha.id
)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine_with_ha.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"listVirtualMachines returned invalid object in response."
)
self.assertNotEqual(
len(vms),
0,
"listVirtualMachines returned empty list."
)
vm = vms[0]
self.debug("Deployed VM on host: %s" % vm.hostid)
#validate the virtual machine created is host Ha enabled
list_hosts_response = list_hosts(
self.apiclient,
id=vm.hostid
)
self.assertEqual(
isinstance(list_hosts_response, list),
True,
"listHosts returned invalid object in response."
)
self.assertNotEqual(
len(list_hosts_response),
0,
"listHosts retuned empty list in response."
)
self.assertEqual(
list_hosts_response[0].hahost,
False,
"VM created on HA enabled host."
)
#create and verify virtual machine with Ha disabled service offering
virtual_machine_without_ha = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.account.name,
domainid=self.account.account.domainid,
serviceofferingid=self.service_offering_without_ha.id
)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine_without_ha.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"listVirtualMachines returned invalid object in response."
)
self.assertNotEqual(
len(vms),
0,
"listVirtualMachines returned empty list."
)
vm = vms[0]
self.debug("Deployed VM on host: %s" % vm.hostid)
#verify that the virtual machine created on the host is Ha disabled
list_hosts_response = list_hosts(
self.apiclient,
id=vm.hostid
)
self.assertEqual(
isinstance(list_hosts_response, list),
True,
"listHosts returned invalid object in response."
)
self.assertNotEqual(
len(list_hosts_response),
0,
"listHosts returned empty list."
)
host = list_hosts_response[0]
self.assertEqual(
host.hahost,
False,
"VM migrated to HA enabled host."
)
def test_03_cant_migrate_vm_to_host_with_ha_positive(self):
""" Verify you can not migrate VMs to hosts with an ha.tag (positive) """
# Steps,
#1. Create a Compute service offering with the “Offer HA” option selected.
#2. Create a Guest VM with the compute service offering created above.
#3. Select the VM and migrate VM to another host. Choose a “Suitable” host (i.e. host2)
# Validations
#The option from the “Migrate instance to another host” dialog box” should list host3 as “Not Suitable” for migration.
#Confirm that the VM is migrated to the “Suitable” host you selected (i.e. host2)
#create and verify the virtual machine with HA enabled service offering
virtual_machine_with_ha = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.account.name,
domainid=self.account.account.domainid,
serviceofferingid=self.service_offering_with_ha.id
)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine_with_ha.id,
listall=True,
)
self.assertEqual(
isinstance(vms, list),
True,
"List VMs should return valid response for deployed VM"
)
self.assertNotEqual(
len(vms),
0,
"List VMs should return valid response for deployed VM"
)
vm = vms[0]
self.debug("Deployed VM on host: %s" % vm.hostid)
#Find out a Suitable host for VM migration
list_hosts_response = list_hosts(
self.apiclient,
)
self.assertEqual(
isinstance(list_hosts_response, list),
True,
"The listHosts API returned the invalid list"
)
self.assertNotEqual(
len(list_hosts_response),
0,
"The listHosts returned nothing."
)
suitableHost = None
for host in list_hosts_response:
if host.suitableformigration == True and host.hostid != vm.hostid:
suitableHost = host
break
self.assertTrue(suitableHost is not None, "suitablehost should not be None")
#Migration of the VM to a suitable host
self.debug("Migrating VM-ID: %s to Host: %s" % (self.vm.id, suitableHost.id))
cmd = migrateVirtualMachine.migrateVirtualMachineCmd()
cmd.hostid = suitableHost.id
cmd.virtualmachineid = self.vm.id
self.apiclient.migrateVirtualMachine(cmd)
#Verify that the VM migrated to a targeted Suitable host
list_vm_response = list_virtual_machines(
self.apiclient,
id=vm.id
)
self.assertEqual(
isinstance(list_vm_response, list),
True,
"The listVirtualMachines returned the invalid list."
)
self.assertNotEqual(
list_vm_response,
None,
"The listVirtualMachines API returned nothing."
)
vm_response = list_vm_response[0]
self.assertEqual(
vm_response.id,
vm.id,
"The virtual machine id and the the virtual machine from listVirtualMachines is not matching."
)
self.assertEqual(
vm_response.hostid,
suitableHost.id,
"The VM is not migrated to targeted suitable host."
)
def test_04_cant_migrate_vm_to_host_with_ha_negative(self):
""" Verify you can not migrate VMs to hosts with an ha.tag (negative) """
# Steps,
#1. Create a Compute service offering with the “Offer HA” option selected.
#2. Create a Guest VM with the compute service offering created above.
#3. Select the VM and migrate VM to another host. Choose a “Not Suitable” host.
# Validations,
#The option from the “Migrate instance to another host” dialog box” should list host3 as “Not Suitable” for migration.
#By design, The Guest VM can STILL can be migrated to host3 if the admin chooses to do so.
#create and verify virtual machine with HA enabled service offering
virtual_machine_with_ha = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.account.name,
domainid=self.account.account.domainid,
serviceofferingid=self.service_offering_with_ha.id
)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine_with_ha.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"The listVirtualMachines returned invalid object in response."
)
self.assertNotEqual(
len(vms),
0,
"The listVirtualMachines returned empty response."
)
vm = vms[0]
self.debug("Deployed VM on host: %s" % vm.hostid)
#Find out Non-Suitable host for VM migration
list_hosts_response = list_hosts(
self.apiclient,
)
self.assertEqual(
isinstance(list_hosts_response, list),
True,
"listHosts returned invalid object in response."
)
self.assertNotEqual(
len(list_hosts_response),
0,
"listHosts returned empty response."
)
notSuitableHost = None
for host in list_hosts_response:
if not host.suitableformigration and host.hostid != vm.hostid:
notSuitableHost = host
break
self.assertTrue(notSuitableHost is not None, "notsuitablehost should not be None")
#Migrate VM to Non-Suitable host
self.debug("Migrating VM-ID: %s to Host: %s" % (vm.id, notSuitableHost.id))
cmd = migrateVirtualMachine.migrateVirtualMachineCmd()
cmd.hostid = notSuitableHost.id
cmd.virtualmachineid = vm.id
self.apiclient.migrateVirtualMachine(cmd)
#Verify that the virtual machine got migrated to targeted Non-Suitable host
list_vm_response = list_virtual_machines(
self.apiclient,
id=vm.id
)
self.assertEqual(
isinstance(list_vm_response, list),
True,
"listVirtualMachine returned invalid object in response."
)
self.assertNotEqual(
len(list_vm_response),
0,
"listVirtualMachines returned empty response."
)
self.assertEqual(
list_vm_response[0].id,
vm.id,
"Virtual machine id with the virtual machine from listVirtualMachine is not matching."
)
self.assertEqual(
list_vm_response[0].hostid,
notSuitableHost.id,
"The detination host id of migrated VM is not matching."
)
def test_05_no_vm_with_ha_gets_migrated_to_ha_host_in_live_migration(self):
""" Verify that none of the VMs with HA enabled migrate to an ha tagged host during live migration """
# Steps,
#1. Fresh install CS (Bonita) that supports this feature
#2. Create Basic zone, pod, cluster, add 3 hosts to cluster (host1, host2, host3), secondary & primary Storage
#3. When adding host3, assign the HA host tag.
#4. Create VMs with and without the Compute Service Offering with the HA tag.
#5. Note the VMs on host1 and whether any of the VMs have their “HA enabled” flags enabled.
#6. Put host1 into maintenance mode.
# Validations,
#1. Make sure the VMs are created on either host1 or host2 and not on host3
#2. Putting host1 into maintenance mode should trigger a live migration. Make sure the VMs are not migrated to HA enabled host3.
# create and verify virtual machine with HA disabled service offering
virtual_machine_with_ha = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.account.name,
domainid=self.account.account.domainid,
serviceofferingid=self.service_offering_with_ha.id
)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine_with_ha.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List VMs should return valid response for deployed VM"
)
self.assertNotEqual(
len(vms),
0,
"List VMs should return valid response for deployed VM"
)
vm_with_ha_enabled = vms[0]
#Verify the virtual machine got created on non HA host
list_hosts_response = list_hosts(
self.apiclient,
id=vm_with_ha_enabled.hostid
)
self.assertEqual(
isinstance(list_hosts_response, list),
True,
"Check list response returns a valid list"
)
self.assertNotEqual(
len(list_hosts_response),
0,
"Check Host is available"
)
self.assertEqual(
list_hosts_response[0].hahost,
False,
"The virtual machine is not ha enabled so check if VM is created on host which is also not ha enabled"
)
#put the Host in maintainance mode
self.debug("Enabling maintenance mode for host %s" % vm_with_ha_enabled.hostid)
cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
cmd.id = vm_with_ha_enabled.hostid
self.apiclient.prepareHostForMaintenance(cmd)
timeout = self.services["timeout"]
#verify the VM live migration happened to another running host
self.debug("Waiting for VM to come up")
wait_for_vm(
self.apiclient,
virtualmachineid=vm_with_ha_enabled.id,
interval=timeout
)
vms = VirtualMachine.list(
self.apiclient,
id=vm_with_ha_enabled.id,
listall=True,
)
self.assertEqual(
isinstance(vms, list),
True,
"List VMs should return valid response for deployed VM"
)
self.assertNotEqual(
len(vms),
0,
"List VMs should return valid response for deployed VM"
)
vm_with_ha_enabled1 = vms[0]
list_hosts_response = list_hosts(
self.apiclient,
id=vm_with_ha_enabled1.hostid
)
self.assertEqual(
isinstance(list_hosts_response, list),
True,
"Check list response returns a valid list"
)
self.assertNotEqual(
len(list_hosts_response),
0,
"Check Host is available"
)
self.assertEqual(
list_hosts_response[0].hahost,
False,
"The virtual machine is not ha enabled so check if VM is created on host which is also not ha enabled"
)
self.debug("Disabling the maintenance mode for host %s" % vm_with_ha_enabled.hostid)
cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
cmd.id = vm_with_ha_enabled.hostid
self.apiclient.cancelHostMaintenance(cmd)
def test_06_no_vm_without_ha_gets_migrated_to_ha_host_in_live_migration(self):
""" Verify that none of the VMs without HA enabled migrate to an ha tagged host during live migration """
# Steps,
#1. Fresh install CS (Bonita) that supports this feature
#2. Create Basic zone, pod, cluster, add 3 hosts to cluster (host1, host2, host3), secondary & primary Storage
#3. When adding host3, assign the HA host tag.
#4. Create VMs with and without the Compute Service Offering with the HA tag.
#5. Note the VMs on host1 and whether any of the VMs have their “HA enabled” flags enabled.
#6. Put host1 into maintenance mode.
# Validations,
#1. Make sure the VMs are created on either host1 or host2 and not on host3
#2. Putting host1 into maintenance mode should trigger a live migration. Make sure the VMs are not migrated to HA enabled host3.
# create and verify virtual machine with HA disabled service offering
virtual_machine_without_ha = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.account.name,
domainid=self.account.account.domainid,
serviceofferingid=self.service_offering_without_ha.id
)
vms = VirtualMachine.list(
self.apiclient,
id=virtual_machine_without_ha.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List VMs should return valid response for deployed VM"
)
self.assertNotEqual(
len(vms),
0,
"List VMs should return valid response for deployed VM"
)
vm_with_ha_disabled = vms[0]
#Verify the virtual machine got created on non HA host
list_hosts_response = list_hosts(
self.apiclient,
id=vm_with_ha_disabled.hostid
)
self.assertEqual(
isinstance(list_hosts_response, list),
True,
"Check list response returns a valid list"
)
self.assertNotEqual(
len(list_hosts_response),
0,
"Check Host is available"
)
self.assertEqual(
list_hosts_response[0].hahost,
False,
"The virtual machine is not ha enabled so check if VM is created on host which is also not ha enabled"
)
#put the Host in maintainance mode
self.debug("Enabling maintenance mode for host %s" % vm_with_ha_disabled.hostid)
cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
cmd.id = vm_with_ha_disabled.hostid
self.apiclient.prepareHostForMaintenance(cmd)
timeout = self.services["timeout"]
#verify the VM live migration happened to another running host
self.debug("Waiting for VM to come up")
wait_for_vm(
self.apiclient,
virtualmachineid=vm_with_ha_disabled.id,
interval=timeout
)
vms = VirtualMachine.list(
self.apiclient,
id=vm_with_ha_disabled.id,
listall=True
)
self.assertEqual(
isinstance(vms, list),
True,
"List VMs should return valid response for deployed VM"
)
self.assertNotEqual(
len(vms),
0,
"List VMs should return valid response for deployed VM"
)
list_hosts_response = list_hosts(
self.apiclient,
id=vms[0].hostid
)
self.assertEqual(
isinstance(list_hosts_response, list),
True,
"Check list response returns a valid list"
)
self.assertNotEqual(
len(list_hosts_response),
0,
"Check Host is available"
)
self.assertEqual(
list_hosts_response[0].hahost,
False,
"The virtual machine is not ha enabled so check if VM is created on host which is also not ha enabled"
)
self.debug("Disabling the maintenance mode for host %s" % vm_with_ha_disabled.hostid)
cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
cmd.id = vm_with_ha_disabled.hostid
self.apiclient.cancelHostMaintenance(cmd)

View File

@ -185,6 +185,27 @@ def wait_for_ssvms(apiclient, zoneid, podid, interval=60):
break
return
def wait_for_vm(apiclient, virtualmachineid, interval=60):
"""After setup wait for VM to come Up"""
time.sleep(interval)
timeout = 40
while True:
list_vm_response = list_virtual_machines(
apiclient,
id=virtualmachineid
)
vm = list_vm_response[0]
if vm.state != 'Running':
# Sleep to ensure VM is Up and Running
time.sleep(interval)
timeout = timeout - 1
elif vm.state == 'Running':
break
elif timeout == 0:
raise Exception("VM failed to come up")
break
return
def download_builtin_templates(apiclient, zoneid, hypervisor, host,
linklocalip, interval=60):

View File

@ -945,7 +945,8 @@
}
},
tags: { label: 'label.storage.tags' },
domain: { label: 'label.domain' }
domain: { label: 'label.domain' },
storagetype: { label: 'label.storage.type' }
}
],

View File

@ -9,7 +9,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
(function($, cloudStack) {
var zoneObjs, hypervisorObjs, featuredTemplateObjs, communityTemplateObjs, myTemplateObjs, featuredIsoObjs, community
var zoneObjs, hypervisorObjs, featuredTemplateObjs, communityTemplateObjs, myTemplateObjs, featuredIsoObjs, community;
var selectedZoneObj, selectedTemplateObj, selectedHypervisor, selectedDiskOfferingObj;
var step5ContainerType = 'nothing-to-select'; //'nothing-to-select', 'select-network', 'select-security-group'
@ -17,6 +17,17 @@
maxDiskOfferingSize: function() {
return g_capabilities.customdiskofferingmaxsize;
},
// Called in networks list, when VPC drop-down is changed
// -- if vpcID given, return true if in network specified by vpcID
// -- if vpcID == -1, return true if network is not associated with a VPC
vpcFilter: function(data, vpcID) {
return vpcID != -1?
data.vpcid == vpcID :
!data.vpcid;
},
// Data providers for each wizard step
steps: [
// Step 1: Setup
function(args) {
@ -301,11 +312,23 @@
networkData.account = g_account;
}
var networkObjs;
var networkObjs, vpcObjs;
// Get VPCs
$.ajax({
url: createURL('listVPCs'),
data: isDomainAdmin() ?
{ account: args.context.users[0].account, domainid: args.context.users[0].domainid } :
{ listAll: true },
async: false,
success: function(json) {
vpcObjs = json.listvpcsresponse.vpc ? json.listvpcsresponse.vpc : [];
}
});
$.ajax({
url: createURL('listNetworks'),
data: networkData,
dataType: "json",
async: false,
success: function(json) {
networkObjs = json.listnetworksresponse.network ? json.listnetworksresponse.network : [];
@ -337,7 +360,8 @@
myNetworks: [], //not used any more
sharedNetworks: networkObjs,
securityGroups: [],
networkOfferings: networkOfferingObjs
networkOfferings: networkOfferingObjs,
vpcs: vpcObjs
}
});
}
@ -370,7 +394,8 @@
myNetworks: [], //not used any more
sharedNetworks: [],
securityGroups: securityGroupArray,
networkOfferings: []
networkOfferings: [],
vpcs: []
}
});
}
@ -382,7 +407,8 @@
myNetworks: [], //not used any more
sharedNetworks: [],
securityGroups: [],
networkOfferings: []
networkOfferings: [],
vpcs: []
}
});
}

View File

@ -1405,9 +1405,10 @@
args.$tierSelect.hide();
}
// args.$tierSelect.change(function() {
args.$tierSelect.change(function() {
args.$tierSelect.closest('.list-view').listView('refresh');
// });
});
args.$tierSelect.closest('.list-view').listView('refresh');
},
listView: $.extend(true, {}, cloudStack.sections.instances, {
@ -3858,10 +3859,22 @@
},
{
displaytext: { label: 'label.description', isEditable: true },
account: { label: 'label.account' },
domain: { label: 'label.domain' },
zonename: { label: 'label.zone' },
cidr: { label: 'label.cidr' },
networkdomain: { label: 'label.network.domain' },
state: { label: 'label.state' },
restartrequired: {
label: 'label.restart.required',
converter: function(booleanValue) {
if (booleanValue == true) {
return "<font color='red'>Yes</font>";
}
return "No";
}
},
id: { label: 'label.id' }
}
],

View File

@ -103,6 +103,14 @@
.click(function() {
var $radio = $(this).closest('.select').find('input[type=radio]');
if ($(this).attr('type') == 'checkbox') {
if ($(this).closest('.select-container').hasClass('single-select')) {
$(this).closest('.select').siblings().find('input[type=checkbox]')
.attr('checked', false);
$(this).closest('.select').find('input[type=radio]').click();
}
}
if ($radio.is(':checked') && !$(this).is(':checked')) {
if (!$radio.closest('.select').index()) {
return false;
@ -121,7 +129,8 @@
$('<div>').addClass('select-desc')
.append($('<div>').addClass('name').html(this[fields.name]))
.append($('<div>').addClass('desc').html(this[fields.desc]))
);
)
.data('json-obj', this);
$selects.append($select);
@ -139,6 +148,11 @@
if (!$checkbox.is(':checked')) {
$checkbox.attr('checked', true);
}
if ($(this).closest('.select-container').hasClass('single-select')) {
$(this).closest('.select').siblings().find('input[type=checkbox]')
.attr('checked', false);
}
})
.after(
$('<div>').addClass('name').html(options.secondary.desc)
@ -480,9 +494,81 @@
// Show relevant conditional sub-step if present
$step.find('.wizard-step-conditional').hide();
// Filter network list by VPC ID
var filterNetworkList = function(vpcID) {
var $selects = $step.find('.my-networks .select-container .select');
var $visibleSelects = $($.grep($selects, function(select) {
var $select = $(select);
return args.vpcFilter($select.data('json-obj'), vpcID);
}));
var $addNetworkForm = $step.find('.select.new-network');
var $addNewNetworkCheck = $addNetworkForm.find('input[name=new-network]');
// VPC networks cannot be created via instance wizard
if (vpcID != -1) {
$step.find('.my-networks .select-container').addClass('single-select');
$addNetworkForm.hide();
if ($addNewNetworkCheck.is(':checked')) {
$addNewNetworkCheck.click();
$addNewNetworkCheck.attr('checked', false);
}
} else {
$step.find('.my-networks .select-container').removeClass('single-select');
$addNetworkForm.show();
}
$selects.find('input[type=checkbox]').attr('checked', false);
$selects.hide();
$visibleSelects.show();
// Select first visible item by default
$visibleSelects.filter(':first')
.find('input[type=radio]')
.click();
cloudStack.evenOdd($visibleSelects, 'div.select', {
even: function($elem) {
$elem.removeClass('odd');
$elem.addClass('even');
},
odd: function($elem) {
$elem.removeClass('even');
$elem.addClass('odd');
}
});
};
var $vpcSelect = $step.find('select[name=vpc-filter]');
$vpcSelect.unbind('change');
$vpcSelect.change(function() {
filterNetworkList($vpcSelect.val());
});
return {
response: {
success: function(args) {
var vpcs = args.data.vpcs;
// Populate VPC drop-down
$vpcSelect.html('');
$(vpcs).map(function(index, vpc) {
var $option = $('<option>');
var id = vpc.id;
var description = vpc.name;
$option.attr('value', id);
$option.html(description);
$option.appendTo($vpcSelect);
});
// 'No VPC' option
$('<option>').attr('value', '-1').html('None').prependTo($vpcSelect);
$vpcSelect.val(-1);
// Populate network offering drop-down
$(args.data.networkOfferings).each(function() {
$('<option>')
@ -516,6 +602,9 @@
})
);
// Show non-VPC networks by default
filterNetworkList(-1);
// Security groups (alt. page)
$step.find('.security-groups .select-container').append(
makeSelects('security-groups', args.data.securityGroups, {

View File

@ -18,7 +18,7 @@
var siteToSiteVPN = args.siteToSiteVPN;
var links = {
'ip-addresses': 'IP Addresses',
'gateways': 'Gateways',
'gateways': 'Private Gateway',
'site-to-site-vpn': 'Site-to-site VPN'
};
var $links = $('<ul>').addClass('links');
@ -48,14 +48,62 @@
});
break;
case 'gateways':
$browser.cloudBrowser('addPanel', {
title: 'Gateways',
maximizeIfSelected: true,
complete: function($panel) {
//ipAddresses.listView is a function
$panel.listView(gateways.listView(), {context: gateways.context});
}
});
//siteToSiteVPN is an object
var addAction = gateways.add;
var isGatewayPresent = addAction.preCheck({ context: gateways.context });
var showGatewayListView = function() {
$browser.cloudBrowser('addPanel', {
title: 'Private Gateway',
maximizeIfSelected: true,
complete: function($panel) {
$panel.listView(gateways.listView(), { context: gateways.context });
}
});
};
if (isGatewayPresent) {
showGatewayListView();
} else {
cloudStack.dialog.createForm({
form: addAction.createForm,
after: function(args) {
var data = args.data;
var $loading = $('<div>').addClass('loading-overlay').appendTo($chart);
var error = function(message) {
$loading.remove();
cloudStack.dialog.notice({ message: message });
};
addAction.action({
data: data,
context: gateways.context,
response: {
success: function(args) {
var _custom = args._custom;
var notification = {
poll: addAction.notification.poll,
_custom: _custom,
desc: addAction.messages.notification()
};
var success = function(args) {
if (!$chart.is(':visible')) return;
$loading.remove();
showGatewayListView();
};
cloudStack.ui.notifications.add(
notification,
success, {},
error, {}
);
},
error: error
}
});
}
});
}
break;
case 'site-to-site-vpn':
//siteToSiteVPN is an object
@ -63,7 +111,7 @@
var isVPNPresent = addAction.preCheck({ context: siteToSiteVPN.context });
var showVPNListView = function() {
$browser.cloudBrowser('addPanel', {
title: 'Site-to-site VPNs',
title: 'Site-to-site VPN',
maximizeIfSelected: true,
complete: function($panel) {
$panel.listView(siteToSiteVPN, {context: siteToSiteVPN.context});
@ -105,7 +153,8 @@
success, {},
error, {}
);
}
},
error: error
}
});
}

View File

@ -437,6 +437,76 @@
}
},
gateways: {
add: {
preCheck: function(args) {
var items;
$.ajax({
url: createURL('listPrivateGateways'),
async: false,
data: {
vpcid: args.context.vpc[0].id,
listAll: true
},
success: function(json) {
items = json.listprivategatewaysresponse.privategateway;
args.response.success({ data: items });
}
});
if (items && items.length) {
return true;
}
return false;
},
label: 'Add new gateway',
messages: {
notification: function(args) {
return 'Add new gateway';
}
},
createForm: {
title: 'Add new gateway',
desc: 'Please specify the information to add a new gateway to this VPC.',
fields: {
vlan: { label: 'label.vlan', validation: { required: true }},
ipaddress: { label: 'label.ip.address', validation: { required: true }},
gateway: { label: 'label.gateway', validation: { required: true }},
netmask: { label: 'label.netmask', validation: { required: true }}
}
},
action: function(args) {
$.ajax({
url: createURL('createPrivateGateway'),
data: {
vpcid: args.context.vpc[0].id,
ipaddress: args.data.ipaddress,
gateway: args.data.gateway,
netmask: args.data.netmask,
vlan: args.data.vlan
},
success: function(json) {
var jid = json.createprivategatewayresponse.jobid;
args.response.success(
{_custom:
{jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.privategateway;
}
}
}
);
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
listView: function() {
return {
listView: {
@ -447,62 +517,6 @@
netmask: { label: 'label.netmask', validation: { required: true }},
vlan: { label: 'label.vlan', validation: { required: true }}
},
actions: {
add: {
label: 'Add new gateway',
preFilter: function(args) {
if(isAdmin())
return true;
else
return false;
},
messages: {
notification: function(args) {
return 'Add new gateway';
}
},
createForm: {
title: 'Add new gateway',
desc: 'Please specify the information to add a new gateway to this VPC.',
fields: {
ipaddress: { label: 'label.ip.address', validation: { required: true }},
gateway: { label: 'label.gateway', validation: { required: true }},
netmask: { label: 'label.netmask', validation: { required: true }},
vlan: { label: 'label.vlan', validation: { required: true }}
}
},
action: function(args) {
$.ajax({
url: createURL('createPrivateGateway'),
data: {
vpcid: args.context.vpc[0].id,
ipaddress: args.data.ipaddress,
gateway: args.data.gateway,
netmask: args.data.netmask,
vlan: args.data.vlan
},
success: function(json) {
var jid = json.createprivategatewayresponse.jobid;
args.response.success(
{_custom:
{jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.privategateway;
}
}
}
);
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
dataProvider: function(args) {
$.ajax({
url: createURL('listPrivateGateways'),