コード例 #1
0
ファイル: UsageDaoImpl.java プロジェクト: vogxn/cloudstack
 @Override
 public void updateUserStats(List<UserStatisticsVO> userStats) {
   Transaction txn = Transaction.currentTxn();
   try {
     txn.start();
     String sql = UPDATE_USER_STATS;
     PreparedStatement pstmt = null;
     pstmt =
         txn.prepareAutoCloseStatement(
             sql); // in reality I just want CLOUD_USAGE dataSource connection
     for (UserStatisticsVO userStat : userStats) {
       pstmt.setLong(1, userStat.getNetBytesReceived());
       pstmt.setLong(2, userStat.getNetBytesSent());
       pstmt.setLong(3, userStat.getCurrentBytesReceived());
       pstmt.setLong(4, userStat.getCurrentBytesSent());
       pstmt.setLong(5, userStat.getAggBytesReceived());
       pstmt.setLong(6, userStat.getAggBytesSent());
       pstmt.setLong(7, userStat.getId());
       pstmt.addBatch();
     }
     pstmt.executeBatch();
     txn.commit();
   } catch (Exception ex) {
     txn.rollback();
     s_logger.error("error saving user stats to cloud_usage db", ex);
     throw new CloudRuntimeException(ex.getMessage());
   }
 }
コード例 #2
0
ファイル: UsageDaoImpl.java プロジェクト: vogxn/cloudstack
  @Override
  public void updateAccounts(List<AccountVO> accounts) {
    Transaction txn = Transaction.currentTxn();
    try {
      txn.start();
      String sql = UPDATE_ACCOUNT;
      PreparedStatement pstmt = null;
      pstmt =
          txn.prepareAutoCloseStatement(
              sql); // in reality I just want CLOUD_USAGE dataSource connection
      for (AccountVO acct : accounts) {
        pstmt.setString(1, acct.getAccountName());

        Date removed = acct.getRemoved();
        if (removed == null) {
          pstmt.setString(2, null);
        } else {
          pstmt.setString(
              2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), acct.getRemoved()));
        }

        pstmt.setLong(3, acct.getId());
        pstmt.addBatch();
      }
      pstmt.executeBatch();
      txn.commit();
    } catch (Exception ex) {
      txn.rollback();
      s_logger.error("error saving account to cloud_usage db", ex);
      throw new CloudRuntimeException(ex.getMessage());
    }
  }
コード例 #3
0
 @Override
 public void saveUsageNetworks(List<UsageNetworkVO> usageNetworks) {
   Transaction txn = Transaction.currentTxn();
   try {
     txn.start();
     String sql = INSERT_USAGE_NETWORK;
     PreparedStatement pstmt = null;
     pstmt =
         txn.prepareAutoCloseStatement(
             sql); // in reality I just want CLOUD_USAGE dataSource connection
     for (UsageNetworkVO usageNetwork : usageNetworks) {
       pstmt.setLong(1, usageNetwork.getAccountId());
       pstmt.setLong(2, usageNetwork.getZoneId());
       pstmt.setLong(3, usageNetwork.getHostId());
       pstmt.setString(4, usageNetwork.getHostType());
       pstmt.setLong(5, usageNetwork.getNetworkId());
       pstmt.setLong(6, usageNetwork.getBytesSent());
       pstmt.setLong(7, usageNetwork.getBytesReceived());
       pstmt.setLong(8, usageNetwork.getAggBytesReceived());
       pstmt.setLong(9, usageNetwork.getAggBytesSent());
       pstmt.setLong(10, usageNetwork.getEventTimeMillis());
       pstmt.addBatch();
     }
     pstmt.executeBatch();
     txn.commit();
   } catch (Exception ex) {
     txn.rollback();
     s_logger.error("error saving usage_network to cloud_usage db", ex);
     throw new CloudRuntimeException(ex.getMessage());
   }
 }
コード例 #4
0
  @Override
  @DB
  public boolean addInstanceToGroups(final Long userVmId, final List<Long> groups) {
    if (!isVmSecurityGroupEnabled(userVmId)) {
      s_logger.warn(
          "User vm " + userVmId + " is not security group enabled, can't add it to security group");
      return false;
    }
    if (groups != null && !groups.isEmpty()) {

      final Transaction txn = Transaction.currentTxn();
      txn.start();
      UserVm userVm =
          _userVMDao.acquireInLockTable(
              userVmId); // ensures that duplicate entries are not created.
      List<SecurityGroupVO> sgs = new ArrayList<SecurityGroupVO>();
      for (Long sgId : groups) {
        sgs.add(_securityGroupDao.findById(sgId));
      }
      final Set<SecurityGroupVO> uniqueGroups =
          new TreeSet<SecurityGroupVO>(new SecurityGroupVOComparator());
      uniqueGroups.addAll(sgs);
      if (userVm == null) {
        s_logger.warn("Failed to acquire lock on user vm id=" + userVmId);
      }
      try {
        for (SecurityGroupVO securityGroup : uniqueGroups) {
          // don't let the group be deleted from under us.
          SecurityGroupVO ngrpLock = _securityGroupDao.lockRow(securityGroup.getId(), false);
          if (ngrpLock == null) {
            s_logger.warn(
                "Failed to acquire lock on network group id="
                    + securityGroup.getId()
                    + " name="
                    + securityGroup.getName());
            txn.rollback();
            return false;
          }
          if (_securityGroupVMMapDao.findByVmIdGroupId(userVmId, securityGroup.getId()) == null) {
            SecurityGroupVMMapVO groupVmMapVO =
                new SecurityGroupVMMapVO(securityGroup.getId(), userVmId);
            _securityGroupVMMapDao.persist(groupVmMapVO);
          }
        }
        txn.commit();
        return true;
      } finally {
        if (userVm != null) {
          _userVMDao.releaseFromLockTable(userVmId);
        }
      }
    }
    return false;
  }
コード例 #5
0
 @Override
 public void deleteOldStats(long maxEventTime) {
   Transaction txn = Transaction.currentTxn();
   String sql = DELETE_OLD_STATS;
   PreparedStatement pstmt = null;
   try {
     txn.start();
     pstmt = txn.prepareAutoCloseStatement(sql);
     pstmt.setLong(1, maxEventTime);
     pstmt.executeUpdate();
     txn.commit();
   } catch (Exception ex) {
     txn.rollback();
     s_logger.error("error deleting old usage network stats", ex);
   }
 }
