@Override
  @DB
  public VpnUser addVpnUser(long vpnOwnerId, String username, String password) {
    Account caller = UserContext.current().getCaller();

    if (!username.matches("^[a-zA-Z0-9][a-zA-Z0-9@._-]{2,63}$")) {
      throw new InvalidParameterValueException(
          "Username has to be begin with an alphabet have 3-64 characters including alphabets, numbers and the set '@.-_'");
    }
    if (!password.matches("^[a-zA-Z0-9][a-zA-Z0-9@#+=._-]{2,31}$")) {
      throw new InvalidParameterValueException(
          "Password has to be 3-32 characters including alphabets, numbers and the set '@#+=.-_'");
    }
    Transaction txn = Transaction.currentTxn();
    txn.start();
    Account owner = _accountDao.lockRow(vpnOwnerId, true);
    if (owner == null) {
      throw new InvalidParameterValueException("Unable to add vpn user: Another operation active");
    }
    _accountMgr.checkAccess(caller, null, true, owner);

    // don't allow duplicated user names for the same account
    VpnUserVO vpnUser = _vpnUsersDao.findByAccountAndUsername(owner.getId(), username);
    if (vpnUser != null) {
      throw new InvalidParameterValueException(
          "VPN User with name " + username + " is already added for account " + owner);
    }

    long userCount = _vpnUsersDao.getVpnUserCount(owner.getId());
    if (userCount >= _userLimit) {
      throw new AccountLimitException(
          "Cannot add more than " + _userLimit + " remote access vpn users");
    }

    VpnUser user =
        _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, owner.getDomainId(), username, password));
    UsageEventUtils.publishUsageEvent(
        EventTypes.EVENT_VPN_USER_ADD,
        user.getAccountId(),
        0,
        user.getId(),
        user.getUsername(),
        user.getClass().getName(),
        user.getUuid());
    txn.commit();
    return user;
  }
  @Override
  public long getEntityOwnerId() {
    Account account = UserContext.current().getCaller();
    if ((account == null) || isAdmin(account.getType())) {
      if ((domainId != null) && (accountName != null)) {
        Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
        if (userAccount != null) {
          return userAccount.getId();
        } else {
          throw new InvalidParameterValueException(
              "Unable to find account by name " + accountName + " in domain " + domainId);
        }
      }
    }

    return account.getId();
  }
  @Override
  public void create() {
    Account owner = _accountService.getAccount(getEntityOwnerId());

    VpnUser vpnUser = _ravService.addVpnUser(owner.getId(), userName, password);
    if (vpnUser == null) {
      throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to add vpn user");
    }
    setEntityId(vpnUser.getId());
  }
  private Long accountAndUserValidation(
      Account account, Long userId, UserVmVO vmInstanceCheck, VMTemplateVO template, String msg)
      throws PermissionDeniedException {

    if (account != null) {
      if (!isAdmin(account.getType())) {
        if ((vmInstanceCheck != null) && (account.getId() != vmInstanceCheck.getAccountId())) {
          throw new PermissionDeniedException(msg + ". Permission denied.");
        }

        if ((template != null)
            && (!template.isPublicTemplate()
                && (account.getId() != template.getAccountId())
                && (template.getTemplateType() != TemplateType.PERHOST))) {
          throw new PermissionDeniedException(msg + ". Permission denied.");
        }

      } else {
        if ((vmInstanceCheck != null)
            && !_domainDao.isChildDomain(account.getDomainId(), vmInstanceCheck.getDomainId())) {
          throw new PermissionDeniedException(msg + ". Permission denied.");
        }
        // FIXME: if template/ISO owner is null we probably need to
        // throw some kind of exception

        if (template != null) {
          Account templateOwner = _accountDao.findById(template.getAccountId());
          if ((templateOwner != null)
              && !_domainDao.isChildDomain(account.getDomainId(), templateOwner.getDomainId())) {
            throw new PermissionDeniedException(msg + ". Permission denied.");
          }
        }
      }
    }
    // If command is executed via 8096 port, set userId to the id of System
    // account (1)
    if (userId == null) {
      userId = new Long(1);
    }

    return userId;
  }
 @Override
 public String toString() {
   return new StringBuffer("CCtxt[acct=")
       .append(account.getId())
       .append("; user="******"; id=")
       .append(contextId)
       .append("]")
       .toString();
 }
  @Override
  public long getEntityOwnerId() {
    Account account = CallContext.current().getCallingAccount();
    if (account != null) {
      return account.getId();
    }

    return Account
        .ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events
                            // are tracked
  }
  @Override
  public long getEntityOwnerId() {
    Account caller = UserContext.current().getCaller();

    if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) {
      throw new InvalidParameterValueException(
          "Account name and domain id must be specified together");
    }

    if (accountName != null) {
      return _accountService.finalizeOwner(caller, accountName, domainId, null).getId();
    }

    return caller.getId();
  }
  @Override
  public long getEntityOwnerId() {
    final Long volumeId = getVolumeId();
    final Long snapshotId = getSnapshotId();
    final Account callingAccount = CallContext.current().getCallingAccount();
    if (volumeId != null) {
      final Volume volume = _entityMgr.findById(Volume.class, volumeId);
      if (volume != null) {
        _accountService.checkAccess(
            callingAccount, SecurityChecker.AccessType.UseEntry, false, volume);
      } else {
        throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
      }
    } else {
      final Snapshot snapshot = _entityMgr.findById(Snapshot.class, snapshotId);
      if (snapshot != null) {
        _accountService.checkAccess(
            callingAccount, SecurityChecker.AccessType.UseEntry, false, snapshot);
      } else {
        throw new InvalidParameterValueException("Unable to find snapshot by id=" + snapshotId);
      }
    }

    if (projectId != null) {
      final Project project = _projectService.getProject(projectId);
      if (project != null) {
        if (project.getState() == Project.State.Active) {
          final Account projectAccount = _accountService.getAccount(project.getProjectAccountId());
          _accountService.checkAccess(
              callingAccount, SecurityChecker.AccessType.UseEntry, false, projectAccount);
          return project.getProjectAccountId();
        } else {
          final PermissionDeniedException ex =
              new PermissionDeniedException(
                  "Can't add resources to the project with specified projectId in state="
                      + project.getState()
                      + " as it's no longer active");
          ex.addProxyObject(project.getUuid(), "projectId");
          throw ex;
        }
      } else {
        throw new InvalidParameterValueException("Unable to find project by id");
      }
    }

    return callingAccount.getId();
  }
  public long getAccountId() {
    if (publicIpId != null) return _networkService.getIp(getSourceIpAddressId()).getAccountId();

    Account account = null;
    if ((domainId != null) && (accountName != null)) {
      account = _responseGenerator.findAccountByNameDomain(accountName, domainId);
      if (account != null) {
        return account.getId();
      } else {
        throw new InvalidParameterValueException(
            "Unable to find account " + accountName + " in domain id=" + domainId);
      }
    } else {
      throw new InvalidParameterValueException(
          "Can't define IP owner. Either specify account/domainId or publicIpId");
    }
  }
 @Override
 public SecurityGroupVO createDefaultSecurityGroup(Long accountId) {
   SecurityGroupVO groupVO =
       _securityGroupDao.findByAccountAndName(accountId, SecurityGroupManager.DEFAULT_GROUP_NAME);
   if (groupVO == null) {
     Account accVO = _accountDao.findById(accountId);
     if (accVO != null) {
       return createSecurityGroup(
           SecurityGroupManager.DEFAULT_GROUP_NAME,
           SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
           accVO.getDomainId(),
           accVO.getId(),
           accVO.getAccountName());
     }
   }
   return groupVO;
 }
  @Override
  @ActionEvent(
      eventType = EventTypes.EVENT_SECURITY_GROUP_CREATE,
      eventDescription = "creating security group")
  public SecurityGroupVO createSecurityGroup(CreateSecurityGroupCmd cmd)
      throws PermissionDeniedException, InvalidParameterValueException {
    String name = cmd.getSecurityGroupName();
    Account caller = UserContext.current().getCaller();
    Account owner = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId());

    if (_securityGroupDao.isNameInUse(
        owner.getId(), owner.getDomainId(), cmd.getSecurityGroupName())) {
      throw new InvalidParameterValueException(
          "Unable to create security group, a group with name " + name + " already exisits.");
    }

    return createSecurityGroup(
        cmd.getSecurityGroupName(),
        cmd.getDescription(),
        owner.getDomainId(),
        owner.getAccountId(),
        owner.getAccountName());
  }
