use of com.cloud.utils.db.TransactionCallbackWithException in project cloudstack by apache.
the class IpAddressManagerImpl method assignDedicateIpAddress.
@DB
@Override
public PublicIp assignDedicateIpAddress(Account owner, final Long guestNtwkId, final Long vpcId, final long dcId, final boolean isSourceNat) throws ConcurrentOperationException, InsufficientAddressCapacityException {
final long ownerId = owner.getId();
PublicIp ip = null;
try {
ip = Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
@Override
public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
Account owner = _accountDao.acquireInLockTable(ownerId);
if (owner == null) {
// this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class
// to get the table name and field name that is queried to fill this ownerid.
ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account");
throw ex;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("lock account " + ownerId + " is acquired");
}
boolean displayIp = true;
if (guestNtwkId != null) {
Network ntwk = _networksDao.findById(guestNtwkId);
displayIp = ntwk.getDisplayNetwork();
} else if (vpcId != null) {
VpcVO vpc = _vpcDao.findById(vpcId);
displayIp = vpc.isDisplay();
}
PublicIp ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, false, null, false, vpcId, displayIp);
IPAddressVO publicIp = ip.ip();
markPublicIpAsAllocated(publicIp);
_ipAddressDao.update(publicIp.getId(), publicIp);
return ip;
}
});
return ip;
} finally {
if (owner != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Releasing lock account " + ownerId);
}
_accountDao.releaseFromLockTable(ownerId);
}
if (ip == null) {
s_logger.error("Unable to get source nat ip address for account " + ownerId);
}
}
}
use of com.cloud.utils.db.TransactionCallbackWithException in project cloudstack by apache.
the class IpAddressManagerImpl method allocatePortableIp.
@Override
@DB
public IpAddress allocatePortableIp(final Account ipOwner, Account caller, final long dcId, final Long networkId, final Long vpcID) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException {
GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
IPAddressVO ipaddr;
try {
portableIpLock.lock(5);
ipaddr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {
@Override
public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
PortableIpVO allocatedPortableIp;
List<PortableIpVO> portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free);
if (portableIpVOs == null || portableIpVOs.isEmpty()) {
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available portable IP addresses", Region.class, new Long(1));
throw ex;
}
// allocate first portable IP to the user
allocatedPortableIp = portableIpVOs.get(0);
allocatedPortableIp.setAllocatedTime(new Date());
allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId());
allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId());
allocatedPortableIp.setState(PortableIp.State.Allocated);
_portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp);
// To make portable IP available as a zone level resource we need to emulate portable IP's (which are
// provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the
// identity of a public IP in zone. Create entry for portable ip in these tables.
// provision portable IP range VLAN into the zone
long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId();
Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public);
String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress();
VlanVO vlan = new VlanVO(VlanType.VirtualNetwork, allocatedPortableIp.getVlan(), allocatedPortableIp.getGateway(), allocatedPortableIp.getNetmask(), dcId, range, network.getId(), physicalNetworkId, null, null, null);
vlan = _vlanDao.persist(vlan);
// provision the portable IP in to user_ip_address table
IPAddressVO ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, physicalNetworkId, network.getId(), vlan.getId(), true);
ipaddr.setState(State.Allocated);
ipaddr.setAllocatedTime(new Date());
ipaddr.setAllocatedInDomainId(ipOwner.getDomainId());
ipaddr.setAllocatedToAccountId(ipOwner.getId());
ipaddr = _ipAddressDao.persist(ipaddr);
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_PORTABLE_IP_ASSIGN, ipaddr.getId(), ipaddr.getDataCenterId(), ipaddr.getId(), ipaddr.getAddress().toString(), ipaddr.isSourceNat(), null, ipaddr.getSystem(), ipaddr.getClass().getName(), ipaddr.getUuid());
return ipaddr;
}
});
} finally {
portableIpLock.unlock();
}
return ipaddr;
}
use of com.cloud.utils.db.TransactionCallbackWithException in project cloudstack by apache.
the class NetworkServiceImpl method commitNetwork.
private Network commitNetwork(final Long networkOfferingId, final String gateway, final String startIP, final String endIP, final String netmask, final String networkDomain, final String vlanId, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId, final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway, final String ip6Cidr, final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk, final ACLType aclType, final Account ownerFinal, final String cidr, final boolean createVlan) throws InsufficientCapacityException, ResourceAllocationException {
try {
Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
@Override
public Network doInTransaction(TransactionStatus status) throws InsufficientCapacityException, ResourceAllocationException {
Account owner = ownerFinal;
Boolean subdomainAccess = subdomainAccessFinal;
Long sharedDomainId = null;
if (isDomainSpecific) {
if (domainId != null) {
sharedDomainId = domainId;
} else {
sharedDomainId = _domainMgr.getDomain(Domain.ROOT_DOMAIN).getId();
subdomainAccess = true;
}
}
// default owner to system if network has aclType=Domain
if (aclType == ACLType.Domain) {
owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
}
// Create guest network
Network network = null;
if (vpcId != null) {
if (!_configMgr.isOfferingForVpc(ntwkOff)) {
throw new InvalidParameterValueException("Network offering can't be used for VPC networks");
}
if (aclId != null) {
NetworkACL acl = _networkACLDao.findById(aclId);
if (acl == null) {
throw new InvalidParameterValueException("Unable to find specified NetworkACL");
}
if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
// ACL should be associated with a VPC
if (!vpcId.equals(acl.getVpcId())) {
throw new InvalidParameterValueException("ACL: " + aclId + " do not belong to the VPC");
}
}
}
network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, aclId, caller, displayNetwork);
} else {
if (_configMgr.isOfferingForVpc(ntwkOff)) {
throw new InvalidParameterValueException("Network offering can be used for VPC networks only");
}
if (ntwkOff.getInternalLb()) {
throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only");
}
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan);
}
if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
// Create vlan ip range
_configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, null, startIP, endIP, gateway, netmask, vlanId, null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
}
return network;
}
});
if (domainId != null && aclType == ACLType.Domain) {
// send event for storing the domain wide resource access
Map<String, Object> params = new HashMap<String, Object>();
params.put(ApiConstants.ENTITY_TYPE, Network.class);
params.put(ApiConstants.ENTITY_ID, network.getId());
params.put(ApiConstants.DOMAIN_ID, domainId);
params.put(ApiConstants.SUBDOMAIN_ACCESS, subdomainAccessFinal == null ? Boolean.TRUE : subdomainAccessFinal);
_messageBus.publish(_name, EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, PublishScope.LOCAL, params);
}
return network;
} catch (Exception e) {
ExceptionUtil.rethrowRuntime(e);
ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
ExceptionUtil.rethrow(e, ResourceAllocationException.class);
throw new IllegalStateException(e);
}
}
use of com.cloud.utils.db.TransactionCallbackWithException in project cloudstack by apache.
the class NetworkServiceImpl method createPrivateNetwork.
@Override
@DB
public Network createPrivateNetwork(final String networkName, final String displayText, long physicalNetworkId, String broadcastUriString, final String startIp, String endIp, final String gateway, String netmask, final long networkOwnerId, final Long vpcId, final Boolean sourceNat, final Long networkOfferingId) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
final Account owner = _accountMgr.getAccount(networkOwnerId);
// Get system network offering
NetworkOfferingVO ntwkOff = null;
if (networkOfferingId != null) {
ntwkOff = _networkOfferingDao.findById(networkOfferingId);
}
if (ntwkOff == null) {
ntwkOff = findSystemNetworkOffering(NetworkOffering.SystemPrivateGatewayNetworkOffering);
}
// Validate physical network
final PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
if (pNtwk == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a physical network" + " having the given id");
ex.addProxyObject(String.valueOf(physicalNetworkId), "physicalNetworkId");
throw ex;
}
// if end ip is not specified, default it to startIp
if (!NetUtils.isValidIp(startIp)) {
throw new InvalidParameterValueException("Invalid format for the ip address parameter");
}
if (endIp == null) {
endIp = startIp;
} else if (!NetUtils.isValidIp(endIp)) {
throw new InvalidParameterValueException("Invalid format for the endIp address parameter");
}
if (!NetUtils.isValidIp(gateway)) {
throw new InvalidParameterValueException("Invalid gateway");
}
if (!NetUtils.isValidNetmask(netmask)) {
throw new InvalidParameterValueException("Invalid netmask");
}
final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
URI uri = BroadcastDomainType.fromString(broadcastUriString);
final String uriString = uri.toString();
BroadcastDomainType tiep = BroadcastDomainType.getSchemeValue(uri);
// TODO make a test for any supported scheme
if (!(tiep == BroadcastDomainType.Vlan || tiep == BroadcastDomainType.Lswitch)) {
throw new InvalidParameterValueException("unsupported type of broadcastUri specified: " + broadcastUriString);
}
final NetworkOfferingVO ntwkOffFinal = ntwkOff;
try {
return Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
@Override
public Network doInTransaction(TransactionStatus status) throws ResourceAllocationException, InsufficientCapacityException {
//lock datacenter as we need to get mac address seq from there
DataCenterVO dc = _dcDao.lockRow(pNtwk.getDataCenterId(), true);
//check if we need to create guest network
Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId);
if (privateNetwork == null) {
//create Guest network
privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null);
if (privateNetwork != null) {
s_logger.debug("Successfully created guest network " + privateNetwork);
} else {
throw new CloudRuntimeException("Creating guest network failed");
}
} else {
s_logger.debug("Private network already exists: " + privateNetwork);
//Do not allow multiple private gateways with same Vlan within a VPC
if (vpcId != null && vpcId.equals(privateNetwork.getVpcId())) {
throw new InvalidParameterValueException("Private network for the vlan: " + uriString + " and cidr " + cidr + " already exists " + "for Vpc " + vpcId + " in zone " + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName());
}
}
if (vpcId != null) {
//add entry to private_ip_address table
PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkIdAndVpcId(privateNetwork.getId(), startIp, vpcId);
if (privateIp != null) {
throw new InvalidParameterValueException("Private ip address " + startIp + " already used for private gateway" + " in zone " + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName());
}
Long mac = dc.getMacAddress();
Long nextMac = mac + 1;
dc.setMacAddress(nextMac);
privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId, sourceNat);
_privateIpDao.persist(privateIp);
_dcDao.update(dc.getId(), dc);
}
s_logger.debug("Private network " + privateNetwork + " is created");
return privateNetwork;
}
});
} catch (Exception e) {
ExceptionUtil.rethrowRuntime(e);
ExceptionUtil.rethrow(e, ResourceAllocationException.class);
ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
throw new IllegalStateException(e);
}
}
use of com.cloud.utils.db.TransactionCallbackWithException 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);
}
}
});
}
Aggregations