diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java index fd923d90d713ddf999b1e30d36c954c598c9e654..bc28f6deb98af0ac7c780158314dc5ee62801547 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java @@ -2214,6 +2214,14 @@ public class VmInstanceBase extends AbstractVmInstance { L3NetworkVO l3vo = dbf.findByUuid(l3Uuid, L3NetworkVO.class); final L3NetworkInventory l3 = L3NetworkInventory.valueOf(l3vo); final VmInstanceInventory vm = getSelfInventory(); + List nics = vm.getVmNics(); + VmNicInventory nicToAttach = VmNicInventory.valueOf(vmNicVO); + nicToAttach.setMetaData("attachNic"); + if (nics == null) { + vm.setVmNics(new ArrayList(Arrays.asList(nicToAttach))); + }else { + nics.add(nicToAttach); + } for (VmPreAttachL3NetworkExtensionPoint ext : pluginRgty.getExtensionList(VmPreAttachL3NetworkExtensionPoint.class)) { ext.vmPreAttachL3Network(vm, l3); } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java index 4ec1e94ce514bc5597a6c9a973d6f1d11f821473..8dfab8500dc706badca365a49b860db8e4e1a35a 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java @@ -4,9 +4,7 @@ import com.google.common.collect.Maps; import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException; import org.apache.commons.lang.StringUtils; import org.apache.commons.validator.routines.DomainValidator; -import org.apache.logging.log4j.util.Strings; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.orm.jpa.JpaSystemException; import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.allocator.HostAllocatorManager; import org.zstack.core.Platform; @@ -761,12 +759,16 @@ public class VmInstanceManagerImpl extends AbstractService implements nic.setUuid(Platform.getUuid()); nic.setMac(mac); nic.setDeviceId(deviceId); + nic.setType(VmInstanceConstant.VIRTUAL_NIC_TYPE); + for (NicManageExtensionPoint ext : pluginRgty.getExtensionList(NicManageExtensionPoint.class)) { + ext.beforeCreateNic(nic, msg); + } nicVO.setUuid(nic.getUuid()); nicVO.setDeviceId(deviceId); - nicVO.setMac(mac); + nicVO.setMac(nic.getMac()); nicVO.setAccountUuid(msg.getSession().getAccountUuid()); - nicVO.setType(VmInstanceConstant.VIRTUAL_NIC_TYPE); + nicVO.setType(nic.getType()); int tries = 5; while (tries-- > 0) { @@ -1200,6 +1202,9 @@ public class VmInstanceManagerImpl extends AbstractService implements })).run(new WhileDoneCompletion(trigger) { @Override public void done(ErrorCodeList errorCodeList) { + for (NicManageExtensionPoint ext : pluginRgty.getExtensionList(NicManageExtensionPoint.class)) { + ext.beforeDeleteNic(nic); + } dbf.removeByPrimaryKey(nic.getUuid(), VmNicVO.class); trigger.next(); } diff --git a/conf/serviceConfig/l2Network.xml b/conf/serviceConfig/l2Network.xml index 535de8bc59f8ef7588857e2555328761d373ea98..ca67982641788b09dc08ba363622fb0278dc85cb 100755 --- a/conf/serviceConfig/l2Network.xml +++ b/conf/serviceConfig/l2Network.xml @@ -47,4 +47,8 @@ org.zstack.header.network.l2.APIGetCandidateClustersForAttachingL2NetworkMsg + + + org.zstack.sugonSdnController.header.APICreateL2TfNetworkMsg + diff --git a/conf/springConfigXml/TfPortAllocator.xml b/conf/springConfigXml/TfPortAllocator.xml index 3f40db0812c54ec0d29d158684716d28f00036c9..4dcb790646990bb21fa42b77e707604eee899b0f 100644 --- a/conf/springConfigXml/TfPortAllocator.xml +++ b/conf/springConfigXml/TfPortAllocator.xml @@ -22,6 +22,11 @@ + + + + + diff --git a/header/src/main/java/org/zstack/header/vm/NicManageExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/NicManageExtensionPoint.java new file mode 100644 index 0000000000000000000000000000000000000000..9a1ce1e7c68a1e93fea6b7e322a1efbde7fa1afb --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/NicManageExtensionPoint.java @@ -0,0 +1,8 @@ +package org.zstack.header.vm; + + +public interface NicManageExtensionPoint { + void beforeCreateNic(VmNicInventory nic, APICreateVmNicMsg msg); + + void beforeDeleteNic(VmNicInventory nic); +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java index da49ab667eb6fccfc49f05c940854df5d19eb938..5f779ad8a3db82df234235811737080baba03a36 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java @@ -246,7 +246,8 @@ public class SugonSdnController implements TfSdnController, SdnController { project.setName(account.getName()); Status status = apiConnector.create(project); if (!status.isSuccess()) { - String message = String.format("create tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); + String message = String.format("create tf project[name:%s] failed due to:%s ",account.getName(), status.getMsg()); +// String message = String.format("create tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); logger.error(message); } } catch (Exception e){ @@ -263,7 +264,8 @@ public class SugonSdnController implements TfSdnController, SdnController { project.setUuid(StringDSL.transToTfUuid(account.getUuid())); Status status = apiConnector.delete(project); if (!status.isSuccess()) { - String message = String.format("delete tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); + String message = String.format("delete tf project[name:%s] failed due to:%s ",account.getName(), status.getMsg()); +// String message = String.format("delete tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); logger.error(message); } } catch (Exception e){ @@ -281,7 +283,8 @@ public class SugonSdnController implements TfSdnController, SdnController { project.setDisplayName(account.getName()); Status status = apiConnector.update(project); if (!status.isSuccess()) { - String message = String.format("update tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); + String message = String.format("update tf project[name:%s] failed due to:%s ",account.getName(), status.getMsg()); +// String message = String.format("update tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); logger.error(message); } } catch (Exception e){ @@ -312,7 +315,8 @@ public class SugonSdnController implements TfSdnController, SdnController { // 更新 tf 网络信息 Status status = apiConnector.update(vn); if(!status.isSuccess()){ - completion.fail(operr("delete tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + completion.fail(operr("delete tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("delete tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); } else{ completion.success(); } @@ -360,7 +364,8 @@ public class SugonSdnController implements TfSdnController, SdnController { // 更新 tf 网络信息 Status status = apiConnector.update(vn); if(!status.isSuccess()){ - completion.fail(operr("update tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + completion.fail(operr("update tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("update tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); } else{ completion.success(); } @@ -448,7 +453,8 @@ public class SugonSdnController implements TfSdnController, SdnController { // 更新 tf 网络信息 Status status = apiConnector.update(vn); if(!status.isSuccess()){ - completion.fail(operr("add tf l3 subnet[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + completion.fail(operr("add tf l3 subnet[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("add tf l3 subnet[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); } else{ completion.success(); } @@ -492,7 +498,8 @@ public class SugonSdnController implements TfSdnController, SdnController { // 更新 tf 网络信息 Status status = apiConnector.update(vn); if(!status.isSuccess()){ - completion.fail(operr("add host router to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + completion.fail(operr("add host router to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("add host router to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); } else{ completion.success(); } @@ -545,7 +552,8 @@ public class SugonSdnController implements TfSdnController, SdnController { // 更新 tf 网络信息 Status status = apiConnector.update(vn); if(!status.isSuccess()){ - completion.fail(operr("delete host route from l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + completion.fail(operr("delete host route from l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("delete host route from l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); } else{ completion.success(); } @@ -602,7 +610,8 @@ public class SugonSdnController implements TfSdnController, SdnController { // 更新 tf 网络信息 Status status = apiConnector.update(vn); if(!status.isSuccess()){ - completion.fail(operr("add dns to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + completion.fail(operr("add dns to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("add dns to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); } else{ completion.success(); } @@ -647,7 +656,8 @@ public class SugonSdnController implements TfSdnController, SdnController { // 更新 tf 网络信息 Status status = apiConnector.update(vn); if (!status.isSuccess()) { - completion.fail(operr("delete dns from to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + completion.fail(operr("delete dns from to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("delete dns from to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); } else { completion.success(); } diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorImpl.java index e43b236083d6a8bf374b95bd49c4f099cb911283..6232c857c13e5dc7c70b2fc1e26bfec5683e0f0f 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorImpl.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorImpl.java @@ -10,6 +10,7 @@ import java.net.Socket; import java.util.ArrayList; import java.util.List; +import com.google.common.io.ByteStreams; import com.google.gson.JsonObject; import org.apache.commons.lang.StringUtils; import org.apache.http.ConnectionReuseStrategy; @@ -339,7 +340,8 @@ class ApiConnectorImpl implements ApiConnector { int status = response.getStatusLine().getStatusCode(); if (status != HttpStatus.SC_OK && status != HttpStatus.SC_ACCEPTED ) { - String reason = response.getStatusLine().getReasonPhrase(); +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); s_logger.warn("<< Response:" + reason); checkResponseKeepAliveStatus(response); return Status.failure(reason); @@ -380,7 +382,8 @@ class ApiConnectorImpl implements ApiConnector { && status != HttpStatus.SC_CREATED && status != HttpStatus.SC_ACCEPTED ) { - String reason = response.getStatusLine().getReasonPhrase(); +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); s_logger.error("create api request failed: " + reason); if (status != HttpStatus.SC_NOT_FOUND) { s_logger.error("Failure message: " + getResponseData(response)); @@ -425,7 +428,8 @@ class ApiConnectorImpl implements ApiConnector { int status = response.getStatusLine().getStatusCode(); if (status != HttpStatus.SC_OK && status != HttpStatus.SC_ACCEPTED ) { - String reason = response.getStatusLine().getReasonPhrase(); +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); s_logger.warn("<< Response:" + reason); checkResponseKeepAliveStatus(response); return Status.failure(reason); @@ -448,7 +452,8 @@ class ApiConnectorImpl implements ApiConnector { int status = response.getStatusLine().getStatusCode(); if (status != HttpStatus.SC_OK) { - String reason = response.getStatusLine().getReasonPhrase(); +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); s_logger.warn("GET failed: " + reason); if (status != HttpStatus.SC_NOT_FOUND) { s_logger.error("Failure message: " + getResponseData(response)); @@ -493,7 +498,8 @@ class ApiConnectorImpl implements ApiConnector { if (status != HttpStatus.SC_OK && status != HttpStatus.SC_NO_CONTENT && status != HttpStatus.SC_ACCEPTED ) { - String reason = response.getStatusLine().getReasonPhrase(); +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); s_logger.warn("Delete failed: " + reason); if (status != HttpStatus.SC_NOT_FOUND) { s_logger.error("Failure message: " + getResponseData(response)); @@ -664,7 +670,8 @@ class ApiConnectorImpl implements ApiConnector { && status != HttpStatus.SC_CREATED && status != HttpStatus.SC_ACCEPTED && status != HttpStatus.SC_NO_CONTENT ) { - String reason = response.getStatusLine().getReasonPhrase(); +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); s_logger.error("sync request failed: " + reason); if (status != HttpStatus.SC_NOT_FOUND) { s_logger.error("Failure message: " + getResponseData(response)); diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Status.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Status.java index a9c69a08514cf4656691b532866fa5b61db4917a..fc460e3c5cabea8fd3b36faea496ad3f73f4b480 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Status.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Status.java @@ -6,6 +6,7 @@ public abstract class Status { public abstract boolean isSuccess(); public abstract void ifFailure(ErrorHandler handler); + public abstract String getMsg(); private final static Status success = new Success(); @@ -27,6 +28,13 @@ public abstract class Status { public void ifFailure(ErrorHandler handler) { // do nothing } + + @Override + public String getMsg() { + // do nothing + return "success"; + } + } private static class Failure extends Status { @@ -45,6 +53,11 @@ public abstract class Status { public void ifFailure(ErrorHandler handler) { handler.handle(message); } + + @Override + public String getMsg() { + return message; + } } public interface ErrorHandler { diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortClient.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortClient.java index ad4e7a0455ffb404405aac6f754643eed8b08aa8..443760c64607220583d0b03e111eed726f359127 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortClient.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortClient.java @@ -5,6 +5,7 @@ import org.bouncycastle.util.IPAddress; import org.zstack.core.db.Q; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.vm.VmInstanceInventory; import org.zstack.sdnController.header.SdnControllerConstant; import org.zstack.sdnController.header.SdnControllerVO; import org.zstack.sdnController.header.SdnControllerVO_; @@ -34,7 +35,7 @@ public class TfPortClient { return apiConnector; } - public TfPortResponse createPort(String l2Id, String l3Id, String mac, String ip, String tenantId, String vmInventeryId, String tfPortUuid) { + public TfPortResponse createPort(String l2Id, String l3Id, String mac, String ip, String tenantId, String vmInventeryId, String tfPortUuid, String vmName) { TfPortRequestBody portRequestBodyEO = new TfPortRequestBody(); TfPortRequestData portRequestDataEO = new TfPortRequestData(); TfPortRequestContext portRequestContextEO = new TfPortRequestContext(); @@ -113,6 +114,7 @@ public class TfPortClient { PermType2 perms2 = new PermType2(); perms2.setOwner(tenantId); port.setPerms2(perms2); + port.setDisplayName(vmName); ApiConnector apiConnector = getApiConnector(); // always request for v4 and v6 ip object and handle the failure // create the object @@ -173,13 +175,13 @@ public class TfPortClient { throw new RuntimeException(e); } try { - return portVncToNeutorn(virtualMachineInterface); + return portVncToNeutron(virtualMachineInterface); } catch (IOException e) { throw new RuntimeException(e); } } - private TfPortResponse portVncToNeutorn(VirtualMachineInterface portObj) throws IOException { + private TfPortResponse portVncToNeutron(VirtualMachineInterface portObj) throws IOException { ApiConnector apiConnector = getApiConnector(); TfPortResponse tfPortResponse = new TfPortResponse(); tfPortResponse.setPortId(portObj.getUuid()); @@ -364,22 +366,19 @@ public class TfPortClient { public boolean ipAddrInNetId(String ipAddr, String netId) throws IOException { ApiConnector apiConnector = getApiConnector(); - VirtualNetwork virtualNetwork = null; - if (apiConnector != null) { - virtualNetwork = (VirtualNetwork) apiConnector.findById(VirtualNetwork.class, netId); - } - List> instanceIpBackRefs = null; - if (virtualNetwork != null) { - instanceIpBackRefs = virtualNetwork.getInstanceIpBackRefs(); - } - List ipObjects = null; if (apiConnector != null) { - ipObjects = (List) apiConnector.getObjects(InstanceIp.class, instanceIpBackRefs); - } - if (ipObjects != null) { - for (InstanceIp ipObj : ipObjects) { - if (ipObj.getAddress().equals(ipAddr)) { - return true; + VirtualNetwork virtualNetwork = (VirtualNetwork) apiConnector.findById(VirtualNetwork.class, netId); + if (virtualNetwork != null) { + List> instanceIpBackRefs = virtualNetwork.getInstanceIpBackRefs(); + if (instanceIpBackRefs != null) { + List ipObjects = (List) apiConnector.getObjects(InstanceIp.class, instanceIpBackRefs); + if (ipObjects != null) { + for (InstanceIp ipObj : ipObjects) { + if (ipObj.getAddress().equals(ipAddr)) { + return true; + } + } + } } } } @@ -451,6 +450,19 @@ public class TfPortClient { } + public TfPortResponse getVirtualMachineInterface(String portId) { + try { + VirtualMachineInterface port = (VirtualMachineInterface) getApiConnector().findById(VirtualMachineInterface.class, portId); + if (port != null){ + return portVncToNeutron(port); + }else { + return null; + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + private VirtualNetwork networkRead(String l2Id) throws IOException { return virtualNetworkRead(l2Id); } @@ -720,4 +732,15 @@ public class TfPortClient { return tfPortIpEntityList; } + + public void updateTfPort(String tfPortUUid, String accountId, String deviceId) { + try { + VirtualMachineInterface port = (VirtualMachineInterface) getApiConnector().findById(VirtualMachineInterface.class, tfPortUUid); + VirtualMachine vm = ensureInstanceExists(deviceId, accountId, false); + port.setVirtualMachine(vm); + getApiConnector().update(port); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3Network.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3Network.java index 23ce7911ba7e4898b0f56aa4d83f985363e88d27..4420643b3602b5c13d041eb572d69a6fe5b792b1 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3Network.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3Network.java @@ -40,10 +40,21 @@ public class TfL3Network extends L3BasicNetwork { @Autowired protected DatabaseFacade dbf; + SugonSdnController sugonSdnController; + public TfL3Network(L3NetworkVO self) { super(self); } + private SugonSdnController getSugonSdnController() { + if (sugonSdnController != null){ + return sugonSdnController; + } + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); + SdnController sdnController = sdnControllerManager.getSdnController(sdn); + return (SugonSdnController) sdnController; + } + @Override public void handleMessage(Message msg) { if (msg instanceof APIDeleteL3NetworkMsg) { @@ -92,10 +103,7 @@ public class TfL3Network extends L3BasicNetwork { // Get L3 Network from zstack db L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getUuid()).find(); if(l3Network!=null){ - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); - SdnController sdnController = sdnControllerManager.getSdnController(sdn); - SugonSdnController sugonSdnController = (SugonSdnController) sdnController; - sugonSdnController.deleteL3Network(l3Network, new Completion(msg){ + getSugonSdnController().deleteL3Network(l3Network, new Completion(msg){ @Override public void success() { // zstack business processing @@ -120,10 +128,7 @@ public class TfL3Network extends L3BasicNetwork { // Get L3 Network from zstack db L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getUuid()).find(); if(l3Network!=null){ - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); - SdnController sdnController = sdnControllerManager.getSdnController(sdn); - SugonSdnController sugonSdnController = (SugonSdnController) sdnController; - sugonSdnController.updateL3Network(l3Network,msg, new Completion(msg){ + getSugonSdnController().updateL3Network(l3Network,msg, new Completion(msg){ @Override public void success() { // zstack business processing @@ -149,10 +154,7 @@ public class TfL3Network extends L3BasicNetwork { // Get L3 Network from zstack db L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); if(l3Network!=null){ - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); - SdnController sdnController = sdnControllerManager.getSdnController(sdn); - SugonSdnController sugonSdnController = (SugonSdnController) sdnController; - sugonSdnController.addL3IpRangeByCidr(l3Network,msg, new Completion(msg){ + getSugonSdnController().addL3IpRangeByCidr(l3Network,msg, new Completion(msg){ @Override public void success() { // zstack business processing @@ -177,10 +179,7 @@ public class TfL3Network extends L3BasicNetwork { // Get L3 Network from zstack db L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); if(l3Network!=null){ - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); - SdnController sdnController = sdnControllerManager.getSdnController(sdn); - SugonSdnController sugonSdnController = (SugonSdnController) sdnController; - sugonSdnController.deleteL3Network(l3Network, new Completion(msg){ + getSugonSdnController().deleteL3Network(l3Network, new Completion(msg){ @Override public void success() { // zstack business processing @@ -205,10 +204,7 @@ public class TfL3Network extends L3BasicNetwork { // Get L3 Network from zstack db L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); if(l3Network!=null){ - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); - SdnController sdnController = sdnControllerManager.getSdnController(sdn); - SugonSdnController sugonSdnController = (SugonSdnController) sdnController; - sugonSdnController.addL3Dns(l3Network, msg,new Completion(msg){ + getSugonSdnController().addL3Dns(l3Network, msg,new Completion(msg){ @Override public void success() { // zstack business processing @@ -233,10 +229,7 @@ public class TfL3Network extends L3BasicNetwork { // Get L3 Network from zstack db L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); if(l3Network!=null){ - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); - SdnController sdnController = sdnControllerManager.getSdnController(sdn); - SugonSdnController sugonSdnController = (SugonSdnController) sdnController; - sugonSdnController.deleteL3Dns(l3Network, msg,new Completion(msg){ + getSugonSdnController().deleteL3Dns(l3Network, msg,new Completion(msg){ @Override public void success() { // zstack business processing @@ -261,10 +254,7 @@ public class TfL3Network extends L3BasicNetwork { // Get L3 Network from zstack db L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); if(l3Network!=null){ - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); - SdnController sdnController = sdnControllerManager.getSdnController(sdn); - SugonSdnController sugonSdnController = (SugonSdnController) sdnController; - sugonSdnController.addL3HostRoute(l3Network, msg,new Completion(msg){ + getSugonSdnController().addL3HostRoute(l3Network, msg,new Completion(msg){ @Override public void success() { // zstack business processing @@ -289,10 +279,7 @@ public class TfL3Network extends L3BasicNetwork { // Get L3 Network from zstack db L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); if(l3Network!=null){ - SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); - SdnController sdnController = sdnControllerManager.getSdnController(sdn); - SugonSdnController sugonSdnController = (SugonSdnController) sdnController; - sugonSdnController.deleteL3HostRoute(l3Network, msg,new Completion(msg){ + getSugonSdnController().deleteL3HostRoute(l3Network, msg,new Completion(msg){ @Override public void success() { // zstack business processing diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfNicManageExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfNicManageExtensionPointImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..fd8e7733256e4b124f1dbe298db59e32010fa6e1 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfNicManageExtensionPointImpl.java @@ -0,0 +1,70 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.db.Q; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.vm.APICreateVmNicMsg; +import org.zstack.header.vm.NicManageExtensionPoint; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortIpEntity; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortResponse; +import org.zstack.utils.StringDSL; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + + +public class TfNicManageExtensionPointImpl implements NicManageExtensionPoint { + private static final CLogger logger = Utils.getLogger(TfNicManageExtensionPointImpl.class); + + @Autowired + private TfPortService tfPortService; + + @Override + public void beforeCreateNic(VmNicInventory nic, APICreateVmNicMsg msg) { + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if (!SugonSdnControllerConstant.L3_TF_NETWORK_TYPE.equals(l3Network.getType())) { + return; + } + nic.setType(VmInstanceConstant.TF_VIRTUAL_NIC_TYPE); + TfPortResponse port = null; + String portUuid = msg.getResourceUuid(); + if (portUuid != null){ + port = tfPortService.getTfPort(StringDSL.transToTfUuid(portUuid)); + if (port != null){ + String ipAddr = null; + for (TfPortIpEntity ipEntrty: port.getFixedIps()) { + if (ipEntrty.getSubnetId().equals(StringDSL.transToTfUuid(msg.getL3NetworkUuid()))) { + ipAddr = ipEntrty.getIpAddress(); + } + } + if (ipAddr == null) { + throw new RuntimeException(String.format("Tf port with uuid[%s] exists, " + + "but it's subnet id not equal with the l3NetworkUuid in param.", msg.getResourceUuid())); + } + msg.setIp(ipAddr); + nic.setMac(port.getMacAddress()); + logger.debug(String.format("Tf port with uuid[%s] exists, just save ip info to zstack db.", + msg.getResourceUuid())); + } + } + if (port == null) { + String l2NetworkUuid = l3Network.getL2NetworkUuid(); + port = tfPortService.createTfPort(StringDSL.transToTfUuid(portUuid), l2NetworkUuid, msg.getL3NetworkUuid(), + nic.getMac(), msg.getIp()); + logger.debug("Create a new tf port success."); + } + nic.setUuid(StringDSL.transToZstackUuid(port.getPortId())); + } + + @Override + public void beforeDeleteNic(VmNicInventory nic) { + if (!VmInstanceConstant.TF_VIRTUAL_NIC_TYPE.equals(nic.getType())) { + return; + } + tfPortService.deleteTfPort(nic.getUuid()); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfPortService.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfPortService.java index f3adcbaf6ca66b17ab3649ecb61b6d0e66b19b71..fdf5a2d3f791f6000abaecc42641f2e6a4c4722a 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfPortService.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfPortService.java @@ -18,6 +18,25 @@ public class TfPortService { @Autowired protected AccountManager acntMgr; + public TfPortResponse getTfPort(String tfPortUUid) { + TfPortClient tfPortClient = new TfPortClient(); + return tfPortClient.getVirtualMachineInterface(tfPortUUid); + } + + public TfPortResponse createTfPort(String tfPortUUid, String l2NetworkUuid, String l3NetworkUuid, String mac, String ip) { + //invoke tf rest interface to retrieve real ip and mac and portId + TfPortClient tfPortClient = new TfPortClient(); + String tfL2NetworkId = StringDSL.transToTfUuid(l2NetworkUuid); + String tfL3NetworkId = StringDSL.transToTfUuid(l3NetworkUuid); + String accountId = StringDSL.transToTfUuid(acntMgr.getOwnerAccountUuidOfResource(l3NetworkUuid)); + TfPortResponse port = tfPortClient.createPort(tfL2NetworkId, tfL3NetworkId, mac, ip, accountId, null, tfPortUUid, null); + if (port.getCode() != HttpStatus.OK.value()) { + // fail to rollback the flowchain + throw new RuntimeException("failed to invoke creating tf port: " + port); + } + return port; + } + public TfPortResponse createTfPort(String tfPortUUid, VmInstanceInventory vm, L3NetworkInventory l3) { MacOperator mo = new MacOperator(); String customMac = mo.getMac(vm.getUuid(), l3.getUuid()); @@ -33,11 +52,26 @@ public class TfPortService { String tfL3NetworkId = StringDSL.transToTfUuid(l3.getUuid()); String accountId = StringDSL.transToTfUuid(acntMgr.getOwnerAccountUuidOfResource(vm.getUuid())); String vmiUuid = StringDSL.transToTfUuid(vm.getUuid()); - TfPortResponse port = tfPortClient.createPort(tfL2NetworkId, tfL3NetworkId, customMac, customIp, accountId, vmiUuid, tfPortUUid); + String vmName = vm.getName(); + TfPortResponse port = tfPortClient.createPort(tfL2NetworkId, tfL3NetworkId, customMac, customIp, accountId, vmiUuid, tfPortUUid, vmName); if (port.getCode() != HttpStatus.OK.value()) { // fail to rollback the flowchain throw new RuntimeException("failed to invoke creating tf port: " + port); } return port; } + + public TfPortResponse deleteTfPort(String portUUid) { + String accountId = StringDSL.transToTfUuid(acntMgr.getOwnerAccountUuidOfResource(portUUid)); + String tfPortUUid = StringDSL.transToTfUuid(portUUid); + TfPortClient tfPortClient = new TfPortClient(); + return tfPortClient.deletePort(tfPortUUid, accountId); + } + + public void updateTfPort(String tfPortUUid, String vmUuid) { + String accountId = StringDSL.transToTfUuid(acntMgr.getOwnerAccountUuidOfResource(vmUuid)); + String tfVmUUid = StringDSL.transToTfUuid(vmUuid); + TfPortClient tfPortClient = new TfPortClient(); + tfPortClient.updateTfPort(tfPortUUid, accountId, tfVmUUid); + } } diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmPreAttachL3NetworkExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmPreAttachL3NetworkExtensionPointImpl.java index 0192894c7980d3f51ca7d62dd002a298d8822df6..6a9a8d0ed7be6ad9b4422f661c48a28c2161f259 100644 --- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmPreAttachL3NetworkExtensionPointImpl.java +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmPreAttachL3NetworkExtensionPointImpl.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.zstack.compute.vm.CustomNicOperator; import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmNicInventory; import org.zstack.header.vm.VmPreAttachL3NetworkExtensionPoint; import org.zstack.identity.AccountManager; import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; @@ -27,7 +28,23 @@ public class VmPreAttachL3NetworkExtensionPointImpl implements VmPreAttachL3Netw if (!SugonSdnControllerConstant.L3_TF_NETWORK_TYPE.equals(l3.getType())) { return; } - TfPortResponse port = tfPortService.createTfPort(null, vm, l3); + String tfPortUuid = null; + VmNicInventory nicAttach = null; + for (VmNicInventory nic : vm.getVmNics()) { + String metadata = nic.getMetaData(); + if (metadata != null && metadata.equals("attachNic")) { + nicAttach = nic; + } + } + if (nicAttach != null) { + tfPortUuid = StringDSL.transToTfUuid(nicAttach.getUuid()); + TfPortResponse port = tfPortService.getTfPort(tfPortUuid); + if (port != null) { + tfPortService.updateTfPort(tfPortUuid, vm.getUuid()); + return; + } + } + TfPortResponse port = tfPortService.createTfPort(tfPortUuid, vm, l3); String finalMac = port.getMacAddress(); String finalIp = port.getFixedIps().get(0).getIpAddress();