コード例 #6
0
 @Override
 @DB
 public StorageNetworkIpAddressVO takeIpAddress(long rangeId) {
   SearchCriteria<StorageNetworkIpAddressVO> sc = untakenIp.create();
   sc.setParameters("rangeId", rangeId);
   Transaction txn = Transaction.currentTxn();
   txn.start();
   StorageNetworkIpAddressVO ip = lockOneRandomRow(sc, true);
   if (ip == null) {
     txn.rollback();
     return null;
   }
   ip.setTakenAt(new Date());
   update(ip.getId(), ip);
   txn.commit();
   return ip;
 }
コード例 #7
0
ファイル: UsageDaoImpl.java プロジェクト: vogxn/cloudstack
 @Override
 public void saveUserStats(List<UserStatisticsVO> userStats) {
   Transaction txn = Transaction.currentTxn();
   try {
     txn.start();
     String sql = INSERT_USER_STATS;
     PreparedStatement pstmt = null;
     pstmt =
         txn.prepareAutoCloseStatement(
             sql); // in reality I just want CLOUD_USAGE dataSource connection
     for (UserStatisticsVO userStat : userStats) {
       pstmt.setLong(1, userStat.getId());
       pstmt.setLong(2, userStat.getDataCenterId());
       pstmt.setLong(3, userStat.getAccountId());
       pstmt.setString(4, userStat.getPublicIpAddress());
       if (userStat.getDeviceId() != null) {
         pstmt.setLong(5, userStat.getDeviceId());
       } else {
         pstmt.setNull(5, Types.BIGINT);
       }
       pstmt.setString(6, userStat.getDeviceType());
       if (userStat.getNetworkId() != null) {
         pstmt.setLong(7, userStat.getNetworkId());
       } else {
         pstmt.setNull(7, Types.BIGINT);
       }
       pstmt.setLong(8, userStat.getNetBytesReceived());
       pstmt.setLong(9, userStat.getNetBytesSent());
       pstmt.setLong(10, userStat.getCurrentBytesReceived());
       pstmt.setLong(11, userStat.getCurrentBytesSent());
       pstmt.setLong(12, userStat.getAggBytesReceived());
       pstmt.setLong(13, userStat.getAggBytesSent());
       pstmt.addBatch();
     }
     pstmt.executeBatch();
     txn.commit();
   } catch (Exception ex) {
     txn.rollback();
     s_logger.error("error saving user stats to cloud_usage db", ex);
     throw new CloudRuntimeException(ex.getMessage());
   }
 }
コード例 #8
0
ファイル: UsageDaoImpl.java プロジェクト: vogxn/cloudstack
 @Override
 public void deleteRecordsForAccount(Long accountId) {
   String sql = ((accountId == null) ? DELETE_ALL : DELETE_ALL_BY_ACCOUNTID);
   Transaction txn = Transaction.open(Transaction.USAGE_DB);
   PreparedStatement pstmt = null;
   try {
     txn.start();
     pstmt = txn.prepareAutoCloseStatement(sql);
     if (accountId != null) {
       pstmt.setLong(1, accountId.longValue());
     }
     pstmt.executeUpdate();
     txn.commit();
   } catch (Exception ex) {
     txn.rollback();
     s_logger.error("error retrieving usage vm instances for account id: " + accountId);
   } finally {
     txn.close();
   }
 }
コード例 #9
0
 public void update(UsageVPNUserVO usage) {
   Transaction txn = Transaction.open(Transaction.USAGE_DB);
   PreparedStatement pstmt = null;
   try {
     txn.start();
     if (usage.getDeleted() != null) {
       pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED);
       pstmt.setString(
           1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted()));
       pstmt.setLong(2, usage.getAccountId());
       pstmt.setLong(3, usage.getUserId());
     }
     pstmt.executeUpdate();
     txn.commit();
   } catch (Exception e) {
     txn.rollback();
     s_logger.warn("Error updating UsageVPNUserVO", e);
   } finally {
     txn.close();
   }
 }
コード例 #10
0
  @DB
  @Override
  public void allocateVmCapacity(VirtualMachine vm, boolean fromLastHost) {

    long hostId = vm.getHostId();
    HostVO host = _hostDao.findById(hostId);
    long clusterId = host.getClusterId();
    float cpuOvercommitRatio =
        Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio").getValue());
    float memoryOvercommitRatio =
        Float.parseFloat(
            _clusterDetailsDao.findDetail(clusterId, "memoryOvercommitRatio").getValue());

    ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId());

    CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
    CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);

    if (capacityCpu == null || capacityMem == null || svo == null) {
      return;
    }

    int cpu = (int) (svo.getCpu() * svo.getSpeed());
    long ram = (long) (svo.getRamSize() * 1024L * 1024L);

    Transaction txn = Transaction.currentTxn();

    try {
      txn.start();
      capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
      capacityMem = _capacityDao.lockRow(capacityMem.getId(), true);

      long usedCpu = capacityCpu.getUsedCapacity();
      long usedMem = capacityMem.getUsedCapacity();
      long reservedCpu = capacityCpu.getReservedCapacity();
      long reservedMem = capacityMem.getReservedCapacity();
      long actualTotalCpu = capacityCpu.getTotalCapacity();
      long actualTotalMem = capacityMem.getTotalCapacity();
      long totalCpu = (long) (actualTotalCpu * cpuOvercommitRatio);
      long totalMem = (long) (actualTotalMem * memoryOvercommitRatio);
      if (s_logger.isDebugEnabled()) {
        s_logger.debug(
            "Hosts's actual total CPU: "
                + actualTotalCpu
                + " and CPU after applying overprovisioning: "
                + totalCpu);
      }

      long freeCpu = totalCpu - (reservedCpu + usedCpu);
      long freeMem = totalMem - (reservedMem + usedMem);

      if (s_logger.isDebugEnabled()) {
        s_logger.debug("We are allocating VM, increasing the used capacity of this host:" + hostId);
        s_logger.debug(
            "Current Used CPU: " + usedCpu + " , Free CPU:" + freeCpu + " ,Requested CPU: " + cpu);
        s_logger.debug(
            "Current Used RAM: " + usedMem + " , Free RAM:" + freeMem + " ,Requested RAM: " + ram);
      }
      capacityCpu.setUsedCapacity(usedCpu + cpu);
      capacityMem.setUsedCapacity(usedMem + ram);

      if (fromLastHost) {
        /* alloc from reserved */
        if (s_logger.isDebugEnabled()) {
          s_logger.debug(
              "We are allocating VM to the last host again, so adjusting the reserved capacity if it is not less than required");
          s_logger.debug("Reserved CPU: " + reservedCpu + " , Requested CPU: " + cpu);
          s_logger.debug("Reserved RAM: " + reservedMem + " , Requested RAM: " + ram);
        }
        if (reservedCpu >= cpu && reservedMem >= ram) {
          capacityCpu.setReservedCapacity(reservedCpu - cpu);
          capacityMem.setReservedCapacity(reservedMem - ram);
        }
      } else {
        /* alloc from free resource */
        if (!((reservedCpu + usedCpu + cpu <= totalCpu)
            && (reservedMem + usedMem + ram <= totalMem))) {
          if (s_logger.isDebugEnabled()) {
            s_logger.debug(
                "Host doesnt seem to have enough free capacity, but increasing the used capacity anyways, since the VM is already starting on this host ");
          }
        }
      }

      s_logger.debug(
          "CPU STATS after allocation: for host: "
              + hostId
              + ", old used: "
              + usedCpu
              + ", old reserved: "
              + reservedCpu
              + ", actual total: "
              + actualTotalCpu
              + ", total with overprovisioning: "
              + totalCpu
              + "; new used:"
              + capacityCpu.getUsedCapacity()
              + ", reserved:"
              + capacityCpu.getReservedCapacity()
              + "; requested cpu:"
              + cpu
              + ",alloc_from_last:"
              + fromLastHost);

      s_logger.debug(
          "RAM STATS after allocation: for host: "
              + hostId
              + ", old used: "
              + usedMem
              + ", old reserved: "
              + reservedMem
              + ", total: "
              + totalMem
              + "; new used: "
              + capacityMem.getUsedCapacity()
              + ", reserved: "
              + capacityMem.getReservedCapacity()
              + "; requested mem: "
              + ram
              + ",alloc_from_last:"
              + fromLastHost);

      _capacityDao.update(capacityCpu.getId(), capacityCpu);
      _capacityDao.update(capacityMem.getId(), capacityMem);
      txn.commit();
    } catch (Exception e) {
      txn.rollback();
      return;
    }
  }
