use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class ConfigurationManagerImpl method editPod.
@Override
@DB
public Pod editPod(final long id, String name, String startIp, String endIp, String gateway, String netmask, String allocationStateStr) {
// verify parameters
final HostPodVO pod = _podDao.findById(id);
if (pod == null) {
throw new InvalidParameterValueException("Unable to find pod by id " + id);
}
final String[] existingPodIpRange = pod.getDescription().split("-");
String[] leftRangeToAdd = null;
String[] rightRangeToAdd = null;
boolean allowToDownsize = false;
// pod has allocated private IP addresses
if (podHasAllocatedPrivateIPs(id)) {
if (netmask != null) {
final long newCidr = NetUtils.getCidrSize(netmask);
final long oldCidr = pod.getCidrSize();
if (newCidr > oldCidr) {
throw new CloudRuntimeException("The specified pod has allocated private IP addresses, so its IP address range can be extended only");
}
}
if (startIp != null && !startIp.equals(existingPodIpRange[0])) {
if (NetUtils.ipRangesOverlap(startIp, null, existingPodIpRange[0], existingPodIpRange[1])) {
throw new CloudRuntimeException("The specified pod has allocated private IP addresses, so its IP address range can be extended only");
} else {
leftRangeToAdd = new String[2];
final long endIpForUpdate = NetUtils.ip2Long(existingPodIpRange[0]) - 1;
leftRangeToAdd[0] = startIp;
leftRangeToAdd[1] = NetUtils.long2Ip(endIpForUpdate);
}
}
if (endIp != null && !endIp.equals(existingPodIpRange[1])) {
if (NetUtils.ipRangesOverlap(endIp, endIp, existingPodIpRange[0], existingPodIpRange[1])) {
throw new CloudRuntimeException("The specified pod has allocated private IP addresses, so its IP address range can be extended only");
} else {
rightRangeToAdd = new String[2];
final long startIpForUpdate = NetUtils.ip2Long(existingPodIpRange[1]) + 1;
rightRangeToAdd[0] = NetUtils.long2Ip(startIpForUpdate);
rightRangeToAdd[1] = endIp;
}
}
} else {
allowToDownsize = true;
}
if (gateway == null) {
gateway = pod.getGateway();
}
if (netmask == null) {
netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
}
final String oldPodName = pod.getName();
if (name == null) {
name = oldPodName;
}
if (gateway == null) {
gateway = pod.getGateway();
}
if (startIp == null) {
startIp = existingPodIpRange[0];
}
if (endIp == null) {
endIp = existingPodIpRange[1];
}
if (allocationStateStr == null) {
allocationStateStr = pod.getAllocationState().toString();
}
// Verify pod's attributes
final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
final boolean checkForDuplicates = !oldPodName.equals(name);
checkPodAttributes(id, name, pod.getDataCenterId(), gateway, cidr, startIp, endIp, allocationStateStr, checkForDuplicates, false);
try {
final String[] existingPodIpRangeFinal = existingPodIpRange;
final String[] leftRangeToAddFinal = leftRangeToAdd;
final String[] rightRangeToAddFinal = rightRangeToAdd;
final boolean allowToDownsizeFinal = allowToDownsize;
final String allocationStateStrFinal = allocationStateStr;
final String startIpFinal = startIp;
final String endIpFinal = endIp;
final String nameFinal = name;
final String gatewayFinal = gateway;
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(final TransactionStatus status) {
final long zoneId = pod.getDataCenterId();
String startIp = startIpFinal;
String endIp = endIpFinal;
if (!allowToDownsizeFinal) {
if (leftRangeToAddFinal != null) {
_zoneDao.addPrivateIpAddress(zoneId, pod.getId(), leftRangeToAddFinal[0], leftRangeToAddFinal[1]);
}
if (rightRangeToAddFinal != null) {
_zoneDao.addPrivateIpAddress(zoneId, pod.getId(), rightRangeToAddFinal[0], rightRangeToAddFinal[1]);
}
} else {
// delete the old range
_zoneDao.deletePrivateIpAddressByPod(pod.getId());
// add the new one
if (startIp == null) {
startIp = existingPodIpRangeFinal[0];
}
if (endIp == null) {
endIp = existingPodIpRangeFinal[1];
}
_zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIp);
}
pod.setName(nameFinal);
pod.setDataCenterId(zoneId);
pod.setGateway(gatewayFinal);
pod.setCidrAddress(getCidrAddress(cidr));
pod.setCidrSize(getCidrSize(cidr));
final String ipRange = startIp + "-" + endIp;
pod.setDescription(ipRange);
Grouping.AllocationState allocationState = null;
if (allocationStateStrFinal != null && !allocationStateStrFinal.isEmpty()) {
allocationState = Grouping.AllocationState.valueOf(allocationStateStrFinal);
pod.setAllocationState(allocationState);
}
_podDao.update(id, pod);
}
});
} catch (final Exception e) {
s_logger.error("Unable to edit pod due to " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to edit pod. Please contact Cloud Support.");
}
return pod;
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class DeploymentPlanningManagerImpl method checkIfHostFitsPlannerUsage.
@DB
private boolean checkIfHostFitsPlannerUsage(final long hostId, final PlannerResourceUsage resourceUsageRequired) {
// TODO Auto-generated method stub
// check if this host has been picked up by some other planner
// exclusively
// if planner can work with shared host, check if this host has
// been marked as 'shared'
// else if planner needs dedicated host,
PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
if (reservationEntry != null) {
final long id = reservationEntry.getId();
PlannerResourceUsage hostResourceType = reservationEntry.getResourceUsage();
if (hostResourceType != null) {
if (hostResourceType == resourceUsageRequired) {
return true;
} else {
s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + ", since this host has been reserved for planner usage : " + hostResourceType);
return false;
}
} else {
final PlannerResourceUsage hostResourceTypeFinal = hostResourceType;
// let us lock the reservation entry before updating.
return Transaction.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
if (lockedEntry == null) {
s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
return false;
}
// check before updating
if (lockedEntry.getResourceUsage() == null) {
lockedEntry.setResourceUsage(resourceUsageRequired);
_plannerHostReserveDao.persist(lockedEntry);
return true;
} else {
// someone updated it earlier. check if we can still use it
if (lockedEntry.getResourceUsage() == resourceUsageRequired) {
return true;
} else {
s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + ", since this host has been reserved for planner usage : " + hostResourceTypeFinal);
return false;
}
}
}
});
}
}
return false;
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class ConfigurationManagerImpl method createPortableIpRange.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_CREATE, eventDescription = "creating portable ip range", async = false)
public PortableIpRange createPortableIpRange(final CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException {
final Integer regionId = cmd.getRegionId();
final String startIP = cmd.getStartIp();
final String endIP = cmd.getEndIp();
final String gateway = cmd.getGateway();
final String netmask = cmd.getNetmask();
String vlanId = cmd.getVlan();
final RegionVO region = _regionDao.findById(regionId);
if (region == null) {
throw new InvalidParameterValueException("Invalid region ID: " + regionId);
}
if (!NetUtils.isValidIp(startIP) || !NetUtils.isValidIp(endIP) || !NetUtils.validIpRange(startIP, endIP)) {
throw new InvalidParameterValueException("Invalid portable ip range: " + startIP + "-" + endIP);
}
if (!NetUtils.sameSubnet(startIP, gateway, netmask)) {
throw new InvalidParameterValueException("Please ensure that your start IP is in the same subnet as " + "your portable IP range's gateway and as per the IP range's netmask.");
}
if (!NetUtils.sameSubnet(endIP, gateway, netmask)) {
throw new InvalidParameterValueException("Please ensure that your end IP is in the same subnet as " + "your portable IP range's gateway and as per the IP range's netmask.");
}
if (checkOverlapPortableIpRange(regionId, startIP, endIP)) {
throw new InvalidParameterValueException("Ip range: " + startIP + "-" + endIP + " overlaps with a portable" + " IP range already configured in the region " + regionId);
}
if (vlanId == null) {
vlanId = Vlan.UNTAGGED;
} else {
if (!NetUtils.isValidVlan(vlanId)) {
throw new InvalidParameterValueException("Invalid vlan id " + vlanId);
}
final List<DataCenterVO> zones = _zoneDao.listAllZones();
if (zones != null && !zones.isEmpty()) {
for (final DataCenterVO zone : zones) {
// check if there is zone vlan with same id
if (_vlanDao.findByZoneAndVlanId(zone.getId(), vlanId) != null) {
throw new InvalidParameterValueException("Found a VLAN id " + vlanId + " already existing in" + " zone " + zone.getUuid() + " that conflicts with VLAN id of the portable ip range being configured");
}
//check if there is a public ip range that overlaps with portable ip range being created
checkOverlapPublicIpRange(zone.getId(), startIP, endIP);
}
}
}
final GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
portableIpLock.lock(5);
try {
final String vlanIdFinal = vlanId;
return Transaction.execute(new TransactionCallback<PortableIpRangeVO>() {
@Override
public PortableIpRangeVO doInTransaction(final TransactionStatus status) {
PortableIpRangeVO portableIpRange = new PortableIpRangeVO(regionId, vlanIdFinal, gateway, netmask, startIP, endIP);
portableIpRange = _portableIpRangeDao.persist(portableIpRange);
long startIpLong = NetUtils.ip2Long(startIP);
final long endIpLong = NetUtils.ip2Long(endIP);
while (startIpLong <= endIpLong) {
final PortableIpVO portableIP = new PortableIpVO(regionId, portableIpRange.getId(), vlanIdFinal, gateway, netmask, NetUtils.long2Ip(startIpLong));
_portableIpDao.persist(portableIP);
startIpLong++;
}
// implicitly enable portable IP service for the region
region.setPortableipEnabled(true);
_regionDao.update(region.getId(), region);
return portableIpRange;
}
});
} finally {
portableIpLock.unlock();
}
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class RulesManagerImpl method createStaticNatRule.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating static nat rule", create = true)
public StaticNatRule createStaticNatRule(final StaticNatRule rule, final boolean openFirewall) throws NetworkRuleConflictException {
final Account caller = CallContext.current().getCallingAccount();
final Long ipAddrId = rule.getSourceIpAddressId();
IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
// Validate ip address
if (ipAddress == null) {
throw new InvalidParameterValueException("Unable to create static nat rule; ip id=" + ipAddrId + " doesn't exist in the system");
} else if (ipAddress.isSourceNat() || !ipAddress.isOneToOneNat() || ipAddress.getAssociatedWithVmId() == null) {
throw new NetworkRuleConflictException("Can't do static nat on ip address: " + ipAddress.getAddress());
}
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat, FirewallRuleType.User, null, rule.getTrafficType());
final Long networkId = ipAddress.getAssociatedWithNetworkId();
final Long accountId = ipAddress.getAllocatedToAccountId();
final Long domainId = ipAddress.getAllocatedInDomainId();
_networkModel.checkIpForService(ipAddress, Service.StaticNat, null);
Network network = _networkModel.getNetwork(networkId);
NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
if (off.getElasticIp()) {
throw new InvalidParameterValueException("Can't create ip forwarding rules for the network where elasticIP service is enabled");
}
//String dstIp = _networkModel.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId);
final String dstIp = ipAddress.getVmIp();
return Transaction.execute(new TransactionCallbackWithException<StaticNatRule, NetworkRuleConflictException>() {
@Override
public StaticNatRule doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
FirewallRuleVO newRule = new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, rule.getPurpose(), null, null, null, null, null);
newRule = _firewallDao.persist(newRule);
// create firewallRule for 0.0.0.0/0 cidr
if (openFirewall) {
_firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId(), networkId);
}
try {
_firewallMgr.detectRulesConflict(newRule);
if (!_firewallDao.setStateToAdd(newRule)) {
throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
}
CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), null, FirewallRule.class.getName(), newRule.getUuid());
StaticNatRule staticNatRule = new StaticNatRuleImpl(newRule, dstIp);
return staticNatRule;
} catch (Exception e) {
if (newRule != null) {
// no need to apply the rule as it wasn't programmed on the backend yet
_firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
_firewallMgr.removeRule(newRule);
}
if (e instanceof NetworkRuleConflictException) {
throw (NetworkRuleConflictException) e;
}
throw new CloudRuntimeException("Unable to add static nat rule for the ip id=" + newRule.getSourceIpAddressId(), e);
}
}
});
}
use of com.cloud.utils.db.TransactionStatus in project cloudstack by apache.
the class SecurityGroupManagerImpl method scheduleRulesetUpdateToHosts.
@DB
public void scheduleRulesetUpdateToHosts(final List<Long> affectedVms, final boolean updateSeqno, Long delayMs) {
if (affectedVms.size() == 0) {
return;
}
if (delayMs == null) {
delayMs = new Long(100l);
}
Collections.sort(affectedVms);
if (s_logger.isTraceEnabled()) {
s_logger.trace("Security Group Mgr: scheduling ruleset updates for " + affectedVms.size() + " vms");
}
boolean locked = _workLock.lock(_globalWorkLockTimeout);
if (!locked) {
s_logger.warn("Security Group Mgr: failed to acquire global work lock");
return;
}
if (s_logger.isTraceEnabled()) {
s_logger.trace("Security Group Mgr: acquired global work lock");
}
try {
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
for (Long vmId : affectedVms) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Security Group Mgr: scheduling ruleset update for " + vmId);
}
VmRulesetLogVO log = null;
SecurityGroupWorkVO work = null;
log = _rulesetLogDao.findByVmId(vmId);
if (log == null) {
log = new VmRulesetLogVO(vmId);
log = _rulesetLogDao.persist(log);
}
if (log != null && updateSeqno) {
log.incrLogsequence();
_rulesetLogDao.update(log.getId(), log);
}
work = _workDao.findByVmIdStep(vmId, Step.Scheduled);
if (work == null) {
work = new SecurityGroupWorkVO(vmId, null, null, SecurityGroupWork.Step.Scheduled, null);
work = _workDao.persist(work);
if (s_logger.isTraceEnabled()) {
s_logger.trace("Security Group Mgr: created new work item for " + vmId + "; id = " + work.getId());
}
}
work.setLogsequenceNumber(log.getLogsequence());
_workDao.update(work.getId(), work);
}
}
});
for (Long vmId : affectedVms) {
_executorPool.schedule(new WorkerThread(), delayMs, TimeUnit.MILLISECONDS);
}
} finally {
_workLock.unlock();
if (s_logger.isTraceEnabled()) {
s_logger.trace("Security Group Mgr: released global work lock");
}
}
}
Aggregations