private void attachCluster(
      final APIAttachPrimaryStorageToClusterMsg msg, final NoErrorCompletion completion) {
    final APIAttachPrimaryStorageToClusterEvent evt =
        new APIAttachPrimaryStorageToClusterEvent(msg.getId());
    try {
      extpEmitter.preAttach(self, msg.getClusterUuid());
    } catch (PrimaryStorageException pe) {
      evt.setErrorCode(
          errf.instantiateErrorCode(PrimaryStorageErrors.ATTACH_ERROR, pe.getMessage()));
      bus.publish(evt);
      completion.done();
      return;
    }

    extpEmitter.beforeAttach(self, msg.getClusterUuid());
    attachHook(
        msg.getClusterUuid(),
        new Completion(msg, completion) {
          @Override
          public void success() {
            PrimaryStorageClusterRefVO ref = new PrimaryStorageClusterRefVO();
            ref.setClusterUuid(msg.getClusterUuid());
            ref.setPrimaryStorageUuid(self.getUuid());
            dbf.persist(ref);

            self = dbf.reload(self);
            extpEmitter.afterAttach(self, msg.getClusterUuid());

            PrimaryStorageInventory pinv = (PrimaryStorageInventory) invf.valueOf(self);
            evt.setInventory(pinv);
            logger.debug(
                String.format(
                    "successfully attached primary storage[name:%s, uuid:%s]",
                    pinv.getName(), pinv.getUuid()));
            bus.publish(evt);
            completion.done();
          }

          @Override
          public void fail(ErrorCode errorCode) {
            extpEmitter.failToAttach(self, msg.getClusterUuid());
            evt.setErrorCode(
                errf.instantiateErrorCode(PrimaryStorageErrors.ATTACH_ERROR, errorCode));
            bus.publish(evt);
            completion.done();
          }
        });
  }
  private void releaseNetworkServices(
      final VmInstanceSpec spec,
      NetworkServiceExtensionPosition position,
      final NoErrorCompletion completion) {
    if (!spec.getVmInventory().getType().equals(VmInstanceConstant.USER_VM_TYPE)) {
      completion.done();
      return;
    }

    if (nsExts.isEmpty()) {
      completion.done();
      return;
    }

    // we run into this situation when VM nics are all detached and the
    // VM is being rebooted
    if (spec.getDestNics().isEmpty()) {
      completion.done();
      return;
    }

    List<String> nsTypes = spec.getRequiredNetworkServiceTypes();

    FlowChain schain =
        FlowChainBuilder.newSimpleFlowChain()
            .setName(
                String.format(
                    "release-network-services-from-vm-%s", spec.getVmInventory().getUuid()));
    schain.allowEmptyFlow();

    for (final NetworkServiceExtensionPoint ns : nsExts) {
      if (position != null && ns.getNetworkServiceExtensionPosition() != position) {
        continue;
      }

      if (!nsTypes.contains(ns.getNetworkServiceType().toString())) {
        continue;
      }

      NoRollbackFlow flow =
          new NoRollbackFlow() {
            String __name__ =
                String.format("release-network-service-%s", ns.getNetworkServiceType());

            @Override
            public void run(final FlowTrigger chain, Map data) {
              logger.debug(
                  String.format(
                      "NetworkServiceExtensionPoint[%s] is asking back ends to release network service[%s] if needed",
                      ns.getClass().getName(), ns.getNetworkServiceType()));
              ns.releaseNetworkService(
                  spec,
                  data,
                  new NoErrorCompletion() {
                    @Override
                    public void done() {
                      chain.next();
                    }
                  });
            }
          };

      schain.then(flow);
    }

    schain
        .done(
            new FlowDoneHandler(completion) {
              @Override
              public void handle(Map data) {
                logger.debug(
                    String.format(
                        "successfully released network services for vm[uuid:%s,  name:%s]",
                        spec.getVmInventory().getUuid(), spec.getVmInventory().getName()));
                completion.done();
              }
            })
        .start();
  }