コード例 #11
0
  @DB
  @Override
  public boolean releaseVmCapacity(
      VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId) {
    ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId());
    CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
    CapacityVO capacityMemory =
        _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
    Long clusterId = null;
    if (hostId != null) {
      HostVO host = _hostDao.findById(hostId);
      clusterId = host.getClusterId();
    }
    if (capacityCpu == null || capacityMemory == null || svo == null) {
      return false;
    }

    Transaction txn = Transaction.currentTxn();
    try {
      txn.start();

      capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
      capacityMemory = _capacityDao.lockRow(capacityMemory.getId(), true);

      long usedCpu = capacityCpu.getUsedCapacity();
      long usedMem = capacityMemory.getUsedCapacity();
      long reservedCpu = capacityCpu.getReservedCapacity();
      long reservedMem = capacityMemory.getReservedCapacity();
      long actualTotalCpu = capacityCpu.getTotalCapacity();
      float cpuOvercommitRatio =
          Float.parseFloat(
              _clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio").getValue());
      float memoryOvercommitRatio =
          Float.parseFloat(
              _clusterDetailsDao.findDetail(clusterId, "memoryOvercommitRatio").getValue());
      int vmCPU = (int) (svo.getCpu() * svo.getSpeed());
      long vmMem = (long) (svo.getRamSize() * 1024L * 1024L);
      long actualTotalMem = capacityMemory.getTotalCapacity();
      long totalMem = (long) (actualTotalMem * memoryOvercommitRatio);
      long totalCpu = (long) (actualTotalCpu * cpuOvercommitRatio);
      if (s_logger.isDebugEnabled()) {
        s_logger.debug(
            "Hosts's actual total CPU: "
                + actualTotalCpu
                + " and CPU after applying overprovisioning: "
                + totalCpu);
        s_logger.debug(
            "Hosts's actual total RAM: "
                + actualTotalMem
                + " and RAM after applying overprovisioning: "
                + totalMem);
      }

      if (!moveFromReserved) {
        /* move resource from used */
        if (usedCpu >= vmCPU) {
          capacityCpu.setUsedCapacity(usedCpu - vmCPU);
        }
        if (usedMem >= vmMem) {
          capacityMemory.setUsedCapacity(usedMem - vmMem);
        }

        if (moveToReservered) {
          if (reservedCpu + vmCPU <= totalCpu) {
            capacityCpu.setReservedCapacity(reservedCpu + vmCPU);
          }
          if (reservedMem + vmMem <= totalMem) {
            capacityMemory.setReservedCapacity(reservedMem + vmMem);
          }
        }
      } else {
        if (reservedCpu >= vmCPU) {
          capacityCpu.setReservedCapacity(reservedCpu - vmCPU);
        }
        if (reservedMem >= vmMem) {
          capacityMemory.setReservedCapacity(reservedMem - vmMem);
        }
      }

      s_logger.debug(
          "release cpu from host: "
              + hostId
              + ", old used: "
              + usedCpu
              + ",reserved: "
              + reservedCpu
              + ", actual total: "
              + actualTotalCpu
              + ", total with overprovisioning: "
              + totalCpu
              + "; new used: "
              + capacityCpu.getUsedCapacity()
              + ",reserved:"
              + capacityCpu.getReservedCapacity()
              + "; movedfromreserved: "
              + moveFromReserved
              + ",moveToReservered"
              + moveToReservered);

      s_logger.debug(
          "release mem from host: "
              + hostId
              + ", old used: "
              + usedMem
              + ",reserved: "
              + reservedMem
              + ", total: "
              + totalMem
              + "; new used: "
              + capacityMemory.getUsedCapacity()
              + ",reserved:"
              + capacityMemory.getReservedCapacity()
              + "; movedfromreserved: "
              + moveFromReserved
              + ",moveToReservered"
              + moveToReservered);

      _capacityDao.update(capacityCpu.getId(), capacityCpu);
      _capacityDao.update(capacityMemory.getId(), capacityMemory);
      txn.commit();
      return true;
    } catch (Exception e) {
      s_logger.debug("Failed to transit vm's state, due to " + e.getMessage());
      txn.rollback();
      return false;
    }
  }