Exemple #12
0
  @SuppressWarnings("unchecked")
  private void buildAsyncListResponse(BaseListCmd command, Account account) {
    List<ResponseObject> responses = ((ListResponse) command.getResponseObject()).getResponses();
    if (responses != null && responses.size() > 0) {
      List<? extends AsyncJob> jobs = null;

      // list all jobs for ROOT admin
      if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) {
        jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType().toString(), null);
      } else {
        jobs =
            _asyncMgr.findInstancePendingAsyncJobs(
                command.getInstanceType().toString(), account.getId());
      }

      if (jobs.size() == 0) {
        return;
      }

      Map<String, AsyncJob> objectJobMap = new HashMap<String, AsyncJob>();
      for (AsyncJob job : jobs) {
        if (job.getInstanceId() == null) {
          continue;
        }
        String instanceUuid = ApiDBUtils.findJobInstanceUuid(job);
        objectJobMap.put(instanceUuid, job);
      }

      for (ResponseObject response : responses) {
        if (response.getObjectId() != null && objectJobMap.containsKey(response.getObjectId())) {
          AsyncJob job = objectJobMap.get(response.getObjectId());
          response.setJobId(job.getUuid());
          response.setJobStatus(job.getStatus().ordinal());
        }
      }
    }
  }
Exemple #13
0
  private String queueCommand(BaseCmd cmdObj, Map<String, String> params) throws Exception {
    CallContext ctx = CallContext.current();
    Long callerUserId = ctx.getCallingUserId();
    Account caller = ctx.getCallingAccount();

    // Queue command based on Cmd super class:
    // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned.
    // BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as
    // BaseAsyncCmd.
    // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized
    // and returned.
    if (cmdObj instanceof BaseAsyncCmd) {
      Long objectId = null;
      String objectUuid = null;
      if (cmdObj instanceof BaseAsyncCreateCmd) {
        BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj;
        _dispatcher.dispatchCreateCmd(createCmd, params);
        objectId = createCmd.getEntityId();
        objectUuid = createCmd.getEntityUuid();
        params.put("id", objectId.toString());
      } else {
        ApiDispatcher.processParameters(cmdObj, params);
      }

      BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmdObj;

      if (callerUserId != null) {
        params.put("ctxUserId", callerUserId.toString());
      }
      if (caller != null) {
        params.put("ctxAccountId", String.valueOf(caller.getId()));
      }

      long startEventId = ctx.getStartEventId();
      asyncCmd.setStartEventId(startEventId);

      // save the scheduled event
      Long eventId =
          ActionEventUtils.onScheduledActionEvent(
              (callerUserId == null) ? User.UID_SYSTEM : callerUserId,
              asyncCmd.getEntityOwnerId(),
              asyncCmd.getEventType(),
              asyncCmd.getEventDescription(),
              startEventId);
      if (startEventId == 0) {
        // There was no create event before, set current event id as start eventId
        startEventId = eventId;
      }

      params.put("ctxStartEventId", String.valueOf(startEventId));
      params.put("cmdEventType", asyncCmd.getEventType().toString());

      Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId;
      AsyncJobVO job =
          new AsyncJobVO(
              ctx.getContextId(),
              callerUserId,
              caller.getId(),
              cmdObj.getClass().getName(),
              ApiGsonHelper.getBuilder().create().toJson(params),
              instanceId,
              asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null);
      job.setDispatcher(_asyncDispatcher.getName());

      long jobId = _asyncMgr.submitAsyncJob(job);

      if (jobId == 0L) {
        String errorMsg = "Unable to schedule async job for command " + job.getCmd();
        s_logger.warn(errorMsg);
        throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
      }

      if (objectId != null) {
        String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid;
        return getBaseAsyncCreateResponse(jobId, (BaseAsyncCreateCmd) asyncCmd, objUuid);
      } else {
        SerializationContext.current().setUuidTranslation(true);
        return getBaseAsyncResponse(jobId, asyncCmd);
      }
    } else {
      _dispatcher.dispatch(cmdObj, params, false);

      // if the command is of the listXXXCommand, we will need to also return the
      // the job id and status if possible
      // For those listXXXCommand which we have already created DB views, this step is not needed
      // since async job is joined in their db views.
      if (cmdObj instanceof BaseListCmd
          && !(cmdObj instanceof ListVMsCmd)
          && !(cmdObj instanceof ListRoutersCmd)
          && !(cmdObj instanceof ListSecurityGroupsCmd)
          && !(cmdObj instanceof ListTagsCmd)
          && !(cmdObj instanceof ListEventsCmd)
          && !(cmdObj instanceof ListVMGroupsCmd)
          && !(cmdObj instanceof ListProjectsCmd)
          && !(cmdObj instanceof ListProjectAccountsCmd)
          && !(cmdObj instanceof ListProjectInvitationsCmd)
          && !(cmdObj instanceof ListHostsCmd)
          && !(cmdObj instanceof ListVolumesCmd)
          && !(cmdObj instanceof ListUsersCmd)
          && !(cmdObj instanceof ListAccountsCmd)
          && !(cmdObj instanceof ListStoragePoolsCmd)
          && !(cmdObj instanceof ListDiskOfferingsCmd)
          && !(cmdObj instanceof ListServiceOfferingsCmd)
          && !(cmdObj instanceof ListZonesByCmd)) {
        buildAsyncListResponse((BaseListCmd) cmdObj, caller);
      }

      SerializationContext.current().setUuidTranslation(true);
      return ApiResponseSerializer.toSerializedString(
          (ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType());
    }
  }
 public long getCallingAccountId() {
   return account.getId();
 }
  public TemplateProfile prepare(
      boolean isIso,
      Long userId,
      String name,
      String displayText,
      Integer bits,
      Boolean passwordEnabled,
      Boolean requiresHVM,
      String url,
      Boolean isPublic,
      Boolean featured,
      Boolean isExtractable,
      String format,
      Long guestOSId,
      Long zoneId,
      HypervisorType hypervisorType,
      String chksum,
      Boolean bootable,
      String templateTag,
      Account templateOwner,
      Map details)
      throws ResourceAllocationException {
    // Long accountId = null;
    // parameters verification

    if (isPublic == null) {
      isPublic = Boolean.FALSE;
    }

    if (zoneId.longValue() == -1) {
      zoneId = null;
    }

    if (isIso) {
      if (bootable == null) {
        bootable = Boolean.TRUE;
      }
      GuestOS noneGuestOs = ApiDBUtils.findGuestOSByDisplayName(ApiConstants.ISO_GUEST_OS_NONE);
      if ((guestOSId == null || guestOSId == noneGuestOs.getId()) && bootable == true) {
        throw new InvalidParameterValueException("Please pass a valid GuestOS Id");
      }
      if (bootable == false) {
        guestOSId = noneGuestOs.getId(); // Guest os id of None.
      }
    } else {
      if (bits == null) {
        bits = Integer.valueOf(64);
      }
      if (passwordEnabled == null) {
        passwordEnabled = false;
      }
      if (requiresHVM == null) {
        requiresHVM = true;
      }
    }

    if (isExtractable == null) {
      isExtractable = Boolean.FALSE;
    }

    boolean isAdmin =
        _accountDao.findById(templateOwner.getId()).getType() == Account.ACCOUNT_TYPE_ADMIN;

    if (!isAdmin && zoneId == null) {
      throw new InvalidParameterValueException("Please specify a valid zone Id.");
    }

    if (url.toLowerCase().contains("file://")) {
      throw new InvalidParameterValueException("File:// type urls are currently unsupported");
    }

    boolean allowPublicUserTemplates =
        Boolean.parseBoolean(_configDao.getValue("allow.public.user.templates"));
    if (!isAdmin && !allowPublicUserTemplates && isPublic) {
      throw new InvalidParameterValueException("Only private templates/ISO can be created.");
    }

    if (!isAdmin || featured == null) {
      featured = Boolean.FALSE;
    }

    // If command is executed via 8096 port, set userId to the id of System
    // account (1)
    if (userId == null) {
      userId = Long.valueOf(1);
    }

    ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
    if (imgfmt == null) {
      throw new IllegalArgumentException(
          "Image format is incorrect "
              + format
              + ". Supported formats are "
              + EnumUtils.listValues(ImageFormat.values()));
    }

    // Check that the resource limit for templates/ISOs won't be exceeded
    UserVO user = _userDao.findById(userId);
    if (user == null) {
      throw new IllegalArgumentException("Unable to find user with id " + userId);
    }

    _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);

    if (templateOwner.getType() != Account.ACCOUNT_TYPE_ADMIN && zoneId == null) {
      throw new IllegalArgumentException("Only admins can create templates in all zones");
    }

    // If a zoneId is specified, make sure it is valid
    if (zoneId != null) {
      DataCenterVO zone = _dcDao.findById(zoneId);
      if (zone == null) {
        throw new IllegalArgumentException("Please specify a valid zone.");
      }
      Account caller = UserContext.current().getCaller();
      if (Grouping.AllocationState.Disabled == zone.getAllocationState()
          && !_accountMgr.isRootAdmin(caller.getType())) {
        throw new PermissionDeniedException(
            "Cannot perform this operation, Zone is currently disabled: " + zoneId);
      }
    }

    List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates();
    for (VMTemplateVO template : systemvmTmplts) {
      if (template.getName().equalsIgnoreCase(name)
          || template.getDisplayText().equalsIgnoreCase(displayText)) {
        throw new IllegalArgumentException("Cannot use reserved names for templates");
      }
    }

    Long id = _tmpltDao.getNextInSequence(Long.class, "id");
    UserContext.current().setEventDetails("Id: " + id + " name: " + name);
    return new TemplateProfile(
        id,
        userId,
        name,
        displayText,
        bits,
        passwordEnabled,
        requiresHVM,
        url,
        isPublic,
        featured,
        isExtractable,
        imgfmt,
        guestOSId,
        zoneId,
        hypervisorType,
        templateOwner.getAccountName(),
        templateOwner.getDomainId(),
        templateOwner.getAccountId(),
        chksum,
        bootable,
        templateTag,
        details);
  }
  public DomainRouterVO deployELBVm(
      Network guestNetwork, DeployDestination dest, Account owner, Map<Param, Object> params)
      throws ConcurrentOperationException, ResourceUnavailableException,
          InsufficientCapacityException {
    long dcId = dest.getDataCenter().getId();

    // lock guest network
    Long guestNetworkId = guestNetwork.getId();
    guestNetwork = _networkDao.acquireInLockTable(guestNetworkId);

    if (guestNetwork == null) {
      throw new ConcurrentOperationException("Unable to acquire network lock: " + guestNetworkId);
    }

    try {

      if (_networkModel.isNetworkSystem(guestNetwork)
          || guestNetwork.getGuestType() == Network.GuestType.Shared) {
        owner = _accountService.getSystemAccount();
      }

      if (s_logger.isDebugEnabled()) {
        s_logger.debug(
            "Starting a ELB vm for network configurations: " + guestNetwork + " in " + dest);
      }
      assert guestNetwork.getState() == Network.State.Implemented
              || guestNetwork.getState() == Network.State.Setup
              || guestNetwork.getState() == Network.State.Implementing
          : "Network is not yet fully implemented: " + guestNetwork;

      DataCenterDeployment plan = null;
      DomainRouterVO elbVm = null;

      plan = new DataCenterDeployment(dcId, dest.getPod().getId(), null, null, null, null);

      if (elbVm == null) {
        long id = _routerDao.getNextInSequence(Long.class, "id");
        if (s_logger.isDebugEnabled()) {
          s_logger.debug("Creating the ELB vm " + id);
        }

        List<? extends NetworkOffering> offerings =
            _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
        NetworkOffering controlOffering = offerings.get(0);
        NetworkVO controlConfig =
            _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0);

        List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>(2);
        NicProfile guestNic = new NicProfile();
        guestNic.setDefaultNic(true);
        networks.add(new Pair<NetworkVO, NicProfile>(controlConfig, null));
        networks.add(new Pair<NetworkVO, NicProfile>((NetworkVO) guestNetwork, guestNic));

        VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId);

        String typeString = "ElasticLoadBalancerVm";
        Long physicalNetworkId = _networkModel.getPhysicalNetworkId(guestNetwork);
        PhysicalNetworkServiceProvider provider =
            _physicalProviderDao.findByServiceProvider(physicalNetworkId, typeString);
        if (provider == null) {
          throw new CloudRuntimeException(
              "Cannot find service provider "
                  + typeString
                  + " in physical network "
                  + physicalNetworkId);
        }
        VirtualRouterProvider vrProvider =
            _vrProviderDao.findByNspIdAndType(
                provider.getId(), VirtualRouterProviderType.ElasticLoadBalancerVm);
        if (vrProvider == null) {
          throw new CloudRuntimeException(
              "Cannot find virtual router provider "
                  + typeString
                  + " as service provider "
                  + provider.getId());
        }

        elbVm =
            new DomainRouterVO(
                id,
                _elasticLbVmOffering.getId(),
                vrProvider.getId(),
                VirtualMachineName.getSystemVmName(id, _instance, _elbVmNamePrefix),
                template.getId(),
                template.getHypervisorType(),
                template.getGuestOSId(),
                owner.getDomainId(),
                owner.getId(),
                false,
                0,
                false,
                RedundantState.UNKNOWN,
                _elasticLbVmOffering.getOfferHA(),
                false,
                VirtualMachine.Type.ElasticLoadBalancerVm,
                null);
        elbVm.setRole(Role.LB);
        elbVm = _itMgr.allocate(elbVm, template, _elasticLbVmOffering, networks, plan, null, owner);
        // TODO: create usage stats
      }

      State state = elbVm.getState();
      if (state != State.Running) {
        elbVm =
            this.start(
                elbVm, _accountService.getSystemUser(), _accountService.getSystemAccount(), params);
      }

      return elbVm;
    } finally {
      _networkDao.releaseFromLockTable(guestNetworkId);
    }
  }
  @Override
  public List<SecurityGroupRulesVO> searchForSecurityGroupRules(ListSecurityGroupsCmd cmd)
      throws PermissionDeniedException, InvalidParameterValueException {
    Account caller = UserContext.current().getCaller();
    Long domainId = cmd.getDomainId();
    String accountName = cmd.getAccountName();
    Long instanceId = cmd.getVirtualMachineId();
    String securityGroup = cmd.getSecurityGroupName();
    Long id = cmd.getId();
    Long accountId = null;

    if (instanceId != null) {
      UserVmVO userVM = _userVMDao.findById(instanceId);
      if (userVM == null) {
        throw new InvalidParameterValueException(
            "Unable to list network groups for virtual machine instance "
                + instanceId
                + "; instance not found.");
      }
      _accountMgr.checkAccess(caller, null, userVM);
      return listSecurityGroupRulesByVM(instanceId.longValue());
    }

    if (_accountMgr.isAdmin(caller.getType())) {
      if (domainId != null) {
        Domain domain = _domainMgr.getDomain(domainId);
        if (domain == null) {
          throw new InvalidParameterValueException("Unable to find domain by id " + domainId);
        }
        _accountMgr.checkAccess(caller, domain);
        if (accountName != null) {
          Account account = _accountMgr.getActiveAccountByName(accountName, domainId);
          if (account == null) {
            throw new InvalidParameterValueException(
                "Unable to find account " + accountName + " in domain " + domainId);
          }
          _accountMgr.checkAccess(caller, null, account);
          accountId = account.getId();
        }
      }
    } else {
      // regular user can see only his own security groups
      accountId = caller.getId();
    }

    List<SecurityGroupRulesVO> securityRulesList = new ArrayList<SecurityGroupRulesVO>();
    Filter searchFilter =
        new Filter(SecurityGroupVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
    Object keyword = cmd.getKeyword();

    SearchBuilder<SecurityGroupVO> sb = _securityGroupDao.createSearchBuilder();
    sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
    sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
    sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
    sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);

    // only do a recursive domain search if the search is not limited by account or instance
    if ((accountId == null)
        && (instanceId == null)
        && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) {
      SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
      domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
      sb.join(
          "domainSearch",
          domainSearch,
          sb.entity().getDomainId(),
          domainSearch.entity().getId(),
          JoinBuilder.JoinType.INNER);
    }

    SearchCriteria<SecurityGroupVO> sc = sb.create();

    if (id != null) {
      sc.setParameters("id", id);
    }

    if (securityGroup != null) {
      sc.setParameters("name", securityGroup);
    }

    if (accountId != null) {
      sc.setParameters("accountId", accountId);
    }

    // only do a recursive domain search if the search is not limited by account or instance
    if ((accountId == null)
        && (instanceId == null)
        && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) {
      DomainVO domain = _domainDao.findById(caller.getDomainId());
      sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
    }

    if (keyword != null) {
      SearchCriteria<SecurityGroupRulesVO> ssc = _securityGroupRulesDao.createSearchCriteria();
      ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
      ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
      sc.addAnd("name", SearchCriteria.Op.SC, ssc);
    }

    List<SecurityGroupVO> securityGroups = _securityGroupDao.search(sc, searchFilter);
    for (SecurityGroupVO group : securityGroups) {
      securityRulesList.addAll(_securityGroupRulesDao.listSecurityRulesByGroupId(group.getId()));
    }

    return securityRulesList;
  }
  @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());
      }
    }
  }
  @Override
  public DomainRouterVO deployRouter(
      final RouterDeploymentDefinition routerDeploymentDefinition, final boolean startRouter)
      throws InsufficientAddressCapacityException, InsufficientServerCapacityException,
          InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException {

    final ServiceOfferingVO routerOffering =
        _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
    final Account owner = routerDeploymentDefinition.getOwner();

    // Router is the network element, we don't know the hypervisor type yet.
    // Try to allocate the domR twice using diff hypervisors, and when
    // failed both times, throw the exception up
    final List<HypervisorType> hypervisors = getHypervisors(routerDeploymentDefinition);

    int allocateRetry = 0;
    int startRetry = 0;
    DomainRouterVO router = null;
    for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext(); ) {
      final HypervisorType hType = iter.next();
      try {
        final long id = _routerDao.getNextInSequence(Long.class, "id");
        if (s_logger.isDebugEnabled()) {
          s_logger.debug(
              String.format(
                  "Allocating the VR with id=%s in datacenter %s with the hypervisor type %s",
                  id, routerDeploymentDefinition.getDest().getDataCenter(), hType));
        }

        final String templateName =
            retrieveTemplateName(
                hType, routerDeploymentDefinition.getDest().getDataCenter().getId());
        final VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName);

        if (template == null) {
          s_logger.debug(hType + " won't support system vm, skip it");
          continue;
        }

        final boolean offerHA = routerOffering.getOfferHA();

        // routerDeploymentDefinition.getVpc().getId() ==> do not use
        // VPC because it is not a VPC offering.
        final Long vpcId =
            routerDeploymentDefinition.getVpc() != null
                ? routerDeploymentDefinition.getVpc().getId()
                : null;

        long userId = CallContext.current().getCallingUserId();
        if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
          final List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
          if (!userVOs.isEmpty()) {
            userId = userVOs.get(0).getId();
          }
        }

        router =
            new DomainRouterVO(
                id,
                routerOffering.getId(),
                routerDeploymentDefinition.getVirtualProvider().getId(),
                VirtualMachineName.getRouterName(id, s_vmInstanceName),
                template.getId(),
                template.getHypervisorType(),
                template.getGuestOSId(),
                owner.getDomainId(),
                owner.getId(),
                userId,
                routerDeploymentDefinition.isRedundant(),
                RedundantState.UNKNOWN,
                offerHA,
                false,
                vpcId);

        router.setDynamicallyScalable(template.isDynamicallyScalable());
        router.setRole(Role.VIRTUAL_ROUTER);
        router = _routerDao.persist(router);

        reallocateRouterNetworks(routerDeploymentDefinition, router, template, null);
        router = _routerDao.findById(router.getId());
      } catch (final InsufficientCapacityException ex) {
        if (allocateRetry < 2 && iter.hasNext()) {
          s_logger.debug(
              "Failed to allocate the VR with hypervisor type "
                  + hType
                  + ", retrying one more time");
          continue;
        } else {
          throw ex;
        }
      } finally {
        allocateRetry++;
      }

      if (startRouter) {
        try {
          router =
              startVirtualRouter(
                  router,
                  _accountMgr.getSystemUser(),
                  _accountMgr.getSystemAccount(),
                  routerDeploymentDefinition.getParams());
          break;
        } catch (final InsufficientCapacityException ex) {
          if (startRetry < 2 && iter.hasNext()) {
            s_logger.debug(
                "Failed to start the VR  "
                    + router
                    + " with hypervisor type "
                    + hType
                    + ", "
                    + "destroying it and recreating one more time");
            // destroy the router
            destroyRouter(
                router.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
            continue;
          } else {
            throw ex;
          }
        } finally {
          startRetry++;
        }
      } else {
        // return stopped router
        return router;
      }
    }

    return router;
  }
  @Override
  @DB
  public boolean delete(TemplateProfile profile) {
    boolean success = true;

    VMTemplateVO template = profile.getTemplate();
    Long zoneId = profile.getZoneId();
    Long templateId = template.getId();

    String zoneName;
    List<HostVO> secondaryStorageHosts;
    if (!template.isCrossZones() && zoneId != null) {
      DataCenterVO zone = _dcDao.findById(zoneId);
      zoneName = zone.getName();
      secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(zoneId);
    } else {
      zoneName = "(all zones)";
      secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInAllZones();
    }

    s_logger.debug(
        "Attempting to mark template host refs for template: "
            + template.getName()
            + " as destroyed in zone: "
            + zoneName);

    // Make sure the template is downloaded to all the necessary secondary storage hosts
    for (HostVO secondaryStorageHost : secondaryStorageHosts) {
      long hostId = secondaryStorageHost.getId();
      List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
      for (VMTemplateHostVO templateHostVO : templateHostVOs) {
        if (templateHostVO.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) {
          String errorMsg = "Please specify a template that is not currently being downloaded.";
          s_logger.debug(
              "Template: "
                  + template.getName()
                  + " is currently being downloaded to secondary storage host: "
                  + secondaryStorageHost.getName()
                  + "; cant' delete it.");
          throw new CloudRuntimeException(errorMsg);
        }
      }
    }

    Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
    String eventType = "";

    if (template.getFormat().equals(ImageFormat.ISO)) {
      eventType = EventTypes.EVENT_ISO_DELETE;
    } else {
      eventType = EventTypes.EVENT_TEMPLATE_DELETE;
    }

    // Iterate through all necessary secondary storage hosts and mark the template on each host as
    // destroyed
    for (HostVO secondaryStorageHost : secondaryStorageHosts) {
      long hostId = secondaryStorageHost.getId();
      long sZoneId = secondaryStorageHost.getDataCenterId();
      List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
      for (VMTemplateHostVO templateHostVO : templateHostVOs) {
        VMTemplateHostVO lock = _tmpltHostDao.acquireInLockTable(templateHostVO.getId());
        try {
          if (lock == null) {
            s_logger.debug(
                "Failed to acquire lock when deleting templateHostVO with ID: "
                    + templateHostVO.getId());
            success = false;
            break;
          }
          UsageEventVO usageEvent =
              new UsageEventVO(eventType, account.getId(), sZoneId, templateId, null);
          _usageEventDao.persist(usageEvent);
          templateHostVO.setDestroyed(true);
          _tmpltHostDao.update(templateHostVO.getId(), templateHostVO);
          String installPath = templateHostVO.getInstallPath();
          if (installPath != null) {
            Answer answer =
                _agentMgr.sendToSecStorage(
                    secondaryStorageHost,
                    new DeleteTemplateCommand(secondaryStorageHost.getStorageUrl(), installPath));

            if (answer == null || !answer.getResult()) {
              s_logger.debug(
                  "Failed to delete "
                      + templateHostVO
                      + " due to "
                      + ((answer == null) ? "answer is null" : answer.getDetails()));
            } else {
              _tmpltHostDao.remove(templateHostVO.getId());
              s_logger.debug("Deleted template at: " + installPath);
            }
          } else {
            _tmpltHostDao.remove(templateHostVO.getId());
          }
          VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(sZoneId, templateId);

          if (templateZone != null) {
            _tmpltZoneDao.remove(templateZone.getId());
          }
        } finally {
          if (lock != null) {
            _tmpltHostDao.releaseFromLockTable(lock.getId());
          }
        }
      }

      if (!success) {
        break;
      }
    }

    s_logger.debug(
        "Successfully marked template host refs for template: "
            + template.getName()
            + " as destroyed in zone: "
            + zoneName);

    // If there are no more non-destroyed template host entries for this template, delete it
    if (success && (_tmpltHostDao.listByTemplateId(templateId).size() == 0)) {
      long accountId = template.getAccountId();

      VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId);

      try {
        if (lock == null) {
          s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
          success = false;
        } else if (_tmpltDao.remove(templateId)) {
          // Decrement the number of templates
          _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
        }

      } finally {
        if (lock != null) {
          _tmpltDao.releaseFromLockTable(lock.getId());
        }
      }

      s_logger.debug(
          "Removed template: "
              + template.getName()
              + " because all of its template host refs were marked as destroyed.");
    }

    return success;
  }
  @Override
  @DB
  public boolean delete(TemplateProfile profile) {
    VMTemplateVO template = profile.getTemplate();
    Long templateId = template.getId();
    boolean success = true;
    String zoneName;

    if (!template.isCrossZones() && profile.getZoneId() != null) {
      zoneName = profile.getZoneId().toString();
    } else {
      zoneName = "all zones";
    }

    s_logger.debug(
        "Attempting to mark template host refs for template: "
            + template.getName()
            + " as destroyed in zone: "
            + zoneName);
    Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
    String eventType = EventTypes.EVENT_TEMPLATE_DELETE;
    List<TemplateDataStoreVO> templateHostVOs = this._tmpltStoreDao.listByTemplate(templateId);

    for (TemplateDataStoreVO vo : templateHostVOs) {
      TemplateDataStoreVO lock = null;
      try {
        lock = _tmpltStoreDao.acquireInLockTable(vo.getId());
        if (lock == null) {
          s_logger.debug(
              "Failed to acquire lock when deleting templateDataStoreVO with ID: " + vo.getId());
          success = false;
          break;
        }

        vo.setDestroyed(true);
        _tmpltStoreDao.update(vo.getId(), vo);

      } finally {
        if (lock != null) {
          _tmpltStoreDao.releaseFromLockTable(lock.getId());
        }
      }
    }

    if (profile.getZoneId() != null) {
      UsageEventVO usageEvent =
          new UsageEventVO(eventType, account.getId(), profile.getZoneId(), templateId, null);
      _usageEventDao.persist(usageEvent);
    } else {
      List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved();
      for (DataCenterVO dc : dcs) {
        UsageEventVO usageEvent =
            new UsageEventVO(eventType, account.getId(), dc.getId(), templateId, null);
        _usageEventDao.persist(usageEvent);
      }
    }

    VMTemplateZoneVO templateZone =
        _tmpltZoneDao.findByZoneTemplate(profile.getZoneId(), templateId);

    if (templateZone != null) {
      _tmpltZoneDao.remove(templateZone.getId());
    }

    s_logger.debug(
        "Successfully marked template host refs for template: "
            + template.getName()
            + " as destroyed in zone: "
            + zoneName);

    // If there are no more non-destroyed template host entries for this template, delete it
    if (success && (_tmpltStoreDao.listByTemplate(templateId).size() == 0)) {
      long accountId = template.getAccountId();

      VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId);

      try {
        if (lock == null) {
          s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
          success = false;
        } else if (_tmpltDao.remove(templateId)) {
          // Decrement the number of templates and total secondary storage space used by the
          // account.
          _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
          _resourceLimitMgr.recalculateResourceCount(
              accountId, template.getDomainId(), ResourceType.secondary_storage.getOrdinal());
        }

      } finally {
        if (lock != null) {
          _tmpltDao.releaseFromLockTable(lock.getId());
        }
      }
      s_logger.debug(
          "Removed template: "
              + template.getName()
              + " because all of its template host refs were marked as destroyed.");
    }

    return success;
  }
  protected Map<String, Object> createSecStorageVmInstance(
      long dataCenterId, SecondaryStorageVm.Role role) {
    HostVO secHost = _hostDao.findSecondaryStorageHost(dataCenterId);
    if (secHost == null) {
      String msg =
          "No secondary storage available in zone "
              + dataCenterId
              + ", cannot create secondary storage vm";
      s_logger.warn(msg);
      throw new CloudRuntimeException(msg);
    }

    long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
    String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
    Account systemAcct = _accountMgr.getSystemAccount();

    DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
    DataCenter dc = _dcDao.findById(plan.getDataCenterId());

    List<NetworkOfferingVO> defaultOffering =
        _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork);

    if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) {
      defaultOffering =
          _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemGuestNetwork);
    }

    List<NetworkOfferingVO> offerings =
        _networkMgr.getSystemAccountNetworkOfferings(
            NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork);
    List<Pair<NetworkVO, NicProfile>> networks =
        new ArrayList<Pair<NetworkVO, NicProfile>>(offerings.size() + 1);
    NicProfile defaultNic = new NicProfile();
    defaultNic.setDefaultNic(true);
    defaultNic.setDeviceId(2);
    try {
      networks.add(
          new Pair<NetworkVO, NicProfile>(
              _networkMgr
                  .setupNetwork(systemAcct, defaultOffering.get(0), plan, null, null, false, false)
                  .get(0),
              defaultNic));
      for (NetworkOfferingVO offering : offerings) {
        networks.add(
            new Pair<NetworkVO, NicProfile>(
                _networkMgr
                    .setupNetwork(systemAcct, offering, plan, null, null, false, false)
                    .get(0),
                null));
      }
    } catch (ConcurrentOperationException e) {
      s_logger.info("Unable to setup due to concurrent operation. " + e);
      return new HashMap<String, Object>();
    }

    VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId);
    if (template == null) {
      s_logger.debug("Can't find a template to start");
      throw new CloudRuntimeException("Insufficient capacity exception");
    }

    SecondaryStorageVmVO secStorageVm =
        new SecondaryStorageVmVO(
            id,
            _serviceOffering.getId(),
            name,
            template.getId(),
            template.getHypervisorType(),
            template.getGuestOSId(),
            dataCenterId,
            systemAcct.getDomainId(),
            systemAcct.getId(),
            role,
            _serviceOffering.getOfferHA());
    try {
      secStorageVm =
          _itMgr.allocate(
              secStorageVm, template, _serviceOffering, networks, plan, null, systemAcct);
    } catch (InsufficientCapacityException e) {
      s_logger.warn("InsufficientCapacity", e);
      throw new CloudRuntimeException("Insufficient capacity exception", e);
    }

    Map<String, Object> context = new HashMap<String, Object>();
    context.put("secStorageVmId", secStorageVm.getId());
    return context;
  }
  @Override
  public List<LoadBalancerVO> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) {
    Account caller = UserContext.current().getCaller();
    Long ipId = cmd.getPublicIpId();
    Long zoneId = cmd.getZoneId();
    String path = null;

    Pair<String, Long> accountDomainPair =
        _accountMgr.finalizeAccountDomainForList(caller, cmd.getAccountName(), cmd.getDomainId());
    String accountName = accountDomainPair.first();
    Long domainId = accountDomainPair.second();

    if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN
        || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
      Domain domain = _domainMgr.getDomain(caller.getDomainId());
      path = domain.getPath();
    }

    Filter searchFilter =
        new Filter(LoadBalancerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());

    Object id = cmd.getId();
    Object name = cmd.getLoadBalancerRuleName();
    Object keyword = cmd.getKeyword();
    Object instanceId = cmd.getVirtualMachineId();

    SearchBuilder<LoadBalancerVO> sb = _lbDao.createSearchBuilder();
    sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
    sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
    sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ);
    sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
    sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);

    if (instanceId != null) {
      SearchBuilder<LoadBalancerVMMapVO> lbVMSearch = _lb2VmMapDao.createSearchBuilder();
      lbVMSearch.and("instanceId", lbVMSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
      sb.join(
          "lbVMSearch",
          lbVMSearch,
          sb.entity().getId(),
          lbVMSearch.entity().getLoadBalancerId(),
          JoinBuilder.JoinType.INNER);
    }

    if (path != null) {
      // for domain admin we should show only subdomains information
      SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
      domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
      sb.join(
          "domainSearch",
          domainSearch,
          sb.entity().getDomainId(),
          domainSearch.entity().getId(),
          JoinBuilder.JoinType.INNER);
    }

    if (zoneId != null) {
      SearchBuilder<IPAddressVO> ipSearch = _ipAddressDao.createSearchBuilder();
      ipSearch.and("zoneId", ipSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
      sb.join(
          "ipSearch",
          ipSearch,
          sb.entity().getSourceIpAddressId(),
          ipSearch.entity().getId(),
          JoinBuilder.JoinType.INNER);
    }

    SearchCriteria<LoadBalancerVO> sc = sb.create();
    if (keyword != null) {
      SearchCriteria<LoadBalancerVO> ssc = _lbDao.createSearchCriteria();
      ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
      ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");

      sc.addAnd("name", SearchCriteria.Op.SC, ssc);
    }

    if (name != null) {
      sc.setParameters("name", "%" + name + "%");
    }

    if (id != null) {
      sc.setParameters("id", id);
    }

    if (ipId != null) {
      sc.setParameters("sourceIpAddress", ipId);
    }

    if (instanceId != null) {
      sc.setJoinParameters("lbVMSearch", "instanceId", instanceId);
    }

    if (domainId != null) {
      sc.setParameters("domainId", domainId);
      if (accountName != null) {
        Account account = _accountMgr.getActiveAccountByName(accountName, domainId);
        sc.setParameters("accountId", account.getId());
      }
    }

    if (path != null) {
      sc.setJoinParameters("domainSearch", "path", path + "%");
    }

    if (zoneId != null) {
      sc.setJoinParameters("ipSearch", "zoneId", zoneId);
    }

    return _lbDao.search(sc, searchFilter);
  }
  @SuppressWarnings("unchecked")
  private void processRequest(HttpServletRequest req, HttpServletResponse resp) {
    StringBuffer auditTrailSb = new StringBuffer();
    auditTrailSb.append(" " + req.getRemoteAddr());
    auditTrailSb.append(" -- " + req.getMethod() + " ");
    // get the response format since we'll need it in a couple of places
    String responseType = BaseCmd.RESPONSE_TYPE_XML;
    Map<String, Object[]> params = new HashMap<String, Object[]>();
    params.putAll(req.getParameterMap());

    //
    // For HTTP GET requests, it seems that HttpServletRequest.getParameterMap() actually tries
    // to unwrap URL encoded content from ISO-9959-1.
    //
    // After failed in using setCharacterEncoding() to control it, end up with following hacking :
    // for all GET requests,
    // we will override it with our-own way of UTF-8 based URL decoding.
    //
    utf8Fixup(req, params);

    try {
      HttpSession session = req.getSession(false);
      Object[] responseTypeParam = params.get("response");
      if (responseTypeParam != null) {
        responseType = (String) responseTypeParam[0];
      }

      Object[] commandObj = params.get("command");
      if (commandObj != null) {
        String command = (String) commandObj[0];
        if ("logout".equalsIgnoreCase(command)) {
          // if this is just a logout, invalidate the session and return
          if (session != null) {
            Long userId = (Long) session.getAttribute("userid");
            Account account = (Account) session.getAttribute("accountobj");
            Long accountId = null;
            if (account != null) {
              accountId = account.getId();
            }
            auditTrailSb.insert(
                0,
                "(userId="
                    + userId
                    + " accountId="
                    + accountId
                    + " sessionId="
                    + session.getId()
                    + ")");
            if (userId != null) {
              _apiServer.logoutUser(userId);
            }
            try {
              session.invalidate();
            } catch (IllegalStateException ise) {
            }
          }
          auditTrailSb.append("command=logout");
          auditTrailSb.append(" " + HttpServletResponse.SC_OK);
          writeResponse(
              resp,
              getLogoutSuccessResponse(responseType),
              HttpServletResponse.SC_OK,
              responseType);
          return;
        } else if ("login".equalsIgnoreCase(command)) {
          auditTrailSb.append("command=login");
          // if this is a login, authenticate the user and return
          if (session != null) {
            try {
              session.invalidate();
            } catch (IllegalStateException ise) {
            }
          }
          session = req.getSession(true);
          String[] username = (String[]) params.get("username");
          String[] password = (String[]) params.get("password");
          String[] domainIdArr = (String[]) params.get("domainid");

          if (domainIdArr == null) {
            domainIdArr = (String[]) params.get("domainId");
          }
          String[] domainName = (String[]) params.get("domain");
          Long domainId = null;
          if ((domainIdArr != null) && (domainIdArr.length > 0)) {
            try {
              domainId = new Long(Long.parseLong(domainIdArr[0]));
              auditTrailSb.append(" domainid=" + domainId); // building the params for POST call
            } catch (NumberFormatException e) {
              s_logger.warn("Invalid domain id entered by user");
              auditTrailSb.append(
                  " "
                      + HttpServletResponse.SC_UNAUTHORIZED
                      + " "
                      + "Invalid domain id entered, please enter a valid one");
              String serializedResponse =
                  _apiServer.getSerializedApiError(
                      HttpServletResponse.SC_UNAUTHORIZED,
                      "Invalid domain id entered, please enter a valid one",
                      params,
                      responseType,
                      null);
              writeResponse(
                  resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType);
            }
          }
          String domain = null;
          if (domainName != null) {
            domain = domainName[0];
            auditTrailSb.append(" domain=" + domain);
            if (domain != null) {
              // ensure domain starts with '/' and ends with '/'
              if (!domain.endsWith("/")) {
                domain += '/';
              }
              if (!domain.startsWith("/")) {
                domain = "/" + domain;
              }
            }
          }

          if (username != null) {
            String pwd = ((password == null) ? null : password[0]);
            try {
              _apiServer.loginUser(session, username[0], pwd, domainId, domain, params);
              auditTrailSb.insert(
                  0,
                  "(userId="
                      + session.getAttribute("userid")
                      + " accountId="
                      + ((Account) session.getAttribute("accountobj")).getId()
                      + " sessionId="
                      + session.getId()
                      + ")");
              String loginResponse = getLoginSuccessResponse(session, responseType);
              writeResponse(resp, loginResponse, HttpServletResponse.SC_OK, responseType);
              return;
            } catch (CloudAuthenticationException ex) {
              // TODO: fall through to API key, or just fail here w/ auth error? (HTTP 401)
              try {
                session.invalidate();
              } catch (IllegalStateException ise) {
              }

              auditTrailSb.append(
                  " " + BaseCmd.ACCOUNT_ERROR + " " + ex.getMessage() != null
                      ? ex.getMessage()
                      : "failed to authenticate user, check if username/password are correct");
              String serializedResponse =
                  _apiServer.getSerializedApiError(
                      BaseCmd.ACCOUNT_ERROR,
                      ex.getMessage() != null
                          ? ex.getMessage()
                          : "failed to authenticate user, check if username/password are correct",
                      params,
                      responseType,
                      null);
              writeResponse(resp, serializedResponse, BaseCmd.ACCOUNT_ERROR, responseType);
              return;
            }
          }
        }
      }
      auditTrailSb.append(req.getQueryString());
      boolean isNew = ((session == null) ? true : session.isNew());

      // Initialize an empty context and we will update it after we have verified the request below,
      // we no longer rely on web-session here, verifyRequest will populate user/account information
      // if a API key exists
      UserContext.registerContext(
          _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount(), null, false);
      Long userId = null;

      if (!isNew) {
        userId = (Long) session.getAttribute("userid");
        String account = (String) session.getAttribute("account");
        Object accountObj = session.getAttribute("accountobj");
        String sessionKey = (String) session.getAttribute("sessionkey");
        String[] sessionKeyParam = (String[]) params.get("sessionkey");
        if ((sessionKeyParam == null)
            || (sessionKey == null)
            || !sessionKey.equals(sessionKeyParam[0])) {
          try {
            session.invalidate();
          } catch (IllegalStateException ise) {
          }
          auditTrailSb.append(
              " "
                  + HttpServletResponse.SC_UNAUTHORIZED
                  + " "
                  + "unable to verify user credentials");
          String serializedResponse =
              _apiServer.getSerializedApiError(
                  HttpServletResponse.SC_UNAUTHORIZED,
                  "unable to verify user credentials",
                  params,
                  responseType,
                  null);
          writeResponse(
              resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType);
          return;
        }

        // Do a sanity check here to make sure the user hasn't already been deleted
        if ((userId != null)
            && (account != null)
            && (accountObj != null)
            && _apiServer.verifyUser(userId)) {
          String[] command = (String[]) params.get("command");
          if (command == null) {
            s_logger.info("missing command, ignoring request...");
            auditTrailSb.append(
                " " + HttpServletResponse.SC_BAD_REQUEST + " " + "no command specified");
            String serializedResponse =
                _apiServer.getSerializedApiError(
                    HttpServletResponse.SC_BAD_REQUEST,
                    "no command specified",
                    params,
                    responseType,
                    null);
            writeResponse(
                resp, serializedResponse, HttpServletResponse.SC_BAD_REQUEST, responseType);
            return;
          }
          UserContext.updateContext(userId, (Account) accountObj, session.getId());
        } else {
          // Invalidate the session to ensure we won't allow a request across management server
          // restarts if the userId
          // was serialized to the
          // stored session
          try {
            session.invalidate();
          } catch (IllegalStateException ise) {
          }

          auditTrailSb.append(
              " "
                  + HttpServletResponse.SC_UNAUTHORIZED
                  + " "
                  + "unable to verify user credentials");
          String serializedResponse =
              _apiServer.getSerializedApiError(
                  HttpServletResponse.SC_UNAUTHORIZED,
                  "unable to verify user credentials",
                  params,
                  responseType,
                  null);
          writeResponse(
              resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType);
          return;
        }
      }

      if (_apiServer.verifyRequest(params, userId)) {
        /*
         * if (accountObj != null) { Account userAccount = (Account)accountObj; if (userAccount.getType() ==
         * Account.ACCOUNT_TYPE_NORMAL) { params.put(BaseCmd.Properties.USER_ID.getName(), new String[] { userId });
         * params.put(BaseCmd.Properties.ACCOUNT.getName(), new String[] { account });
         * params.put(BaseCmd.Properties.DOMAIN_ID.getName(), new String[] { domainId });
         * params.put(BaseCmd.Properties.ACCOUNT_OBJ.getName(), new Object[] { accountObj }); } else {
         * params.put(BaseCmd.Properties.USER_ID.getName(), new String[] { userId });
         * params.put(BaseCmd.Properties.ACCOUNT_OBJ.getName(), new Object[] { accountObj }); } }
         *
         * // update user context info here so that we can take information if the request is authenticated // via api
         * key mechanism updateUserContext(params, session != null ? session.getId() : null);
         */

        auditTrailSb.insert(
            0,
            "(userId="
                + UserContext.current().getCallerUserId()
                + " accountId="
                + UserContext.current().getCaller().getId()
                + " sessionId="
                + (session != null ? session.getId() : null)
                + ")");

        try {
          String response = _apiServer.handleRequest(params, false, responseType, auditTrailSb);
          writeResponse(
              resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType);
        } catch (ServerApiException se) {
          String serializedResponseText =
              _apiServer.getSerializedApiError(
                  se.getErrorCode(), se.getDescription(), params, responseType, null);
          resp.setHeader("X-Description", se.getDescription());
          writeResponse(resp, serializedResponseText, se.getErrorCode(), responseType);
          auditTrailSb.append(" " + se.getErrorCode() + " " + se.getDescription());
        }
      } else {
        if (session != null) {
          try {
            session.invalidate();
          } catch (IllegalStateException ise) {
          }
        }

        auditTrailSb.append(
            " "
                + HttpServletResponse.SC_UNAUTHORIZED
                + " "
                + "unable to verify user credentials and/or request signature");
        String serializedResponse =
            _apiServer.getSerializedApiError(
                HttpServletResponse.SC_UNAUTHORIZED,
                "unable to verify user credentials and/or request signature",
                params,
                responseType,
                null);
        writeResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType);
      }
    } catch (Exception ex) {
      if (ex instanceof ServerApiException
          && ((ServerApiException) ex).getErrorCode() == BaseCmd.UNSUPPORTED_ACTION_ERROR) {
        ServerApiException se = (ServerApiException) ex;
        String serializedResponseText =
            _apiServer.getSerializedApiError(
                se.getErrorCode(), se.getDescription(), params, responseType, null);
        resp.setHeader("X-Description", se.getDescription());
        writeResponse(resp, serializedResponseText, se.getErrorCode(), responseType);
        auditTrailSb.append(" " + se.getErrorCode() + " " + se.getDescription());
      } else {
        s_logger.error("unknown exception writing api response", ex);
        auditTrailSb.append(" unknown exception writing api response");
      }
    } finally {
      s_accessLogger.info(auditTrailSb.toString());
      // cleanup user context to prevent from being peeked in other request context
      UserContext.unregisterContext();
    }
  }
  @Override
  @DB
  public LoadBalancer handleCreateLoadBalancerRule(
      CreateLoadBalancerRuleCmd lb, Account account, long networkId)
      throws InsufficientAddressCapacityException, NetworkRuleConflictException {
    // this part of code is executed when the LB provider is Elastic Load Balancer vm
    if (!_networkModel.isProviderSupportServiceInNetwork(
        lb.getNetworkId(), Service.Lb, Provider.ElasticLoadBalancerVm)) {
      return null;
    }

    Long ipId = lb.getSourceIpAddressId();
    if (ipId != null) {
      return null;
    }
    boolean newIp = false;
    account = _accountDao.acquireInLockTable(account.getId());
    if (account == null) {
      s_logger.warn("ELB: CreateLoadBalancer: Failed to acquire lock on account");
      throw new CloudRuntimeException("Failed to acquire lock on account");
    }
    try {
      List<LoadBalancerVO> existingLbs =
          findExistingLoadBalancers(
              lb.getName(),
              lb.getSourceIpAddressId(),
              lb.getAccountId(),
              lb.getDomainId(),
              lb.getSourcePortStart());
      if (existingLbs == null) {
        existingLbs =
            findExistingLoadBalancers(
                lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), null);
        if (existingLbs == null) {
          if (lb.getSourceIpAddressId() != null) {
            existingLbs =
                findExistingLoadBalancers(
                    lb.getName(), null, lb.getAccountId(), lb.getDomainId(), null);
            if (existingLbs != null) {
              throw new InvalidParameterValueException(
                  "Supplied LB name "
                      + lb.getName()
                      + " is not associated with IP "
                      + lb.getSourceIpAddressId());
            }
          } else {
            s_logger.debug(
                "Could not find any existing frontend ips for this account for this LB rule, acquiring a new frontent IP for ELB");
            PublicIp ip = allocDirectIp(account, networkId);
            ipId = ip.getId();
            newIp = true;
          }
        } else {
          ipId = existingLbs.get(0).getSourceIpAddressId();
          s_logger.debug(
              "ELB: Found existing frontend ip for this account for this LB rule " + ipId);
        }
      } else {
        s_logger.warn("ELB: Found existing load balancers matching requested new LB");
        throw new NetworkRuleConflictException(
            "ELB: Found existing load balancers matching requested new LB");
      }

      Network network = _networkModel.getNetwork(networkId);
      IPAddressVO ipAddr = _ipAddressDao.findById(ipId);

      LoadBalancer result = null;
      try {
        lb.setSourceIpAddressId(ipId);
        result = _lbMgr.createLoadBalancer(lb, false);
      } catch (NetworkRuleConflictException e) {
        s_logger.warn("Failed to create LB rule, not continuing with ELB deployment");
        if (newIp) {
          releaseIp(ipId, UserContext.current().getCallerUserId(), account);
        }
        throw e;
      }

      DomainRouterVO elbVm = null;

      if (existingLbs == null) {
        elbVm = findELBVmWithCapacity(network, ipAddr);
        if (elbVm == null) {
          elbVm = deployLoadBalancerVM(networkId, ipAddr, account.getId());
          if (elbVm == null) {
            s_logger.warn(
                "Failed to deploy a new ELB vm for ip "
                    + ipAddr
                    + " in network "
                    + network
                    + "lb name="
                    + lb.getName());
            if (newIp) releaseIp(ipId, UserContext.current().getCallerUserId(), account);
          }
        }

      } else {
        ElasticLbVmMapVO elbVmMap = _elbVmMapDao.findOneByIp(ipId);
        if (elbVmMap != null) {
          elbVm = _routerDao.findById(elbVmMap.getElbVmId());
        }
      }

      if (elbVm == null) {
        s_logger.warn("No ELB VM can be found or deployed");
        s_logger.warn("Deleting LB since we failed to deploy ELB VM");
        _lbDao.remove(result.getId());
        return null;
      }

      ElasticLbVmMapVO mapping = new ElasticLbVmMapVO(ipId, elbVm.getId(), result.getId());
      _elbVmMapDao.persist(mapping);
      return result;

    } finally {
      if (account != null) {
        _accountDao.releaseFromLockTable(account.getId());
      }
    }
  }