Example #3
0
  private void refreshFirewall(
      final ApplianceVmRefreshFirewallMsg msg, final NoErrorCompletion completion) {
    class RuleCombiner {
      long total;
      Map<String, List<ApplianceVmFirewallRuleVO>> rules =
          new HashMap<String, List<ApplianceVmFirewallRuleVO>>();
      List<ApplianceVmFirewallRuleTO> result = new ArrayList<ApplianceVmFirewallRuleTO>();
      Map<String, String> l3NicMacMap = new HashMap<String, String>();

      {
        for (VmNicVO nic : self.getVmNics()) {
          l3NicMacMap.put(nic.getL3NetworkUuid(), nic.getMac());
        }

        SimpleQuery<ApplianceVmFirewallRuleVO> q = dbf.createQuery(ApplianceVmFirewallRuleVO.class);
        q.add(ApplianceVmFirewallRuleVO_.applianceVmUuid, Op.EQ, self.getUuid());
        total = q.count();
      }

      List<ApplianceVmFirewallRuleTO> merge() {
        if (total == 0) {
          return new ArrayList<ApplianceVmFirewallRuleTO>();
        }

        prepare();
        normalize();
        return result;
      }

      private void normalize() {
        for (List<ApplianceVmFirewallRuleVO> vos : rules.values()) {
          if (!vos.isEmpty()) {
            normalize(vos);
          }
        }
      }

      private void normalize(List<ApplianceVmFirewallRuleVO> vos) {
        String l3Uuid = null;
        String sip = null;
        String dip = null;
        String allowedCidr = null;
        ApplianceVmFirewallProtocol protocol = null;

        RangeSet rset = new RangeSet();
        for (ApplianceVmFirewallRuleVO vo : vos) {
          if (l3Uuid == null) {
            l3Uuid = vo.getL3NetworkUuid();
          }
          if (sip == null) {
            sip = vo.getSourceIp();
          }
          if (dip == null) {
            dip = vo.getDestIp();
          }
          if (allowedCidr == null) {
            allowedCidr = vo.getAllowCidr();
          }
          if (protocol == null) {
            protocol = vo.getProtocol();
          }
          rset.closed(vo.getStartPort(), vo.getEndPort());
        }

        List<Range> rs = rset.merge();
        for (Range r : rs) {
          ApplianceVmFirewallRuleTO to = new ApplianceVmFirewallRuleTO();
          to.setDestIp(dip);
          to.setNicMac(l3NicMacMap.get(l3Uuid));
          to.setProtocol(protocol.toString());
          to.setAllowCidr(allowedCidr);
          to.setSourceIp(sip);
          to.setStartPort((int) r.getStart());
          to.setEndPort((int) r.getEnd());
          result.add(to);
        }
      }

      private void prepare() {
        int offset = 0;
        int step = 1000;
        while (offset < total) {
          SimpleQuery<ApplianceVmFirewallRuleVO> q =
              dbf.createQuery(ApplianceVmFirewallRuleVO.class);
          q.add(ApplianceVmFirewallRuleVO_.applianceVmUuid, Op.EQ, self.getUuid());
          q.setLimit(step);
          q.setStart(offset);
          List<ApplianceVmFirewallRuleVO> vos = q.list();
          for (ApplianceVmFirewallRuleVO vo : vos) {
            String key =
                String.format(
                    "%s-%s-%s-%s-%s",
                    vo.getL3NetworkUuid(),
                    vo.getProtocol(),
                    vo.getSourceIp(),
                    vo.getDestIp(),
                    vo.getAllowCidr());
            List<ApplianceVmFirewallRuleVO> lst = rules.get(key);
            if (lst == null) {
              lst = new ArrayList<ApplianceVmFirewallRuleVO>();
              rules.put(key, lst);
            }
            lst.add(vo);
          }
          offset += step;
        }
      }
    }

    final ApplianceVmRefreshFirewallReply reply = new ApplianceVmRefreshFirewallReply();
    refreshVO();
    ErrorCode allowed = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR);
    if (allowed != null) {
      reply.setError(allowed);
      bus.reply(msg, reply);
      completion.done();
      return;
    }

    RefreshFirewallCmd cmd = new RefreshFirewallCmd();
    List<ApplianceVmFirewallRuleTO> tos = new RuleCombiner().merge();
    cmd.setRules(tos);

    resf.asyncJsonPost(
        buildUrl(ApplianceVmConstant.REFRESH_FIREWALL_PATH),
        cmd,
        new JsonAsyncRESTCallback<RefreshFirewallRsp>(msg, completion) {
          @Override
          public void fail(ErrorCode err) {
            reply.setError(err);
            bus.reply(msg, reply);
            completion.done();
          }

          @Override
          public void success(RefreshFirewallRsp ret) {
            if (!ret.isSuccess()) {
              logger.warn(
                  String.format(
                      "failed to refresh firewall rules on appliance vm[uuid:%s, name:%s], %s",
                      self.getUuid(), self.getName(), ret.getError()));
              reply.setError(errf.stringToOperationError(ret.getError()));
            }

            bus.reply(msg, reply);
            completion.done();
          }

          @Override
          public Class<RefreshFirewallRsp> getReturnClass() {
            return RefreshFirewallRsp.class;
          }
        });
  }