コード例 #12
0
  @Override
  @DB
  @SuppressWarnings("rawtypes")
  public List<IngressRuleVO> authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd) {
    Long securityGroupId = cmd.getSecurityGroupId();
    String protocol = cmd.getProtocol();
    Integer startPort = cmd.getStartPort();
    Integer endPort = cmd.getEndPort();
    Integer icmpType = cmd.getIcmpType();
    Integer icmpCode = cmd.getIcmpCode();
    List<String> cidrList = cmd.getCidrList();
    Map groupList = cmd.getUserSecurityGroupList();
    Integer startPortOrType = null;
    Integer endPortOrCode = null;

    // Validate parameters
    SecurityGroup securityGroup = _securityGroupDao.findById(securityGroupId);
    if (securityGroup == null) {
      throw new InvalidParameterValueException(
          "Unable to find security group by id " + securityGroupId);
    }

    if (cidrList == null && groupList == null) {
      throw new InvalidParameterValueException(
          "At least one cidr or at least one security group needs to be specified");
    }

    Account caller = UserContext.current().getCaller();
    Account owner = _accountMgr.getAccount(securityGroup.getAccountId());

    if (owner == null) {
      throw new InvalidParameterValueException(
          "Unable to find security group owner by id=" + securityGroup.getAccountId());
    }

    // Verify permissions
    _accountMgr.checkAccess(caller, null, securityGroup);
    Long domainId = owner.getDomainId();

    if (protocol == null) {
      protocol = NetUtils.ALL_PROTO;
    }

    if (!NetUtils.isValidSecurityGroupProto(protocol)) {
      throw new InvalidParameterValueException("Invalid protocol " + protocol);
    }
    if ("icmp".equalsIgnoreCase(protocol)) {
      if ((icmpType == null) || (icmpCode == null)) {
        throw new InvalidParameterValueException(
            "Invalid ICMP type/code specified, icmpType = "
                + icmpType
                + ", icmpCode = "
                + icmpCode);
      }
      if (icmpType == -1 && icmpCode != -1) {
        throw new InvalidParameterValueException("Invalid icmp type range");
      }
      if (icmpCode > 255) {
        throw new InvalidParameterValueException("Invalid icmp code ");
      }
      startPortOrType = icmpType;
      endPortOrCode = icmpCode;
    } else if (protocol.equals(NetUtils.ALL_PROTO)) {
      if ((startPort != null) || (endPort != null)) {
        throw new InvalidParameterValueException(
            "Cannot specify startPort or endPort without specifying protocol");
      }
      startPortOrType = 0;
      endPortOrCode = 0;
    } else {
      if ((startPort == null) || (endPort == null)) {
        throw new InvalidParameterValueException(
            "Invalid port range specified, startPort = " + startPort + ", endPort = " + endPort);
      }
      if (startPort == 0 && endPort == 0) {
        endPort = 65535;
      }
      if (startPort > endPort) {
        throw new InvalidParameterValueException("Invalid port range " + startPort + ":" + endPort);
      }
      if (startPort > 65535 || endPort > 65535 || startPort < -1 || endPort < -1) {
        throw new InvalidParameterValueException(
            "Invalid port numbers " + startPort + ":" + endPort);
      }

      if (startPort < 0 || endPort < 0) {
        throw new InvalidParameterValueException("Invalid port range " + startPort + ":" + endPort);
      }
      startPortOrType = startPort;
      endPortOrCode = endPort;
    }

    protocol = protocol.toLowerCase();

    List<SecurityGroupVO> authorizedGroups = new ArrayList<SecurityGroupVO>();
    if (groupList != null) {
      Collection userGroupCollection = groupList.values();
      Iterator iter = userGroupCollection.iterator();
      while (iter.hasNext()) {
        HashMap userGroup = (HashMap) iter.next();
        String group = (String) userGroup.get("group");
        String authorizedAccountName = (String) userGroup.get("account");

        if ((group == null) || (authorizedAccountName == null)) {
          throw new InvalidParameterValueException(
              "Invalid user group specified, fields 'group' and 'account' cannot be null, please specify groups in the form:  userGroupList[0].group=XXX&userGroupList[0].account=YYY");
        }

        Account authorizedAccount = _accountDao.findActiveAccount(authorizedAccountName, domainId);
        if (authorizedAccount == null) {
          throw new InvalidParameterValueException(
              "Nonexistent account: "
                  + authorizedAccountName
                  + " when trying to authorize ingress for "
                  + securityGroupId
                  + ":"
                  + protocol
                  + ":"
                  + startPortOrType
                  + ":"
                  + endPortOrCode);
        }

        SecurityGroupVO groupVO =
            _securityGroupDao.findByAccountAndName(authorizedAccount.getId(), group);
        if (groupVO == null) {
          throw new InvalidParameterValueException(
              "Nonexistent group "
                  + group
                  + " for account "
                  + authorizedAccountName
                  + "/"
                  + domainId
                  + " is given, unable to authorize ingress.");
        }

        // Check permissions
        if (domainId != groupVO.getDomainId()) {
          throw new PermissionDeniedException(
              "Can't add security group id="
                  + groupVO.getDomainId()
                  + " as it belongs to different domain");
        }

        authorizedGroups.add(groupVO);
      }
    }

    final Transaction txn = Transaction.currentTxn();
    final Set<SecurityGroupVO> authorizedGroups2 =
        new TreeSet<SecurityGroupVO>(new SecurityGroupVOComparator());

    authorizedGroups2.addAll(authorizedGroups); // Ensure we don't re-lock the same row
    txn.start();

    // Prevents other threads/management servers from creating duplicate ingress rules
    securityGroup = _securityGroupDao.acquireInLockTable(securityGroupId);
    if (securityGroup == null) {
      s_logger.warn("Could not acquire lock on network security group: id= " + securityGroupId);
      return null;
    }
    List<IngressRuleVO> newRules = new ArrayList<IngressRuleVO>();
    try {
      for (final SecurityGroupVO ngVO : authorizedGroups2) {
        final Long ngId = ngVO.getId();
        // Don't delete the referenced group from under us
        if (ngVO.getId() != securityGroup.getId()) {
          final SecurityGroupVO tmpGrp = _securityGroupDao.lockRow(ngId, false);
          if (tmpGrp == null) {
            s_logger.warn("Failed to acquire lock on security group: " + ngId);
            txn.rollback();
            return null;
          }
        }
        IngressRuleVO ingressRule =
            _ingressRuleDao.findByProtoPortsAndAllowedGroupId(
                securityGroup.getId(), protocol, startPortOrType, endPortOrCode, ngVO.getId());
        if (ingressRule != null) {
          continue; // rule already exists.
        }
        ingressRule =
            new IngressRuleVO(
                securityGroup.getId(), startPortOrType, endPortOrCode, protocol, ngVO.getId());
        ingressRule = _ingressRuleDao.persist(ingressRule);
        newRules.add(ingressRule);
      }
      if (cidrList != null) {
        for (String cidr : cidrList) {
          IngressRuleVO ingressRule =
              _ingressRuleDao.findByProtoPortsAndCidr(
                  securityGroup.getId(), protocol, startPortOrType, endPortOrCode, cidr);
          if (ingressRule != null) {
            continue;
          }
          ingressRule =
              new IngressRuleVO(
                  securityGroup.getId(), startPortOrType, endPortOrCode, protocol, cidr);
          ingressRule = _ingressRuleDao.persist(ingressRule);
          newRules.add(ingressRule);
        }
      }
      if (s_logger.isDebugEnabled()) {
        s_logger.debug(
            "Added " + newRules.size() + " rules to security group " + securityGroup.getName());
      }
      txn.commit();
      final ArrayList<Long> affectedVms = new ArrayList<Long>();
      affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(securityGroup.getId()));
      scheduleRulesetUpdateToHosts(affectedVms, true, null);
      return newRules;
    } catch (Exception e) {
      s_logger.warn("Exception caught when adding ingress rules ", e);
      throw new CloudRuntimeException("Exception caught when adding ingress rules", e);
    } finally {
      if (securityGroup != null) {
        _securityGroupDao.releaseFromLockTable(securityGroup.getId());
      }
    }
  }
