use of org.apache.cloudstack.context.CallContext in project cloudstack by apache.
the class RemoteAccessVpnManagerImpl method createRemoteAccessVpn.
@Override
@DB
public RemoteAccessVpn createRemoteAccessVpn(final long publicIpId, String ipRange, boolean openFirewall, final Boolean forDisplay) throws NetworkRuleConflictException {
CallContext ctx = CallContext.current();
final Account caller = ctx.getCallingAccount();
Long networkId = null;
// make sure ip address exists
final PublicIpAddress ipAddr = _networkMgr.getPublicIpAddress(publicIpId);
if (ipAddr == null) {
throw new InvalidParameterValueException("Unable to create remote access vpn, invalid public IP address id" + publicIpId);
}
_accountMgr.checkAccess(caller, null, true, ipAddr);
if (!ipAddr.readyToUse()) {
throw new InvalidParameterValueException("The Ip address is not ready to be used yet: " + ipAddr.getAddress());
}
IPAddressVO ipAddress = _ipAddressDao.findById(publicIpId);
networkId = ipAddress.getAssociatedWithNetworkId();
if (networkId != null) {
_networkMgr.checkIpForService(ipAddress, Service.Vpn, null);
}
final Long vpcId = ipAddress.getVpcId();
/* IP Address used for VPC must be the source NAT IP of whole VPC */
if (vpcId != null && ipAddress.isSourceNat()) {
assert networkId == null;
// No firewall setting for VPC, it would be open internally
openFirewall = false;
}
final boolean openFirewallFinal = openFirewall;
if (networkId == null && vpcId == null) {
throw new InvalidParameterValueException("Unable to create remote access vpn for the ipAddress: " + ipAddr.getAddress().addr() + " as ip is not associated with any network or VPC");
}
RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByPublicIpAddress(publicIpId);
if (vpnVO != null) {
//if vpn is in Added state, return it to the api
if (vpnVO.getState() == RemoteAccessVpn.State.Added) {
return vpnVO;
}
throw new InvalidParameterValueException("A Remote Access VPN already exists for this public Ip address");
}
if (ipRange == null) {
ipRange = RemoteAccessVpnClientIpRange.valueIn(ipAddr.getAccountId());
}
final String[] range = ipRange.split("-");
if (range.length != 2) {
throw new InvalidParameterValueException("Invalid ip range");
}
if (!NetUtils.isValidIp(range[0]) || !NetUtils.isValidIp(range[1])) {
throw new InvalidParameterValueException("Invalid ip in range specification " + ipRange);
}
if (!NetUtils.validIpRange(range[0], range[1])) {
throw new InvalidParameterValueException("Invalid ip range " + ipRange);
}
Pair<String, Integer> cidr = null;
// TODO: assumes one virtual network / domr per account per zone
if (networkId != null) {
vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(ipAddr.getAccountId(), networkId);
if (vpnVO != null) {
//if vpn is in Added state, return it to the api
if (vpnVO.getState() == RemoteAccessVpn.State.Added) {
return vpnVO;
}
throw new InvalidParameterValueException("A Remote Access VPN already exists for this account");
}
//Verify that vpn service is enabled for the network
Network network = _networkMgr.getNetwork(networkId);
if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Vpn)) {
throw new InvalidParameterValueException("Vpn service is not supported in network id=" + ipAddr.getAssociatedWithNetworkId());
}
cidr = NetUtils.getCidr(network.getCidr());
} else {
// Don't need to check VPC because there is only one IP(source NAT IP) available for VPN
Vpc vpc = _vpcDao.findById(vpcId);
cidr = NetUtils.getCidr(vpc.getCidr());
}
// FIXME: This check won't work for the case where the guest ip range
// changes depending on the vlan allocated.
String[] guestIpRange = NetUtils.getIpRangeFromCidr(cidr.first(), cidr.second());
if (NetUtils.ipRangesOverlap(range[0], range[1], guestIpRange[0], guestIpRange[1])) {
throw new InvalidParameterValueException("Invalid ip range: " + ipRange + " overlaps with guest ip range " + guestIpRange[0] + "-" + guestIpRange[1]);
}
// TODO: check sufficient range
// TODO: check overlap with private and public ip ranges in datacenter
long startIp = NetUtils.ip2Long(range[0]);
final String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1];
final String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength);
return Transaction.execute(new TransactionCallbackWithException<RemoteAccessVpn, NetworkRuleConflictException>() {
@Override
public RemoteAccessVpn doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
if (vpcId == null) {
_rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, openFirewallFinal, caller, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT);
}
RemoteAccessVpnVO vpnVO = new RemoteAccessVpnVO(ipAddr.getAccountId(), ipAddr.getDomainId(), ipAddr.getAssociatedWithNetworkId(), publicIpId, vpcId, range[0], newIpRange, sharedSecret);
if (forDisplay != null) {
vpnVO.setDisplay(forDisplay);
}
return _remoteAccessVpnDao.persist(vpnVO);
}
});
}
use of org.apache.cloudstack.context.CallContext in project cloudstack by apache.
the class VpcManagerImpl method shutdownVpc.
@Override
public boolean shutdownVpc(final long vpcId) throws ConcurrentOperationException, ResourceUnavailableException {
final CallContext ctx = CallContext.current();
final Account caller = ctx.getCallingAccount();
// check if vpc exists
final Vpc vpc = _vpcDao.findById(vpcId);
if (vpc == null) {
throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId);
}
// permission check
_accountMgr.checkAccess(caller, null, false, vpc);
// shutdown provider
s_logger.debug("Shutting down vpc " + vpc);
// TODO - shutdown all vpc resources here (ACLs, gateways, etc)
boolean success = true;
final List<Provider> providersToImplement = getVpcProviders(vpc.getId());
final ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(ctx.getCallingUserId()), caller);
for (final VpcProvider element : getVpcElements()) {
if (providersToImplement.contains(element.getProvider())) {
if (element.shutdownVpc(vpc, context)) {
s_logger.debug("Vpc " + vpc + " has been shutdown succesfully");
} else {
s_logger.warn("Vpc " + vpc + " failed to shutdown");
success = false;
}
}
}
return success;
}
use of org.apache.cloudstack.context.CallContext in project cloudstack by apache.
the class RulesManagerImpl method createPortForwardingRule.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true)
public PortForwardingRule createPortForwardingRule(final PortForwardingRule rule, final Long vmId, Ip vmIp, final boolean openFirewall, final Boolean forDisplay) throws NetworkRuleConflictException {
CallContext ctx = CallContext.current();
final Account caller = ctx.getCallingAccount();
final Long ipAddrId = rule.getSourceIpAddressId();
IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
// Validate ip address
if (ipAddress == null) {
throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " doesn't exist in the system");
} else if (ipAddress.isOneToOneNat()) {
throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled");
}
final Long networkId = rule.getNetworkId();
Network network = _networkModel.getNetwork(networkId);
//associate ip address to network (if needed)
boolean performedIpAssoc = false;
Nic guestNic;
if (ipAddress.getAssociatedWithNetworkId() == null) {
boolean assignToVpcNtwk = network.getVpcId() != null && ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
if (assignToVpcNtwk) {
_networkModel.checkIpForService(ipAddress, Service.PortForwarding, networkId);
s_logger.debug("The ip is not associated with the VPC network id=" + networkId + ", so assigning");
try {
ipAddress = _ipAddrMgr.associateIPToGuestNetwork(ipAddrId, networkId, false);
performedIpAssoc = true;
} catch (Exception ex) {
throw new CloudRuntimeException("Failed to associate ip to VPC network as " + "a part of port forwarding rule creation");
}
}
} else {
_networkModel.checkIpForService(ipAddress, Service.PortForwarding, null);
}
if (ipAddress.getAssociatedWithNetworkId() == null) {
throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
}
try {
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User, networkId, rule.getTrafficType());
final Long accountId = ipAddress.getAllocatedToAccountId();
final Long domainId = ipAddress.getAllocatedInDomainId();
// start port can't be bigger than end port
if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) {
throw new InvalidParameterValueException("Start port can't be bigger than end port");
}
// check that the port ranges are of equal size
if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) {
throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes.");
}
// validate user VM exists
UserVm vm = _vmDao.findById(vmId);
if (vm == null) {
throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" + vmId + ").");
} else if (vm.getState() == VirtualMachine.State.Destroyed || vm.getState() == VirtualMachine.State.Expunging) {
throw new InvalidParameterValueException("Invalid user vm: " + vm.getId());
}
// Verify that vm has nic in the network
Ip dstIp = rule.getDestinationIpAddress();
guestNic = _networkModel.getNicInNetwork(vmId, networkId);
if (guestNic == null || guestNic.getIPv4Address() == null) {
throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
} else {
dstIp = new Ip(guestNic.getIPv4Address());
}
if (vmIp != null) {
//vm ip is passed so it can be primary or secondary ip addreess.
if (!dstIp.equals(vmIp)) {
//the vm ip is secondary ip to the nic.
// is vmIp is secondary ip or not
NicSecondaryIp secondaryIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmIp.toString(), guestNic.getId());
if (secondaryIp == null) {
throw new InvalidParameterValueException("IP Address is not in the VM nic's network ");
}
dstIp = vmIp;
}
}
//if start port and end port are passed in, and they are not equal to each other, perform the validation
boolean validatePortRange = false;
if (rule.getSourcePortStart().intValue() != rule.getSourcePortEnd().intValue() || rule.getDestinationPortStart() != rule.getDestinationPortEnd()) {
validatePortRange = true;
}
if (validatePortRange) {
//source start port and source dest port should be the same. The same applies to dest ports
if (rule.getSourcePortStart().intValue() != rule.getDestinationPortStart()) {
throw new InvalidParameterValueException("Private port start should be equal to public port start");
}
if (rule.getSourcePortEnd().intValue() != rule.getDestinationPortEnd()) {
throw new InvalidParameterValueException("Private port end should be equal to public port end");
}
}
final Ip dstIpFinal = dstIp;
final IPAddressVO ipAddressFinal = ipAddress;
return Transaction.execute(new TransactionCallbackWithException<PortForwardingRuleVO, NetworkRuleConflictException>() {
@Override
public PortForwardingRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIpFinal, rule.getDestinationPortStart(), rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId);
if (forDisplay != null) {
newRule.setDisplay(forDisplay);
}
newRule = _portForwardingDao.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(), ipAddressFinal.getDataCenterId(), newRule.getId(), null, PortForwardingRule.class.getName(), newRule.getUuid());
return newRule;
} 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);
removePFRule(newRule);
}
if (e instanceof NetworkRuleConflictException) {
throw (NetworkRuleConflictException) e;
}
throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e);
}
}
});
} finally {
// release ip address if ipassoc was perfored
if (performedIpAssoc) {
//if the rule is the last one for the ip address assigned to VPC, unassign it from the network
IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
_vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
}
}
}
use of org.apache.cloudstack.context.CallContext in project cloudstack by apache.
the class VirtualNetworkApplianceManagerImpl method stopRouter.
@ActionEvent(eventType = EventTypes.EVENT_ROUTER_STOP, eventDescription = "stopping router Vm", async = true)
@Override
public VirtualRouter stopRouter(final long routerId, final boolean forced) throws ResourceUnavailableException, ConcurrentOperationException {
final CallContext context = CallContext.current();
final Account account = context.getCallingAccount();
// verify parameters
final DomainRouterVO router = _routerDao.findById(routerId);
if (router == null) {
throw new InvalidParameterValueException("Unable to find router by id " + routerId + ".");
}
_accountMgr.checkAccess(account, null, true, router);
final UserVO user = _userDao.findById(CallContext.current().getCallingUserId());
final VirtualRouter virtualRouter = stop(router, forced, user, account);
if (virtualRouter == null) {
throw new CloudRuntimeException("Failed to stop router with id " + routerId);
}
// Clear stop pending flag after stopped successfully
if (router.isStopPending()) {
s_logger.info("Clear the stop pending flag of router " + router.getHostName() + " after stop router successfully");
router.setStopPending(false);
_routerDao.persist(router);
virtualRouter.setStopPending(false);
}
return virtualRouter;
}
use of org.apache.cloudstack.context.CallContext in project cloudstack by apache.
the class RulesManagerImpl method disableStaticNat.
@Override
@ActionEvent(eventType = EventTypes.EVENT_DISABLE_STATIC_NAT, eventDescription = "disabling static nat", async = true)
public boolean disableStaticNat(long ipId) throws ResourceUnavailableException, NetworkRuleConflictException, InsufficientAddressCapacityException {
CallContext ctx = CallContext.current();
Account caller = ctx.getCallingAccount();
IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
checkIpAndUserVm(ipAddress, null, caller, false);
if (ipAddress.getSystem()) {
InvalidParameterValueException ex = new InvalidParameterValueException("Can't disable static nat for system IP address with specified id");
ex.addProxyObject(ipAddress.getUuid(), "ipId");
throw ex;
}
Long vmId = ipAddress.getAssociatedWithVmId();
if (vmId == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Specified IP address id is not associated with any vm Id");
ex.addProxyObject(ipAddress.getUuid(), "ipId");
throw ex;
}
// if network has elastic IP functionality supported, we first have to disable static nat on old ip in order to
// re-enable it on the new one enable static nat takes care of that
Network guestNetwork = _networkModel.getNetwork(ipAddress.getAssociatedWithNetworkId());
NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
if (offering.getElasticIp()) {
if (offering.getAssociatePublicIP()) {
getSystemIpAndEnableStaticNatForVm(_vmDao.findById(vmId), true);
return true;
}
}
return disableStaticNat(ipId, caller, ctx.getCallingUserId(), false);
}
Aggregations