use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class DedicatedResourceManagerImpl method dedicateZone.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Zone")
public List<DedicatedResourceVO> dedicateZone(final Long zoneId, final Long domainId, final String accountName) {
Long accountId = null;
List<HostVO> hosts = null;
if (accountName != null) {
Account caller = CallContext.current().getCallingAccount();
Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
accountId = owner.getId();
}
List<Long> childDomainIds = getDomainChildIds(domainId);
childDomainIds.add(domainId);
checkAccountAndDomain(accountId, domainId);
final DataCenterVO dc = _zoneDao.findById(zoneId);
if (dc == null) {
throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
} else {
DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zoneId);
//check if zone is dedicated
if (dedicatedZone != null) {
s_logger.error("Zone " + dc.getName() + " is already dedicated");
throw new CloudRuntimeException("Zone " + dc.getName() + " is already dedicated");
}
//check if any resource under this zone is dedicated to different account or sub-domain
List<HostPodVO> pods = _podDao.listByDataCenterId(dc.getId());
List<DedicatedResourceVO> podsToRelease = new ArrayList<DedicatedResourceVO>();
List<DedicatedResourceVO> clustersToRelease = new ArrayList<DedicatedResourceVO>();
List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
for (HostPodVO pod : pods) {
DedicatedResourceVO dPod = _dedicatedDao.findByPodId(pod.getId());
if (dPod != null) {
if (!(childDomainIds.contains(dPod.getDomainId()))) {
throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
if (accountId != null) {
if (dPod.getAccountId().equals(accountId)) {
podsToRelease.add(dPod);
} else {
s_logger.error("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
} else {
if (dPod.getAccountId() == null && dPod.getDomainId().equals(domainId)) {
podsToRelease.add(dPod);
}
}
}
}
for (DedicatedResourceVO dr : podsToRelease) {
releaseDedicatedResource(null, dr.getPodId(), null, null);
}
List<ClusterVO> clusters = _clusterDao.listClustersByDcId(dc.getId());
for (ClusterVO cluster : clusters) {
DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
if (dCluster != null) {
if (!(childDomainIds.contains(dCluster.getDomainId()))) {
throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
if (accountId != null) {
if (dCluster.getAccountId().equals(accountId)) {
clustersToRelease.add(dCluster);
} else {
s_logger.error("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
} else {
if (dCluster.getAccountId() == null && dCluster.getDomainId().equals(domainId)) {
clustersToRelease.add(dCluster);
}
}
}
}
for (DedicatedResourceVO dr : clustersToRelease) {
releaseDedicatedResource(null, null, dr.getClusterId(), null);
}
hosts = _hostDao.listByDataCenterId(dc.getId());
for (HostVO host : hosts) {
DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
if (dHost != null) {
if (!(childDomainIds.contains(dHost.getDomainId()))) {
throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
if (accountId != null) {
if (dHost.getAccountId().equals(accountId)) {
hostsToRelease.add(dHost);
} else {
s_logger.error("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
}
} else {
if (dHost.getAccountId() == null && dHost.getDomainId().equals(domainId)) {
hostsToRelease.add(dHost);
}
}
}
}
for (DedicatedResourceVO dr : hostsToRelease) {
releaseDedicatedResource(null, null, null, dr.getHostId());
}
}
checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
final Long accountIdFinal = accountId;
return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
@Override
public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
// find or create the affinity group by name under this account/domain
AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
if (group == null) {
s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
}
DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null, group.getId());
try {
dedicatedResource.setDomainId(domainId);
if (accountIdFinal != null) {
dedicatedResource.setAccountId(accountIdFinal);
}
dedicatedResource = _dedicatedDao.persist(dedicatedResource);
// save the domainId in the zone
dc.setDomainId(domainId);
if (!_zoneDao.update(zoneId, dc)) {
throw new CloudRuntimeException("Failed to dedicate zone, could not set domainId. Please contact Cloud Support.");
}
} catch (Exception e) {
s_logger.error("Unable to dedicate zone due to " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
}
List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
result.add(dedicatedResource);
return result;
}
});
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class GlobalLoadBalancingRulesServiceImpl method revokeGslbRule.
@DB
private void revokeGslbRule(final long gslbRuleId, Account caller) {
final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
if (gslbRule == null) {
throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
}
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
if (gslbRule.getState() == com.cloud.region.ha.GlobalLoadBalancerRule.State.Staged) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Rule Id: " + gslbRuleId + " is still in Staged state so just removing it.");
}
_gslbRuleDao.remove(gslbRuleId);
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), 0, gslbRule.getId(), gslbRule.getName(), GlobalLoadBalancerRule.class.getName(), gslbRule.getUuid());
return;
} else if (gslbRule.getState() == GlobalLoadBalancerRule.State.Add || gslbRule.getState() == GlobalLoadBalancerRule.State.Active) {
//mark the GSlb rule to be in revoke state
gslbRule.setState(GlobalLoadBalancerRule.State.Revoke);
_gslbRuleDao.update(gslbRuleId, gslbRule);
}
final List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = Transaction.execute(new TransactionCallback<List<GlobalLoadBalancerLbRuleMapVO>>() {
@Override
public List<GlobalLoadBalancerLbRuleMapVO> doInTransaction(TransactionStatus status) {
List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
if (gslbLbMapVos != null) {
//mark all the GSLB-LB mapping to be in revoke state
for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) {
gslbLbMap.setRevoke(true);
_gslbLbMapDao.update(gslbLbMap.getId(), gslbLbMap);
}
}
return gslbLbMapVos;
}
});
boolean success = false;
try {
if (gslbLbMapVos != null) {
applyGlobalLoadBalancerRuleConfig(gslbRuleId, true);
}
success = true;
} catch (ResourceUnavailableException e) {
throw new CloudRuntimeException("Failed to update the gloabal load balancer");
}
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
//remove all mappings between GSLB rule and load balancer rules
if (gslbLbMapVos != null) {
for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) {
_gslbLbMapDao.remove(gslbLbMap.getId());
}
}
//remove the GSLB rule itself
_gslbRuleDao.remove(gslbRuleId);
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), 0, gslbRule.getId(), gslbRule.getName(), GlobalLoadBalancerRule.class.getName(), gslbRule.getUuid());
}
});
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class GlobalLoadBalancingRulesServiceImpl method assignToGlobalLoadBalancerRule.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_GLOBAL_LOAD_BALANCER_RULE, eventDescription = "Assigning a load balancer rule to global load balancer rule", async = true)
public boolean assignToGlobalLoadBalancerRule(AssignToGlobalLoadBalancerRuleCmd assignToGslbCmd) {
CallContext ctx = CallContext.current();
Account caller = ctx.getCallingAccount();
final long gslbRuleId = assignToGslbCmd.getGlobalLoadBalancerRuleId();
final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
if (gslbRule == null) {
throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
}
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
if (gslbRule.getState() == GlobalLoadBalancerRule.State.Revoke) {
throw new InvalidParameterValueException("global load balancer rule id: " + gslbRule.getUuid() + " is in revoked state");
}
final List<Long> newLbRuleIds = assignToGslbCmd.getLoadBalancerRulesIds();
if (newLbRuleIds == null || newLbRuleIds.isEmpty()) {
throw new InvalidParameterValueException("empty list of load balancer rule Ids specified to be assigned" + " global load balancer rule");
}
List<Long> oldLbRuleIds = new ArrayList<Long>();
List<Long> oldZones = new ArrayList<Long>();
List<Long> newZones = new ArrayList<Long>(oldZones);
List<Pair<Long, Long>> physcialNetworks = new ArrayList<Pair<Long, Long>>();
// get the list of load balancer rules id's that are assigned currently to GSLB rule and corresponding zone id's
List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
if (gslbLbMapVos != null) {
for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
Network network = _networkDao.findById(loadBalancer.getNetworkId());
oldZones.add(network.getDataCenterId());
oldLbRuleIds.add(gslbLbMapVo.getLoadBalancerId());
}
}
/* check each of the load balancer rule id passed in the 'AssignToGlobalLoadBalancerRuleCmd' command is
* valid ID
* caller has access to the rule
* check rule is not revoked
* no two rules are in same zone
* rule is not already assigned to gslb rule
*/
for (Long lbRuleId : newLbRuleIds) {
LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
if (loadBalancer == null) {
throw new InvalidParameterValueException("Specified load balancer rule ID does not exist.");
}
_accountMgr.checkAccess(caller, null, true, loadBalancer);
if (gslbRule.getAccountId() != loadBalancer.getAccountId()) {
throw new InvalidParameterValueException("GSLB rule and load balancer rule does not belong to same account");
}
if (loadBalancer.getState() == LoadBalancer.State.Revoke) {
throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is in revoke state");
}
if (oldLbRuleIds != null && oldLbRuleIds.contains(loadBalancer.getId())) {
throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is already assigned");
}
Network network = _networkDao.findById(loadBalancer.getNetworkId());
if (oldZones != null && oldZones.contains(network.getDataCenterId()) || newZones != null && newZones.contains(network.getDataCenterId())) {
throw new InvalidParameterValueException("Load balancer rule specified should be in unique zone");
}
newZones.add(network.getDataCenterId());
physcialNetworks.add(new Pair<Long, Long>(network.getDataCenterId(), network.getPhysicalNetworkId()));
}
// for each of the physical network check if GSLB service provider configured
for (Pair<Long, Long> physicalNetwork : physcialNetworks) {
if (!checkGslbServiceEnabledInZone(physicalNetwork.first(), physicalNetwork.second())) {
throw new InvalidParameterValueException("GSLB service is not enabled in the Zone:" + physicalNetwork.first() + " and physical network " + physicalNetwork.second());
}
}
final Map<Long, Long> lbRuleWeightMap = assignToGslbCmd.getLoadBalancerRuleWeightMap();
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
// persist the mapping for the new Lb rule that needs to assigned to a gslb rule
for (Long lbRuleId : newLbRuleIds) {
GlobalLoadBalancerLbRuleMapVO newGslbLbMap = new GlobalLoadBalancerLbRuleMapVO();
newGslbLbMap.setGslbLoadBalancerId(gslbRuleId);
newGslbLbMap.setLoadBalancerId(lbRuleId);
if (lbRuleWeightMap != null && lbRuleWeightMap.get(lbRuleId) != null) {
newGslbLbMap.setWeight(lbRuleWeightMap.get(lbRuleId));
}
_gslbLbMapDao.persist(newGslbLbMap);
}
// mark the gslb rule state as add
if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged || gslbRule.getState() == GlobalLoadBalancerRule.State.Active) {
gslbRule.setState(GlobalLoadBalancerRule.State.Add);
_gslbRuleDao.update(gslbRule.getId(), gslbRule);
}
}
});
boolean success = false;
try {
s_logger.debug("Configuring gslb rule configuration on the gslb service providers in the participating zones");
// apply the gslb rule on to the back end gslb service providers on zones participating in gslb
if (!applyGlobalLoadBalancerRuleConfig(gslbRuleId, false)) {
s_logger.warn("Failed to add load balancer rules " + newLbRuleIds + " to global load balancer rule id " + gslbRuleId);
CloudRuntimeException ex = new CloudRuntimeException("Failed to add load balancer rules to GSLB rule ");
throw ex;
}
// on success set state to Active
gslbRule.setState(GlobalLoadBalancerRule.State.Active);
_gslbRuleDao.update(gslbRule.getId(), gslbRule);
success = true;
} catch (ResourceUnavailableException e) {
throw new CloudRuntimeException("Failed to apply new GSLB configuration while assigning new LB rules to GSLB rule.");
}
return success;
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class GlobalLoadBalancingRulesServiceImpl method createGlobalLoadBalancerRule.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, eventDescription = "creating global load " + "balancer rule", create = true)
public GlobalLoadBalancerRule createGlobalLoadBalancerRule(CreateGlobalLoadBalancerRuleCmd newRule) {
final Integer regionId = newRule.getRegionId();
final String algorithm = newRule.getAlgorithm();
final String stickyMethod = newRule.getStickyMethod();
final String name = newRule.getName();
final String description = newRule.getDescription();
final String domainName = newRule.getServiceDomainName();
final String serviceType = newRule.getServiceType();
final Account gslbOwner = _accountMgr.getAccount(newRule.getEntityOwnerId());
if (!GlobalLoadBalancerRule.Algorithm.isValidAlgorithm(algorithm)) {
throw new InvalidParameterValueException("Invalid Algorithm: " + algorithm);
}
if (!GlobalLoadBalancerRule.Persistence.isValidPersistence(stickyMethod)) {
throw new InvalidParameterValueException("Invalid persistence: " + stickyMethod);
}
if (!GlobalLoadBalancerRule.ServiceType.isValidServiceType(serviceType)) {
throw new InvalidParameterValueException("Invalid service type: " + serviceType);
}
if (!NetUtils.verifyDomainName(domainName)) {
throw new InvalidParameterValueException("Invalid domain name : " + domainName);
}
GlobalLoadBalancerRuleVO gslbRuleWithDomainName = _gslbRuleDao.findByDomainName(domainName);
if (gslbRuleWithDomainName != null) {
throw new InvalidParameterValueException("Domain name " + domainName + "is in use");
}
Region region = _regionDao.findById(regionId);
if (region == null) {
throw new InvalidParameterValueException("Invalid region ID: " + regionId);
}
String providerDnsName = _globalConfigDao.getValue(Config.CloudDnsName.key());
if (!region.checkIfServiceEnabled(Region.Service.Gslb) || (providerDnsName == null)) {
throw new CloudRuntimeException("GSLB service is not enabled in region : " + region.getName());
}
GlobalLoadBalancerRuleVO newGslbRule = Transaction.execute(new TransactionCallback<GlobalLoadBalancerRuleVO>() {
@Override
public GlobalLoadBalancerRuleVO doInTransaction(TransactionStatus status) {
GlobalLoadBalancerRuleVO newGslbRule = new GlobalLoadBalancerRuleVO(name, description, domainName, algorithm, stickyMethod, serviceType, regionId, gslbOwner.getId(), gslbOwner.getDomainId(), GlobalLoadBalancerRule.State.Staged);
_gslbRuleDao.persist(newGslbRule);
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, newGslbRule.getAccountId(), 0, newGslbRule.getId(), name, GlobalLoadBalancerRule.class.getName(), newGslbRule.getUuid());
return newGslbRule;
}
});
s_logger.debug("successfully created new global load balancer rule for the account " + gslbOwner.getId());
return newGslbRule;
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class UserVmManagerImpl method moveVMToUser.
@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false)
public UserVm moveVMToUser(final AssignVMCmd cmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
// VERIFICATIONS and VALIDATIONS
// VV 1: verify the two users
Account caller = CallContext.current().getCallingAccount();
if (!_accountMgr.isRootAdmin(caller.getId()) && !_accountMgr.isDomainAdmin(caller.getId())) {
// VMs
throw new InvalidParameterValueException("Only domain admins are allowed to assign VMs and not " + caller.getType());
}
// get and check the valid VM
final UserVmVO vm = _vmDao.findById(cmd.getVmId());
if (vm == null) {
throw new InvalidParameterValueException("There is no vm by that id " + cmd.getVmId());
} else if (vm.getState() == State.Running) {
// running
if (s_logger.isDebugEnabled()) {
s_logger.debug("VM is Running, unable to move the vm " + vm);
}
InvalidParameterValueException ex = new InvalidParameterValueException("VM is Running, unable to move the vm with specified vmId");
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
final Account oldAccount = _accountService.getActiveAccountById(vm.getAccountId());
if (oldAccount == null) {
throw new InvalidParameterValueException("Invalid account for VM " + vm.getAccountId() + " in domain.");
}
final Account newAccount = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
if (newAccount == null) {
throw new InvalidParameterValueException("Invalid accountid=" + cmd.getAccountName() + " in domain " + cmd.getDomainId());
}
if (newAccount.getState() == Account.State.disabled) {
throw new InvalidParameterValueException("The new account owner " + cmd.getAccountName() + " is disabled.");
}
//check caller has access to both the old and new account
_accountMgr.checkAccess(caller, null, true, oldAccount);
_accountMgr.checkAccess(caller, null, true, newAccount);
// make sure the accounts are not same
if (oldAccount.getAccountId() == newAccount.getAccountId()) {
throw new InvalidParameterValueException("The new account is the same as the old account. Account id =" + oldAccount.getAccountId());
}
// don't allow to move the vm if there are existing PF/LB/Static Nat
// rules, or vm is assigned to static Nat ip
List<PortForwardingRuleVO> pfrules = _portForwardingDao.listByVm(cmd.getVmId());
if (pfrules != null && pfrules.size() > 0) {
throw new InvalidParameterValueException("Remove the Port forwarding rules for this VM before assigning to another user.");
}
List<FirewallRuleVO> snrules = _rulesDao.listStaticNatByVmId(vm.getId());
if (snrules != null && snrules.size() > 0) {
throw new InvalidParameterValueException("Remove the StaticNat rules for this VM before assigning to another user.");
}
List<LoadBalancerVMMapVO> maps = _loadBalancerVMMapDao.listByInstanceId(vm.getId());
if (maps != null && maps.size() > 0) {
throw new InvalidParameterValueException("Remove the load balancing rules for this VM before assigning to another user.");
}
// check for one on one nat
List<IPAddressVO> ips = _ipAddressDao.findAllByAssociatedVmId(cmd.getVmId());
for (IPAddressVO ip : ips) {
if (ip.isOneToOneNat()) {
throw new InvalidParameterValueException("Remove the one to one nat rule for this VM for ip " + ip.toString());
}
}
DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
// Get serviceOffering and Volumes for Virtual Machine
final ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
final List<VolumeVO> volumes = _volsDao.findByInstance(cmd.getVmId());
//Remove vm from instance group
removeInstanceFromInstanceGroup(cmd.getVmId());
// VV 2: check if account/domain is with in resource limits to create a new vm
resourceLimitCheck(newAccount, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
// VV 3: check if volumes and primary storage space are with in resource limits
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume, _volsDao.findByInstance(cmd.getVmId()).size());
Long totalVolumesSize = (long) 0;
for (VolumeVO volume : volumes) {
totalVolumesSize += volume.getSize();
}
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.primary_storage, totalVolumesSize);
// VV 4: Check if new owner can use the vm template
VirtualMachineTemplate template = _templateDao.findById(vm.getTemplateId());
if (!template.isPublicTemplate()) {
Account templateOwner = _accountMgr.getAccount(template.getAccountId());
_accountMgr.checkAccess(newAccount, null, true, templateOwner);
}
// VV 5: check the new account can create vm in the domain
DomainVO domain = _domainDao.findById(cmd.getDomainId());
_accountMgr.checkAccess(newAccount, domain);
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
//generate destroy vm event for usage
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
// update resource counts for old account
resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
// OWNERSHIP STEP 1: update the vm owner
vm.setAccountId(newAccount.getAccountId());
vm.setDomainId(cmd.getDomainId());
_vmDao.persist(vm);
// OS 2: update volume
for (VolumeVO volume : volumes) {
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
volume.setAccountId(newAccount.getAccountId());
volume.setDomainId(newAccount.getDomainId());
_volsDao.persist(volume);
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
//snapshots: mark these removed in db
List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId());
for (SnapshotVO snapshot : snapshots) {
_snapshotDao.remove(snapshot.getId());
}
}
//update resource count of new account
resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
//generate usage events to account for this change
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
}
});
VirtualMachine vmoi = _itMgr.findById(vm.getId());
VirtualMachineProfileImpl vmOldProfile = new VirtualMachineProfileImpl(vmoi);
// OS 3: update the network
List<Long> networkIdList = cmd.getNetworkIds();
List<Long> securityGroupIdList = cmd.getSecurityGroupIdList();
if (zone.getNetworkType() == NetworkType.Basic) {
if (networkIdList != null && !networkIdList.isEmpty()) {
throw new InvalidParameterValueException("Can't move vm with network Ids; this is a basic zone VM");
}
// cleanup the old security groups
_securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
// cleanup the network for the oldOwner
_networkMgr.cleanupNics(vmOldProfile);
_networkMgr.expungeNics(vmOldProfile);
// security groups will be recreated for the new account, when the
// VM is started
List<NetworkVO> networkList = new ArrayList<NetworkVO>();
// Get default guest network in Basic zone
Network defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
if (defaultNetwork == null) {
throw new InvalidParameterValueException("Unable to find a default network to start a vm");
} else {
networkList.add(_networkDao.findById(defaultNetwork.getId()));
}
boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware);
if (securityGroupIdList != null && isVmWare) {
throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
} else if (!isVmWare && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
if (securityGroupIdList == null) {
securityGroupIdList = new ArrayList<Long>();
}
SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(newAccount.getId());
if (defaultGroup != null) {
// check if security group id list already contains Default
// security group, and if not - add it
boolean defaultGroupPresent = false;
for (Long securityGroupId : securityGroupIdList) {
if (securityGroupId.longValue() == defaultGroup.getId()) {
defaultGroupPresent = true;
break;
}
}
if (!defaultGroupPresent) {
securityGroupIdList.add(defaultGroup.getId());
}
} else {
// create default security group for the account
if (s_logger.isDebugEnabled()) {
s_logger.debug("Couldn't find default security group for the account " + newAccount + " so creating a new one");
}
defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION, newAccount.getDomainId(), newAccount.getId(), newAccount.getAccountName());
securityGroupIdList.add(defaultGroup.getId());
}
}
LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
NicProfile profile = new NicProfile();
profile.setDefaultNic(true);
networks.put(networkList.get(0), new ArrayList<NicProfile>(Arrays.asList(profile)));
VirtualMachine vmi = _itMgr.findById(vm.getId());
VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
_networkMgr.allocate(vmProfile, networks);
_securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
s_logger.debug("AssignVM: Basic zone, adding security groups no " + securityGroupIdList.size() + " to " + vm.getInstanceName());
} else {
if (zone.isSecurityGroupEnabled()) {
// advanced zone with security groups
// cleanup the old security groups
_securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
Set<NetworkVO> applicableNetworks = new HashSet<NetworkVO>();
String requestedIPv4ForDefaultNic = null;
String requestedIPv6ForDefaultNic = null;
// if networkIdList is null and the first network of vm is shared network, then keep it if possible
if (networkIdList == null || networkIdList.isEmpty()) {
NicVO defaultNicOld = _nicDao.findDefaultNicForVM(vm.getId());
if (defaultNicOld != null) {
NetworkVO defaultNetworkOld = _networkDao.findById(defaultNicOld.getNetworkId());
if (defaultNetworkOld != null && defaultNetworkOld.getGuestType() == Network.GuestType.Shared && defaultNetworkOld.getAclType() == ACLType.Domain) {
try {
_networkModel.checkNetworkPermissions(newAccount, defaultNetworkOld);
applicableNetworks.add(defaultNetworkOld);
requestedIPv4ForDefaultNic = defaultNicOld.getIPv4Address();
requestedIPv6ForDefaultNic = defaultNicOld.getIPv6Address();
s_logger.debug("AssignVM: use old shared network " + defaultNetworkOld.getName() + " with old ip " + requestedIPv4ForDefaultNic + " on default nic of vm:" + vm.getInstanceName());
} catch (PermissionDeniedException e) {
s_logger.debug("AssignVM: the shared network on old default nic can not be applied to new account");
}
}
}
}
// cleanup the network for the oldOwner
_networkMgr.cleanupNics(vmOldProfile);
_networkMgr.expungeNics(vmOldProfile);
if (networkIdList != null && !networkIdList.isEmpty()) {
// add any additional networks
for (Long networkId : networkIdList) {
NetworkVO network = _networkDao.findById(networkId);
if (network == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find specified network id");
ex.addProxyObject(networkId.toString(), "networkId");
throw ex;
}
_networkModel.checkNetworkPermissions(newAccount, network);
// don't allow to use system networks
NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
if (networkOffering.isSystemOnly()) {
InvalidParameterValueException ex = new InvalidParameterValueException("Specified Network id is system only and can't be used for vm deployment");
ex.addProxyObject(network.getUuid(), "networkId");
throw ex;
}
applicableNetworks.add(network);
}
}
// add the new nics
LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
int toggle = 0;
NetworkVO defaultNetwork = null;
for (NetworkVO appNet : applicableNetworks) {
NicProfile defaultNic = new NicProfile();
if (toggle == 0) {
defaultNic.setDefaultNic(true);
defaultNic.setRequestedIPv4(requestedIPv4ForDefaultNic);
defaultNic.setRequestedIPv6(requestedIPv6ForDefaultNic);
defaultNetwork = appNet;
toggle++;
}
networks.put(appNet, new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
}
boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware);
if (securityGroupIdList != null && isVmWare) {
throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
} else if (!isVmWare && (defaultNetwork == null || _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork)) && _networkModel.canAddDefaultSecurityGroup()) {
if (securityGroupIdList == null) {
securityGroupIdList = new ArrayList<Long>();
}
SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(newAccount.getId());
if (defaultGroup != null) {
// check if security group id list already contains Default
// security group, and if not - add it
boolean defaultGroupPresent = false;
for (Long securityGroupId : securityGroupIdList) {
if (securityGroupId.longValue() == defaultGroup.getId()) {
defaultGroupPresent = true;
break;
}
}
if (!defaultGroupPresent) {
securityGroupIdList.add(defaultGroup.getId());
}
} else {
// create default security group for the account
if (s_logger.isDebugEnabled()) {
s_logger.debug("Couldn't find default security group for the account " + newAccount + " so creating a new one");
}
defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION, newAccount.getDomainId(), newAccount.getId(), newAccount.getAccountName());
securityGroupIdList.add(defaultGroup.getId());
}
}
VirtualMachine vmi = _itMgr.findById(vm.getId());
VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
if (applicableNetworks.isEmpty()) {
throw new InvalidParameterValueException("No network is specified, please specify one when you move the vm. For now, please add a network to VM on NICs tab.");
} else {
_networkMgr.allocate(vmProfile, networks);
}
_securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
s_logger.debug("AssignVM: Advanced zone, adding security groups no " + securityGroupIdList.size() + " to " + vm.getInstanceName());
} else {
if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) {
throw new InvalidParameterValueException("Can't move vm with security groups; security group feature is not enabled in this zone");
}
Set<NetworkVO> applicableNetworks = new HashSet<NetworkVO>();
// if networkIdList is null and the first network of vm is shared network, then keep it if possible
if (networkIdList == null || networkIdList.isEmpty()) {
NicVO defaultNicOld = _nicDao.findDefaultNicForVM(vm.getId());
if (defaultNicOld != null) {
NetworkVO defaultNetworkOld = _networkDao.findById(defaultNicOld.getNetworkId());
if (defaultNetworkOld != null && defaultNetworkOld.getGuestType() == Network.GuestType.Shared && defaultNetworkOld.getAclType() == ACLType.Domain) {
try {
_networkModel.checkNetworkPermissions(newAccount, defaultNetworkOld);
applicableNetworks.add(defaultNetworkOld);
} catch (PermissionDeniedException e) {
s_logger.debug("AssignVM: the shared network on old default nic can not be applied to new account");
}
}
}
}
// cleanup the network for the oldOwner
_networkMgr.cleanupNics(vmOldProfile);
_networkMgr.expungeNics(vmOldProfile);
if (networkIdList != null && !networkIdList.isEmpty()) {
// add any additional networks
for (Long networkId : networkIdList) {
NetworkVO network = _networkDao.findById(networkId);
if (network == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find specified network id");
ex.addProxyObject(networkId.toString(), "networkId");
throw ex;
}
_networkModel.checkNetworkPermissions(newAccount, network);
// don't allow to use system networks
NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
if (networkOffering.isSystemOnly()) {
InvalidParameterValueException ex = new InvalidParameterValueException("Specified Network id is system only and can't be used for vm deployment");
ex.addProxyObject(network.getUuid(), "networkId");
throw ex;
}
applicableNetworks.add(network);
}
} else if (applicableNetworks.isEmpty()) {
NetworkVO defaultNetwork = null;
List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
if (requiredOfferings.size() < 1) {
throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required + " to automatically create the network as a part of vm creation");
}
if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
// get Virtual networks
List<? extends Network> virtualNetworks = _networkModel.listNetworksForAccount(newAccount.getId(), zone.getId(), Network.GuestType.Isolated);
if (virtualNetworks.isEmpty()) {
long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
// Validate physical network
PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
if (physicalNetwork == null) {
throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " + requiredOfferings.get(0).getTags());
}
s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null, null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
// if the network offering has persistent set to true, implement the network
if (requiredOfferings.get(0).getIsPersistent()) {
DeployDestination dest = new DeployDestination(zone, null, null, null);
UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
Journal journal = new Journal.LogJournal("Implementing " + newNetwork, s_logger);
ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, caller);
s_logger.debug("Implementing the network for account" + newNetwork + " as a part of" + " network provision for persistent networks");
try {
Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(newNetwork.getId(), dest, context);
if (implementedNetwork == null || implementedNetwork.first() == null) {
s_logger.warn("Failed to implement the network " + newNetwork);
}
newNetwork = implementedNetwork.second();
} catch (Exception ex) {
s_logger.warn("Failed to implement network " + newNetwork + " elements and" + " resources as a part of network provision for persistent network due to ", ex);
CloudRuntimeException e = new CloudRuntimeException("Failed to implement network" + " (with specified id) elements and resources as a part of network provision");
e.addProxyObject(newNetwork.getUuid(), "networkId");
throw e;
}
}
defaultNetwork = _networkDao.findById(newNetwork.getId());
} else if (virtualNetworks.size() > 1) {
throw new InvalidParameterValueException("More than 1 default Isolated networks are found " + "for account " + newAccount + "; please specify networkIds");
} else {
defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId());
}
} else {
throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
}
applicableNetworks.add(defaultNetwork);
}
// add the new nics
LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
int toggle = 0;
for (NetworkVO appNet : applicableNetworks) {
NicProfile defaultNic = new NicProfile();
if (toggle == 0) {
defaultNic.setDefaultNic(true);
toggle++;
}
networks.put(appNet, new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
}
VirtualMachine vmi = _itMgr.findById(vm.getId());
VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
_networkMgr.allocate(vmProfile, networks);
s_logger.debug("AssignVM: Advance virtual, adding networks no " + networks.size() + " to " + vm.getInstanceName());
}
// END IF NON SEC GRP ENABLED
}
// END IF ADVANCED
s_logger.info("AssignVM: vm " + vm.getInstanceName() + " now belongs to account " + newAccount.getAccountName());
return vm;
}
Aggregations