コード例 #13
0
    @Override
    public void run() {
      try {
        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
        sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Storage.toString());

        ConcurrentHashMap<Long, StorageStats> storageStats =
            new ConcurrentHashMap<Long, StorageStats>();
        List<HostVO> hosts = _hostDao.search(sc, null);
        for (HostVO host : hosts) {
          GetStorageStatsCommand command = new GetStorageStatsCommand(host.getGuid());
          Answer answer = _agentMgr.easySend(host.getId(), command);
          if (answer != null && answer.getResult()) {
            storageStats.put(host.getId(), (StorageStats) answer);
          }
        }

        sc = _hostDao.createSearchCriteria();
        sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.SecondaryStorage.toString());

        hosts = _hostDao.search(sc, null);
        for (HostVO host : hosts) {
          GetStorageStatsCommand command = new GetStorageStatsCommand(host.getGuid());
          Answer answer = _agentMgr.easySend(host.getId(), command);
          if (answer != null && answer.getResult()) {
            storageStats.put(host.getId(), (StorageStats) answer);
          }
        }
        _storageStats = storageStats;

        ConcurrentHashMap<Long, StorageStats> storagePoolStats =
            new ConcurrentHashMap<Long, StorageStats>();

        List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
        for (StoragePoolVO pool : storagePools) {
          GetStorageStatsCommand command =
              new GetStorageStatsCommand(pool.getUuid(), pool.getPoolType(), pool.getPath());
          Answer answer = _storageManager.sendToPool(pool, command);
          if (answer != null && answer.getResult()) {
            storagePoolStats.put(pool.getId(), (StorageStats) answer);
          }
        }
        _storagePoolStats = storagePoolStats;

        // a list to store the new capacity entries that will be committed once everything is
        // calculated
        List<CapacityVO> newCapacities = new ArrayList<CapacityVO>();

        // Updating the storage entries and creating new ones if they dont exist.
        Transaction txn = Transaction.open(Transaction.CLOUD_DB);
        try {
          if (s_logger.isTraceEnabled()) {
            s_logger.trace("recalculating system storage capacity");
          }
          txn.start();
          for (Long hostId : storageStats.keySet()) {
            StorageStats stats = storageStats.get(hostId);
            short capacityType = -1;
            HostVO host = _hostDao.findById(hostId);
            host.setTotalSize(stats.getCapacityBytes());
            _hostDao.update(host.getId(), host);

            SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
            capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
            capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, host.getDataCenterId());

            if (Host.Type.SecondaryStorage.equals(host.getType())) {
              capacityType = CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE;
            } else if (Host.Type.Storage.equals(host.getType())) {
              capacityType = CapacityVO.CAPACITY_TYPE_STORAGE;
            }
            if (-1 != capacityType) {
              capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
              List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
              if (capacities.size() == 0) { // Create a new one
                CapacityVO capacity =
                    new CapacityVO(
                        host.getId(),
                        host.getDataCenterId(),
                        host.getPodId(),
                        stats.getByteUsed(),
                        stats.getCapacityBytes(),
                        capacityType);
                _capacityDao.persist(capacity);
              } else { // Update if it already exists.
                CapacityVO capacity = capacities.get(0);
                capacity.setUsedCapacity(stats.getByteUsed());
                capacity.setTotalCapacity(stats.getCapacityBytes());
                _capacityDao.update(capacity.getId(), capacity);
              }
            }
          } // End of for
          txn.commit();
        } catch (Exception ex) {
          txn.rollback();
          s_logger.error("Unable to start transaction for storage capacity update");
        } finally {
          txn.close();
        }

        for (Long poolId : storagePoolStats.keySet()) {
          StorageStats stats = storagePoolStats.get(poolId);
          StoragePoolVO pool = _storagePoolDao.findById(poolId);

          if (pool == null) {
            continue;
          }

          pool.setCapacityBytes(stats.getCapacityBytes());
          long available = stats.getCapacityBytes() - stats.getByteUsed();
          if (available < 0) {
            available = 0;
          }
          pool.setAvailableBytes(available);
          _storagePoolDao.update(pool.getId(), pool);

          _storageManager.createCapacityEntry(pool, 0L);
        }
      } catch (Throwable t) {
        s_logger.error("Error trying to retrieve storage stats", t);
      }
    }
