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(); }
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; } }); }