Ejemplo n.º 1
0
  protected String retrieveTemplateName(final HypervisorType hType, final long datacenterId) {
    String templateName = null;

    if (hType == HypervisorType.BareMetal) {
      final ConfigKey<String> hypervisorConfigKey = hypervisorsMap.get(HypervisorType.VMware);
      templateName = hypervisorConfigKey.valueIn(datacenterId);
    } else {
      // Returning NULL is fine because the simulator will need it when
      // being used instead of a real hypervisor.
      // The hypervisorsMap contains only real hypervisors.
      final ConfigKey<String> hypervisorConfigKey = hypervisorsMap.get(hType);

      if (hypervisorConfigKey != null) {
        templateName = hypervisorConfigKey.valueIn(datacenterId);
      }
    }

    return templateName;
  }
  @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);
          }
        });
  }