コード例 #14
0
  @Override
  public CiscoVnmcController addCiscoVnmcResource(AddCiscoVnmcResourceCmd cmd) {
    String deviceName = Provider.CiscoVnmc.getName();
    NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName);
    Long physicalNetworkId = cmd.getPhysicalNetworkId();
    CiscoVnmcController ciscoVnmcResource = null;

    PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
    if (physicalNetwork == null) {
      throw new InvalidParameterValueException(
          "Could not find phyical network with ID: " + physicalNetworkId);
    }
    long zoneId = physicalNetwork.getDataCenterId();

    PhysicalNetworkServiceProviderVO ntwkSvcProvider =
        _physicalNetworkServiceProviderDao.findByServiceProvider(
            physicalNetwork.getId(), networkDevice.getNetworkServiceProvder());
    if (ntwkSvcProvider == null) {
      throw new CloudRuntimeException(
          "Network Service Provider: "
              + networkDevice.getNetworkServiceProvder()
              + " is not enabled in the physical network: "
              + physicalNetworkId
              + "to add this device");
    } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
      throw new CloudRuntimeException(
          "Network Service Provider: "
              + ntwkSvcProvider.getProviderName()
              + " is in shutdown state in the physical network: "
              + physicalNetworkId
              + "to add this device");
    }

    if (_ciscoVnmcDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) {
      throw new CloudRuntimeException(
          "A Cisco Vnmc device is already configured on this physical network");
    }

    Map<String, String> params = new HashMap<String, String>();
    params.put("guid", UUID.randomUUID().toString());
    params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId()));
    params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId()));
    params.put("name", "Cisco VNMC Controller - " + cmd.getHost());
    params.put("ip", cmd.getHost());
    params.put("username", cmd.getUsername());
    params.put("password", cmd.getPassword());

    Map<String, Object> hostdetails = new HashMap<String, Object>();
    hostdetails.putAll(params);

    ServerResource resource = new CiscoVnmcResource();
    Transaction txn = Transaction.currentTxn();
    try {
      resource.configure(cmd.getHost(), hostdetails);

      Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, params);
      if (host != null) {
        txn.start();

        ciscoVnmcResource =
            new CiscoVnmcControllerVO(
                host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName);
        _ciscoVnmcDao.persist((CiscoVnmcControllerVO) ciscoVnmcResource);

        DetailVO detail =
            new DetailVO(host.getId(), "deviceid", String.valueOf(ciscoVnmcResource.getId()));
        _hostDetailsDao.persist(detail);

        txn.commit();
        return ciscoVnmcResource;
      } else {
        throw new CloudRuntimeException("Failed to add Cisco Vnmc device due to internal error.");
      }
    } catch (ConfigurationException e) {
      txn.rollback();
      throw new CloudRuntimeException(e.getMessage());
    }
  }
コード例 #15
0
  @Override
  public List<UsageVPNUserVO> getUsageRecords(
      Long accountId, Long domainId, Date startDate, Date endDate, boolean limit, int page) {
    List<UsageVPNUserVO> usageRecords = new ArrayList<UsageVPNUserVO>();

    Long param1 = null;
    String sql = null;
    if (accountId != null) {
      sql = GET_USAGE_RECORDS_BY_ACCOUNT;
      param1 = accountId;
    } else if (domainId != null) {
      sql = GET_USAGE_RECORDS_BY_DOMAIN;
      param1 = domainId;
    } else {
      sql = GET_ALL_USAGE_RECORDS;
    }

    if (limit) {
      int startIndex = 0;
      if (page > 0) {
        startIndex = 500 * (page - 1);
      }
      sql += " LIMIT " + startIndex + ",500";
    }

    Transaction txn = Transaction.open(Transaction.USAGE_DB);
    PreparedStatement pstmt = null;

    try {
      int i = 1;
      pstmt = txn.prepareAutoCloseStatement(sql);
      if (param1 != null) {
        pstmt.setLong(i++, param1);
      }
      pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
      pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
      pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
      pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
      pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
      pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));

      ResultSet rs = pstmt.executeQuery();
      while (rs.next()) {
        // zoneId, account_id, domain_id, user_id, user_name, created, deleted
        Long zoneId = Long.valueOf(rs.getLong(1));
        Long acctId = Long.valueOf(rs.getLong(2));
        Long dId = Long.valueOf(rs.getLong(3));
        long userId = Long.valueOf(rs.getLong(4));
        String userName = rs.getString(5);
        Date createdDate = null;
        Date deletedDate = null;
        String createdTS = rs.getString(6);
        String deletedTS = rs.getString(7);

        if (createdTS != null) {
          createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS);
        }
        if (deletedTS != null) {
          deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS);
        }

        usageRecords.add(
            new UsageVPNUserVO(zoneId, acctId, dId, userId, userName, createdDate, deletedDate));
      }
    } catch (Exception e) {
      txn.rollback();
      s_logger.warn("Error getting usage records", e);
    } finally {
      txn.close();
    }

    return usageRecords;
  }
コード例 #16
0
  @Override
  @DB
  public void destroyRemoteAccessVpn(long ipId, Account caller)
      throws ResourceUnavailableException {
    RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(ipId);
    if (vpn == null) {
      s_logger.debug("vpn id=" + ipId + " does not exists ");
      return;
    }

    _accountMgr.checkAccess(caller, null, true, vpn);

    Network network = _networkMgr.getNetwork(vpn.getNetworkId());

    vpn.setState(RemoteAccessVpn.State.Removed);
    _remoteAccessVpnDao.update(vpn.getServerAddressId(), vpn);

    boolean success = false;
    try {
      for (RemoteAccessVPNServiceProvider element : _vpnServiceProviders) {
        if (element.stopVpn(network, vpn)) {
          success = true;
          break;
        }
      }
    } finally {
      if (success) {
        // Cleanup corresponding ports
        List<? extends FirewallRule> vpnFwRules = _rulesDao.listByIpAndPurpose(ipId, Purpose.Vpn);
        Transaction txn = Transaction.currentTxn();

        boolean applyFirewall = false;
        List<FirewallRuleVO> fwRules = new ArrayList<FirewallRuleVO>();
        // if related firewall rule is created for the first vpn port, it would be created for the 2
        // other ports as well, so need to cleanup the backend
        if (_rulesDao.findByRelatedId(vpnFwRules.get(0).getId()) != null) {
          applyFirewall = true;
        }

        if (applyFirewall) {
          txn.start();

          for (FirewallRule vpnFwRule : vpnFwRules) {
            // don't apply on the backend yet; send all 3 rules in a banch
            _firewallMgr.revokeRelatedFirewallRule(vpnFwRule.getId(), false);
            fwRules.add(_rulesDao.findByRelatedId(vpnFwRule.getId()));
          }

          s_logger.debug(
              "Marked "
                  + fwRules.size()
                  + " firewall rules as Revoked as a part of disable remote access vpn");

          txn.commit();

          // now apply vpn rules on the backend
          s_logger.debug(
              "Reapplying firewall rules for ip id="
                  + ipId
                  + " as a part of disable remote access vpn");
          success = _firewallMgr.applyIngressFirewallRules(ipId, caller);
        }

        if (success) {
          try {
            txn.start();
            _remoteAccessVpnDao.remove(ipId);
            // Stop billing of VPN users when VPN is removed. VPN_User_ADD events will be generated
            // when VPN is created again
            List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
            for (VpnUserVO user : vpnUsers) {
              // VPN_USER_REMOVE event is already generated for users in Revoke state
              if (user.getState() != VpnUser.State.Revoke) {
                UsageEventUtils.publishUsageEvent(
                    EventTypes.EVENT_VPN_USER_REMOVE,
                    user.getAccountId(),
                    0,
                    user.getId(),
                    user.getUsername(),
                    user.getClass().getName(),
                    user.getUuid());
              }
            }
            if (vpnFwRules != null) {
              for (FirewallRule vpnFwRule : vpnFwRules) {
                _rulesDao.remove(vpnFwRule.getId());
                s_logger.debug(
                    "Successfully removed firewall rule with ip id="
                        + vpnFwRule.getSourceIpAddressId()
                        + " and port "
                        + vpnFwRule.getSourcePortStart()
                        + " as a part of vpn cleanup");
              }
            }
            txn.commit();
          } catch (Exception ex) {
            txn.rollback();
            s_logger.warn("Unable to release the three vpn ports from the firewall rules", ex);
          }
        }
      }
    }
  }
