package org.zstack.network.l2.vxlan.vxlanNetworkPool; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.host.HostConstant; import org.zstack.header.host.HostVO; import org.zstack.header.host.HostVO_; import org.zstack.header.host.HypervisorType; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l2.L2NetworkConstant; import org.zstack.header.network.l2.L2NetworkInventory; import org.zstack.header.network.l2.L2NetworkRealizationExtensionPoint; import org.zstack.header.network.l2.L2NetworkType; import org.zstack.header.vm.VmNicInventory; import org.zstack.kvm.*; import org.zstack.network.l2.vxlan.vtep.CreateVtepMsg; import org.zstack.network.l2.vxlan.vtep.VtepVO; import org.zstack.network.l2.vxlan.vtep.VtepVO_; import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.zstack.core.Platform.operr; import static org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolConstant.KVM_VXLAN_TYPE; import static org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolConstant.VXLAN_KVM_CHECK_L2VXLAN_NETWORK_PATH; import static org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolConstant.VXLAN_PORT; /** * Created by weiwang on 20/03/2017. */ public class KVMRealizeL2VxlanNetworkPoolBackend implements L2NetworkRealizationExtensionPoint, KVMCompleteNicInformationExtensionPoint { private static CLogger logger = Utils.getLogger(KVMRealizeL2VxlanNetworkPoolBackend.class); @Autowired private DatabaseFacade dbf; @Autowired private ApiTimeoutManager timeoutMgr; @Autowired private CloudBus bus; @Override public void realize(L2NetworkInventory l2Network, String hostUuid, Completion completion) { completion.success(); } @Override public void check(final L2NetworkInventory l2Network, final String hostUuid, final Completion completion) { check(l2Network, hostUuid, true, completion); } public void check(L2NetworkInventory l2Network, String hostUuid, boolean noStatusCheck, Completion completion) { final L2VxlanNetworkPoolInventory vxlanPool = (L2VxlanNetworkPoolInventory) l2Network; final String clusterUuid = Q.New(HostVO.class).select(HostVO_.clusterUuid).eq(HostVO_.uuid, hostUuid).findValue(); VxlanKvmAgentCommands.CheckVxlanCidrCmd cmd = new VxlanKvmAgentCommands.CheckVxlanCidrCmd(); cmd.setCidr(getAttachedCidrs(vxlanPool.getUuid()).get(clusterUuid)); if (!l2Network.getPhysicalInterface().isEmpty()) { cmd.setPhysicalInterfaceName(l2Network.getPhysicalInterface()); } KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(hostUuid); msg.setCommand(cmd); msg.setCommandTimeout(timeoutMgr.getTimeout(cmd.getClass(), "5m")); msg.setPath(VXLAN_KVM_CHECK_L2VXLAN_NETWORK_PATH); msg.setNoStatusCheck(noStatusCheck); bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); bus.send(msg, new CloudBusCallBack(completion) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { completion.fail(reply.getError()); return; } KVMHostAsyncHttpCallReply hreply = reply.castReply(); VxlanKvmAgentCommands.CheckVxlanCidrResponse rsp = hreply.toResponse(VxlanKvmAgentCommands.CheckVxlanCidrResponse.class); if (!rsp.isSuccess()) { ErrorCode err = operr("failed to check cidr[%s] for l2VxlanNetwork[uuid:%s, name:%s] on kvm host[uuid:%s], %s", cmd.getCidr(), vxlanPool.getUuid(), vxlanPool.getName(), hostUuid, rsp.getError()); completion.fail(err); return; } String info = String.format("successfully checked cidr[%s] for l2VxlanNetwork[uuid:%s, name:%s] on kvm host[uuid:%s]", cmd.getCidr(), vxlanPool.getUuid(), vxlanPool.getName(), hostUuid); logger.debug(info); completion.success(); } }); } @Override public L2NetworkType getSupportedL2NetworkType() { return L2NetworkType.valueOf(VxlanNetworkPoolConstant.VXLAN_NETWORK_POOL_TYPE); } @Override public HypervisorType getSupportedHypervisorType() { return HypervisorType.valueOf("KVM"); } @Override public L2NetworkType getL2NetworkTypeVmNicOn() { return getSupportedL2NetworkType(); } @Override public KVMAgentCommands.NicTO completeNicInformation(L2NetworkInventory l2Network, VmNicInventory nic) { VxlanNetworkPoolVO vo = dbf.findByUuid(l2Network.getUuid(), VxlanNetworkPoolVO.class); KVMAgentCommands.NicTO to = new KVMAgentCommands.NicTO(); to.setMac(nic.getMac()); to.setUuid(nic.getUuid()); to.setDeviceId(nic.getDeviceId()); to.setNicInternalName(nic.getInternalName()); return to; } public Map<String, String> getAttachedCidrs(String l2NetworkUuid) { List<Map<String, String>> tokenList = VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTokensOfTagsByResourceUuid(l2NetworkUuid); Map<String, String> attachedClusters = new HashMap<>(); for (Map<String, String> tokens : tokenList) { attachedClusters.put(tokens.get(VxlanSystemTags.CLUSTER_UUID_TOKEN), tokens.get(VxlanSystemTags.VTEP_CIDR_TOKEN).split("[{}]")[1]); } return attachedClusters; } }