コード例 #17
0
  @Override
  @DB
  public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
    VmwareDatacenterVO vmwareDc = null;
    Long zoneId = cmd.getZoneId();
    String userName = cmd.getUsername();
    String password = cmd.getPassword();
    String vCenterHost = cmd.getVcenter();
    String vmwareDcName = cmd.getName();

    // Validate username, password, VMware DC name and vCenter
    if (userName == null) {
      throw new InvalidParameterValueException("Missing or invalid parameter username.");
    }

    if (password == null) {
      throw new InvalidParameterValueException("Missing or invalid parameter username.");
    }

    if (vmwareDcName == null) {
      throw new InvalidParameterValueException(
          "Missing or invalid parameter name. Please provide valid VMware datacenter name.");
    }

    if (vCenterHost == null) {
      throw new InvalidParameterValueException(
          "Missing or invalid parameter name. "
              + "Please provide valid VMware vCenter server's IP address or fully qualified domain name.");
    }

    if (zoneId == null) {
      throw new InvalidParameterValueException(
          "Missing or invalid parameter name. " + "Please provide valid zone id.");
    }

    // Zone validation
    validateZone(zoneId);

    VmwareDatacenterZoneMapVO vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId);
    // Check if zone is associated with VMware DC
    if (vmwareDcZoneMap != null) {
      // Check if the associated VMware DC matches the one specified in API params
      // This check would yield success as the association exists between same entities (zone and
      // VMware DC)
      // This scenario would result in if the API addVmwareDc is called more than once with same
      // parameters.
      Long associatedVmwareDcId = vmwareDcZoneMap.getVmwareDcId();
      VmwareDatacenterVO associatedVmwareDc = _vmwareDcDao.findById(associatedVmwareDcId);
      if (associatedVmwareDc.getVcenterHost().equalsIgnoreCase(vCenterHost)
          && associatedVmwareDc.getVmwareDatacenterName().equalsIgnoreCase(vmwareDcName)) {
        s_logger.info(
            "Ignoring API call addVmwareDc, because VMware DC "
                + vCenterHost
                + "/"
                + vmwareDcName
                + " is already associated with specified zone with id "
                + zoneId);
        return associatedVmwareDc;
      } else {
        throw new CloudRuntimeException(
            "Zone "
                + zoneId
                + " is already associated with a VMware datacenter. "
                + "Only 1 VMware DC can be associated with a zone.");
      }
    }
    // Zone validation to check if the zone already has resources.
    // Association of VMware DC to zone is not allowed if zone already has resources added.
    validateZoneWithResources(zoneId, "add VMware datacenter to zone");

    // Check if DC is already part of zone
    // In that case vmware_data_center table should have the DC
    vmwareDc = _vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost);
    if (vmwareDc != null) {
      throw new ResourceInUseException(
          "This DC is already part of other CloudStack zone(s). Cannot add this DC to more zones.");
    }

    VmwareContext context = null;
    DatacenterMO dcMo = null;
    String dcCustomFieldValue;
    boolean addDcCustomFieldDef = false;
    boolean dcInUse = false;
    String guid;
    ManagedObjectReference dcMor;
    try {
      context = VmwareContextFactory.create(vCenterHost, userName, password);

      // Check if DC exists on vCenter
      dcMo = new DatacenterMO(context, vmwareDcName);
      dcMor = dcMo.getMor();
      if (dcMor == null) {
        String msg =
            "Unable to find VMware DC " + vmwareDcName + " in vCenter " + vCenterHost + ". ";
        s_logger.error(msg);
        throw new InvalidParameterValueException(msg);
      }

      // Check if DC is already associated with another cloudstack deployment
      // Get custom field property cloud.zone over this DC
      guid = vmwareDcName + "@" + vCenterHost;

      dcCustomFieldValue = dcMo.getCustomFieldValue(CustomFieldConstants.CLOUD_ZONE);
      if (dcCustomFieldValue == null) {
        addDcCustomFieldDef = true;
      }
      dcInUse = Boolean.parseBoolean(dcCustomFieldValue);
      if (dcInUse) {
        throw new ResourceInUseException(
            "This DC is being managed by other CloudStack deployment. Cannot add this DC to zone.");
      }

      // Add DC to database into vmware_data_center table
      vmwareDc = new VmwareDatacenterVO(guid, vmwareDcName, vCenterHost, userName, password);
      Transaction txn = Transaction.currentTxn();
      try {
        txn.start();
        vmwareDc = _vmwareDcDao.persist(vmwareDc);
        txn.commit();
      } catch (Exception e) {
        txn.rollback();
        s_logger.error(
            "Failed to persist VMware datacenter details to database. Exception: "
                + e.getMessage());
        throw new CloudRuntimeException(e.getMessage());
      }

      // Map zone with vmware datacenter
      vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());

      txn = Transaction.currentTxn();
      try {
        txn.start();
        vmwareDcZoneMap = _vmwareDcZoneMapDao.persist(vmwareDcZoneMap);
        txn.commit();
      } catch (Exception e) {
        txn.rollback();
        s_logger.error(
            "Failed to associate VMware datacenter with zone "
                + zoneId
                + ". Exception: "
                + e.getMessage());
        // Removing VMware datacenter from vmware_data_center table because association with zone
        // failed.
        _vmwareDcDao.remove(vmwareDcZoneMap.getId());
        throw new CloudRuntimeException(e.getMessage());
      }

      // Set custom field for this DC
      if (addDcCustomFieldDef) {
        dcMo.ensureCustomFieldDef(CustomFieldConstants.CLOUD_ZONE);
      }
      dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "true");

    } catch (Throwable e) {
      String msg = "Failed to add VMware DC to zone ";
      if (e instanceof RemoteException) {
        msg = "Encountered remote exception at vCenter. " + VmwareHelper.getExceptionMessage(e);
      } else {
        msg += "due to : " + e.getMessage();
      }
      throw new CloudRuntimeException(msg);
    } finally {
      if (context != null) {
        context.close();
      }
      context = null;
    }
    return vmwareDc;
  }
コード例 #18
0
  @Override
  public boolean implement(
      Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
      throws ConcurrentOperationException, ResourceUnavailableException,
          InsufficientCapacityException {
    DataCenter zone = _configMgr.getZone(network.getDataCenterId());

    if (zone.getNetworkType() == NetworkType.Basic) {
      s_logger.debug("Not handling network implement in zone of type " + NetworkType.Basic);
      return false;
    }

    if (!canHandle(network)) {
      return false;
    }

    List<CiscoVnmcControllerVO> devices =
        _ciscoVnmcDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
    if (devices.isEmpty()) {
      s_logger.error("No Cisco Vnmc device on network " + network.getName());
      return false;
    }

    List<CiscoAsa1000vDeviceVO> asaList =
        _ciscoAsa1000vDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
    if (asaList.isEmpty()) {
      s_logger.debug("No Cisco ASA 1000v device on network " + network.getName());
      return false;
    }

    NetworkAsa1000vMapVO asaForNetwork = _networkAsa1000vMapDao.findByNetworkId(network.getId());
    if (asaForNetwork != null) {
      s_logger.debug("Cisco ASA 1000v device already associated with network " + network.getName());
      return true;
    }

    if (!_networkModel.isProviderSupportServiceInNetwork(
        network.getId(), Service.SourceNat, Provider.CiscoVnmc)) {
      s_logger.error(
          "SourceNat service is not provided by Cisco Vnmc device on network " + network.getName());
      return false;
    }

    Transaction txn = Transaction.currentTxn();
    boolean status = false;
    try {
      txn.start();

      // ensure that there is an ASA 1000v assigned to this network
      CiscoAsa1000vDevice assignedAsa = assignAsa1000vToNetwork(network);
      if (assignedAsa == null) {
        s_logger.error("Unable to assign ASA 1000v device to network " + network.getName());
        return false;
      }

      ClusterVO asaCluster = _clusterDao.findById(assignedAsa.getClusterId());
      ClusterVSMMapVO clusterVsmMap = _clusterVsmMapDao.findByClusterId(assignedAsa.getClusterId());
      if (clusterVsmMap == null) {
        s_logger.error(
            "Vmware cluster "
                + asaCluster.getName()
                + " has no Cisco Nexus VSM device associated with it");
        return false;
      }

      CiscoNexusVSMDeviceVO vsmDevice = _vsmDeviceDao.findById(clusterVsmMap.getVsmId());
      if (vsmDevice == null) {
        s_logger.error(
            "Unable to load details of Cisco Nexus VSM device associated with cluster "
                + asaCluster.getName());
        return false;
      }

      CiscoVnmcControllerVO ciscoVnmcDevice = devices.get(0);
      HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcDevice.getHostId());
      _hostDao.loadDetails(ciscoVnmcHost);
      Account owner = context.getAccount();
      PublicIp sourceNatIp = _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network);
      String vlan = network.getBroadcastUri().getHost();
      long vlanId = Long.parseLong(vlan);

      List<VlanVO> vlanVOList =
          _vlanDao.listVlansByPhysicalNetworkId(network.getPhysicalNetworkId());
      List<String> publicGateways = new ArrayList<String>();
      for (VlanVO vlanVO : vlanVOList) {
        publicGateways.add(vlanVO.getVlanGateway());
      }

      // due to VNMC limitation of not allowing source NAT ip as the outside ip of firewall,
      // an additional public ip needs to acquired for assigning as firewall outside ip.
      // In case there are already additional ip addresses available (network restart) use one
      // of them such that it is not the source NAT ip
      IpAddress outsideIp = null;
      List<IPAddressVO> publicIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
      for (IPAddressVO ip : publicIps) {
        if (!ip.isSourceNat()) {
          outsideIp = ip;
          break;
        }
      }
      if (outsideIp == null) { // none available, acquire one
        try {
          Account caller = CallContext.current().getCallingAccount();
          long callerUserId = CallContext.current().getCallingUserId();
          outsideIp = _ipAddrMgr.allocateIp(owner, false, caller, callerUserId, zone);
        } catch (ResourceAllocationException e) {
          s_logger.error("Unable to allocate additional public Ip address. Exception details " + e);
          return false;
        }

        try {
          outsideIp =
              _ipAddrMgr.associateIPToGuestNetwork(outsideIp.getId(), network.getId(), true);
        } catch (ResourceAllocationException e) {
          s_logger.error(
              "Unable to assign allocated additional public Ip "
                  + outsideIp.getAddress().addr()
                  + " to network with vlan "
                  + vlanId
                  + ". Exception details "
                  + e);
          return false;
        }
      }

      // create logical edge firewall in VNMC
      String gatewayNetmask = NetUtils.getCidrNetmask(network.getCidr());
      // due to ASA limitation of allowing single subnet to be assigned to firewall interfaces,
      // all public ip addresses must be from same subnet, this essentially means single public
      // subnet in zone
      if (!createLogicalEdgeFirewall(
          vlanId,
          network.getGateway(),
          gatewayNetmask,
          outsideIp.getAddress().addr(),
          sourceNatIp.getNetmask(),
          publicGateways,
          ciscoVnmcHost.getId())) {
        s_logger.error(
            "Failed to create logical edge firewall in Cisco VNMC device for network "
                + network.getName());
        return false;
      }

      // create stuff in VSM for ASA device
      if (!configureNexusVsmForAsa(
          vlanId,
          network.getGateway(),
          vsmDevice.getUserName(),
          vsmDevice.getPassword(),
          vsmDevice.getipaddr(),
          assignedAsa.getInPortProfile(),
          ciscoVnmcHost.getId())) {
        s_logger.error(
            "Failed to configure Cisco Nexus VSM "
                + vsmDevice.getipaddr()
                + " for ASA device for network "
                + network.getName());
        return false;
      }

      // configure source NAT
      if (!configureSourceNat(vlanId, network.getCidr(), sourceNatIp, ciscoVnmcHost.getId())) {
        s_logger.error(
            "Failed to configure source NAT in Cisco VNMC device for network " + network.getName());
        return false;
      }

      // associate Asa 1000v instance with logical edge firewall
      if (!associateAsaWithLogicalEdgeFirewall(
          vlanId, assignedAsa.getManagementIp(), ciscoVnmcHost.getId())) {
        s_logger.error(
            "Failed to associate Cisco ASA 1000v ("
                + assignedAsa.getManagementIp()
                + ") with logical edge firewall in VNMC for network "
                + network.getName());
        return false;
      }

      status = true;
      txn.commit();
    } finally {
      if (!status) {
        txn.rollback();
        // FIXME: also undo changes in VNMC, VSM if anything failed
      }
    }

    return true;
  }